Documentation
¶
Overview ¶
Package pkg provides public library APIs for the Ason project scaffolding tool.
Package pkg provides public library APIs for the Ason project scaffolding tool.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewGenerationError ¶
NewGenerationError creates a new GenerationError with the given phase and reason. It is returned when generation fails.
func RenderWithEngine ¶
func RenderWithEngine( ctx context.Context, engine Engine, template string, context map[string]interface{}, ) (string, error)
RenderWithEngine is a helper function for rendering a template using a specific engine. This is useful for testing or one-off renders without creating a Generator.
Parameters:
- ctx: Context for cancellation
- engine: The engine to use for rendering
- template: The template content
- context: Variables for substitution
Returns:
- The rendered output
- An error if rendering fails or context is cancelled
Example:
engine := pkg.NewDefaultEngine()
output, err := pkg.RenderWithEngine(ctx, engine, "Hello {{ name }}", map[string]interface{}{"name": "World"})
Types ¶
type CustomEngine ¶
type CustomEngine interface {
// Render renders a template string with context variables
Render(template string, context map[string]interface{}) (string, error)
// RenderFile renders a template from a file path
RenderFile(filePath string, context map[string]interface{}) (string, error)
}
CustomEngine allows creation of custom template engine implementations. This interface is public and can be implemented by users to support different template formats.
Example custom engine implementation:
type MyEngine struct{}
func (e *MyEngine) Render(template string, context map[string]interface{}) (string, error) {
// Custom rendering logic
}
func (e *MyEngine) RenderFile(filePath string, context map[string]interface{}) (string, error) {
// Custom file rendering logic
}
engine := &MyEngine{}
gen, _ := pkg.NewGenerator(engine)
gen.Generate(ctx, template, vars, output)
The Engine interface is simple by design to support: - Pongo2/Jinja2-like engines - Custom template syntax engines - Mock engines for testing
All engines must be thread-safe for concurrent use with the same Generator instance.
type Engine ¶
type Engine interface {
// Render renders a template string with the given context variables.
// The template string should be in the template engine's format (e.g., Pongo2/Jinja2).
// The context map provides variables that can be referenced in the template.
// Returns the rendered output or an error if rendering fails.
//
// Parameters:
// - template: The template content as a string
// - context: Variables available for substitution in the template
//
// Returns:
// - The rendered template output
// - An error if rendering fails (template syntax error, missing variables, etc.)
Render(template string, context map[string]interface{}) (string, error)
// RenderFile renders a template from a file with the given context variables.
// This is used for template files (e.g., *.tmpl) in the project template.
// The filePath should be an absolute or relative path to the template file.
// Returns the rendered output or an error if the file cannot be read or rendering fails.
//
// Parameters:
// - filePath: Path to the template file
// - context: Variables available for substitution in the template
//
// Returns:
// - The rendered template output
// - An error if the file cannot be read or rendering fails
RenderFile(filePath string, context map[string]interface{}) (string, error)
}
Engine defines the interface that template engines must implement. It is used to render template content with variable substitution.
func NewDefaultEngine ¶
func NewDefaultEngine() Engine
NewDefaultEngine returns a new default template engine (Pongo2). This is the recommended engine for most users. The Pongo2 engine supports Jinja2-like template syntax with variable substitution and filters.
Returns:
- A new Engine instance using Pongo2 for rendering
Example:
engine := pkg.NewDefaultEngine() gen, _ := pkg.NewGenerator(engine)
type Generator ¶
type Generator struct {
// contains filtered or unexported fields
}
Generator provides methods to generate projects from templates. A Generator is created once and can be used to generate multiple projects. It is safe for concurrent use when handling multiple project generations.
Example:
engine := pkg.NewDefaultEngine() gen := pkg.NewGenerator(engine) err := gen.Generate(ctx, "/path/to/template", variables, "/output/path")
func NewGenerator ¶
NewGenerator creates a new Generator with the specified template engine. The engine is used for rendering template files and strings. Returns an error if the engine is nil.
Parameters:
- engine: The template engine to use for rendering. Must not be nil.
Returns:
- A new Generator instance ready for use
- An error if the engine is nil
Example:
engine := pkg.NewDefaultEngine()
gen, err := pkg.NewGenerator(engine)
if err != nil {
log.Fatal(err)
}
func (*Generator) Generate ¶
func (g *Generator) Generate( ctx context.Context, templatePath string, variables map[string]interface{}, outputPath string, ) error
Generate renders a project template and writes the output to the specified directory. It is safe for concurrent use but respects the context for cancellation.
The function validates all inputs, loads the template configuration, processes all template files, and writes the output to the specified directory. Binary files are preserved without rendering.
Parameters:
- ctx: Context for cancellation and timeouts
- templatePath: Path to the template directory (must be absolute or relative)
- variables: Variables available for substitution in templates
- outputPath: Path where the generated project will be written (must be absolute or relative)
Returns:
- nil if generation succeeds
- An error if any step fails (validation, loading, rendering, or writing)
The function validates:
- templatePath is not empty and doesn't contain directory traversal attempts
- outputPath is not empty and doesn't contain directory traversal attempts
- All variables have valid names and values
- Context is not cancelled
Example:
gen, _ := pkg.NewGenerator(engine)
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
err := gen.Generate(ctx,
"/path/to/template",
map[string]interface{}{"project_name": "my-app"},
"/output/path")
type InvalidArgumentError ¶
InvalidArgumentError is returned when a required argument is invalid.
func (*InvalidArgumentError) Error ¶
func (e *InvalidArgumentError) Error() string
type Registry ¶
type Registry struct {
// contains filtered or unexported fields
}
Registry manages a local registry of templates. Templates are stored in the XDG Base Directory location (~/.local/share/ason/) and can be registered, listed, and removed programmatically.
A Registry instance is thread-safe and can be shared across goroutines. Use NewRegistry() for the default XDG location or NewRegistryAt(path) for custom paths.
Example:
registry, err := pkg.NewRegistry()
if err != nil {
log.Fatal(err)
}
err = registry.Register("my-template", "/path/to/template", "My template description")
if err != nil {
log.Fatal(err)
}
templates, err := registry.List()
if err != nil {
log.Fatal(err)
}
for _, tmpl := range templates {
fmt.Printf("%s: %s\n", tmpl.Name, tmpl.Path)
}
func NewRegistry ¶
NewRegistry creates a new Registry using the default XDG Base Directory location. The registry file is stored at ~/.local/share/ason/registry.toml If the registry file doesn't exist, it will be created on first write.
Returns:
- A new Registry instance ready for use
- An error if the XDG directory cannot be determined
Example:
registry, err := pkg.NewRegistry()
if err != nil {
log.Fatal(err)
}
func NewRegistryAt ¶
NewRegistryAt creates a new Registry at the specified path. This is useful for testing or using non-standard registry locations.
Parameters:
- registryPath: The path where the registry file will be stored
Returns:
- A new Registry instance
- An error if the registry cannot be loaded
Example:
registry, err := pkg.NewRegistryAt("/custom/path/registry.toml")
if err != nil {
log.Fatal(err)
}
func (*Registry) List ¶
func (r *Registry) List() ([]TemplateInfo, error)
List returns all templates registered in the registry. Templates are returned in alphabetical order by name. The registry is read-locked during this operation to allow concurrent reads.
Returns:
- A slice of TemplateInfo for all registered templates
- An error if the registry cannot be read
Example:
templates, err := registry.List()
if err != nil {
log.Fatal(err)
}
for _, tmpl := range templates {
fmt.Printf("%s: %s\n", tmpl.Name, tmpl.Path)
}
func (*Registry) Register ¶
Register adds or updates a template in the registry. If a template with the same name already exists, it is overwritten silently. The template path is validated before registration.
Parameters:
- name: The unique identifier for the template (alphanumeric + underscores)
- templatePath: The filesystem path to the template directory
- description: A human-readable description of the template
Returns:
- nil if the template is successfully registered
- An error if validation fails or the registry cannot be saved
Example:
err := registry.Register("golang-api", "/templates/golang-api", "Go API template")
if err != nil {
log.Fatal(err)
}
func (*Registry) Remove ¶
Remove deletes a template from the registry. If the template doesn't exist, no error is returned (idempotent operation). The registry is write-locked during this operation to prevent concurrent writes.
Parameters:
- name: The unique identifier of the template to remove
Returns:
- nil if the template is successfully removed
- An error if the registry cannot be saved
Example:
err := registry.Remove("golang-api")
if err != nil {
log.Fatal(err)
}
type TemplateInfo ¶
type TemplateInfo struct {
Name string `json:"name" toml:"name"`
Path string `json:"path" toml:"path"`
Created time.Time `json:"created" toml:"created"`
Description string `json:"description" toml:"description"`
}
TemplateInfo represents metadata about a registered template. It is returned by Registry.List() and contains all necessary information about a template's location and configuration.
Fields:
- Name: The unique identifier for the template in the registry
- Path: The filesystem path where the template is located
- Created: The timestamp when the template was registered
- Description: Human-readable description of the template's purpose