pkg

package
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 17, 2025 License: MIT Imports: 13 Imported by: 0

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

func NewGenerationError(phase, reason string) error

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

func NewGenerator(engine Engine) (*Generator, error)

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")

func (*Generator) GetEngine

func (g *Generator) GetEngine() Engine

GetEngine returns the template engine used by this generator. This is primarily useful for testing or inspecting the engine configuration.

type InvalidArgumentError

type InvalidArgumentError struct {
	Argument string
	Reason   string
}

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

func NewRegistry() (*Registry, error)

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

func NewRegistryAt(registryPath string) (*Registry, error)

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

func (r *Registry) Register(name string, templatePath string, description string) error

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

func (r *Registry) Remove(name string) error

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

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL