weft

module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Sep 2, 2025 License: MIT

README

noun - the horizontal threads in weaving, creating the fabric's structure.

weft

A Go template engine for code generation with extensible post-processing, state management, debugging, and testing utilities.

Packages

  • config - Generic YAML configuration loading with validation support
  • engine - Core template processing with caching and concurrent rendering
  • postprocess - Extensible post-processing framework for transforming generated content
  • processors - Built-in post-processors (Go imports, whitespace cleanup, headers, etc.)
  • render - Template discovery, blocks, includes, and function registry
  • write - File writing with coordination, locking, and composite operations
  • state - File tracking, manifest management, and cleanup operations
  • debug - Debugging, error handling, and template validation
  • testing - Testing utilities, benchmarks, mocks, and snapshots

Basic Usage

package main

import (
    "github.com/cpcf/weft/engine"
    "github.com/cpcf/weft/processors"
)

func main() {
    // Create template engine
    eng := engine.New(
        engine.WithOutputRoot("./generated"),
        engine.WithFailureMode(engine.FailFast),
    )

    // Add post-processors for generated content
    eng.AddPostProcessor(processors.NewGoImports())                // Fix Go imports & formatting
    eng.AddPostProcessor(processors.NewTrimWhitespace())           // Clean whitespace
    eng.AddPostProcessor(processors.NewAddGeneratedHeader("myapp", ".go")) // Add headers
    
    // Create context
    ctx := engine.NewContext(templateFS, "./generated", "mypackage")
    
    // Render templates with post-processing
    if err := eng.RenderDir(ctx, "templates", data); err != nil {
        log.Fatal(err)
    }
}
Custom Template Functions

weft supports custom template functions alongside its built-in functions:

import (
    "text/template"
    "time"
    "github.com/cpcf/weft/engine"
)

// Define custom functions
customFuncs := template.FuncMap{
    "formatDate": func(t time.Time) string {
        return t.Format("2006-01-02")
    },
    "calculateTax": func(amount float64, rate float64) float64 {
        return amount * rate
    },
}

// Create engine with custom functions
eng := engine.New(
    engine.WithCustomFunctions(customFuncs),
    engine.WithOutputRoot("./generated"),
)

// Use in templates:
// {{formatDate .CreatedAt}}
// {{calculateTax .Amount 0.08}}

Post-Processing System

weft includes an extensible post-processing framework that transforms generated content:

Built-in Processors
  • Go Imports - Automatically fixes imports and formats Go code using goimports
  • Trim Whitespace - Removes trailing whitespace from all lines
  • Generated Headers - Adds "Code generated" headers to files
  • Regex Replace - Custom regex-based transformations
Custom Processors

Create custom processors by implementing the postprocess.Processor interface:

type MyProcessor struct{}

func (p *MyProcessor) ProcessContent(filePath string, content []byte) ([]byte, error) {
    if strings.HasSuffix(filePath, ".go") {
        // Custom Go transformations
        return transformGoCode(content), nil
    }
    return content, nil
}

// Add to engine
eng.AddPostProcessor(&MyProcessor{})
Function-based Processors

For simple transformations, use function processors:

eng.AddPostProcessorFunc(func(filePath string, content []byte) ([]byte, error) {
    // Convert line endings to Unix style
    return bytes.ReplaceAll(content, []byte("\r\n"), []byte("\n")), nil
})

See postprocess/README.md for comprehensive documentation.

Configuration Loading

The config package provides utilities for loading YAML configuration files into your custom types:

import "github.com/cpcf/weft/config"

type MyConfig struct {
    Name    string            `yaml:"name"`
    Version string            `yaml:"version"`
    Options map[string]string `yaml:"options"`
}

func main() {
    var cfg MyConfig
    
    // Load configuration from YAML file
    err := config.LoadYAML("config.yaml", &cfg)
    if err != nil {
        log.Fatal(err)
    }
    
    // Use configuration with template engine
    eng := engine.New(engine.WithOutputRoot(cfg.Options["output_dir"]))
    // ...
}

See config/README.md for detailed documentation including validation and testing utilities.

Examples

Directories

Path Synopsis
Package config provides generic configuration loading capabilities for weft
Package config provides generic configuration loading capabilities for weft
Package debug provides helpers for debugging template rendering.
Package debug provides helpers for debugging template rendering.
Package engine provides the core template rendering and post-processing functionality.
Package engine provides the core template rendering and post-processing functionality.
Package postprocess provides a generic framework for post-processing generated content.
Package postprocess provides a generic framework for post-processing generated content.
Package processors provides built-in post-processors for common use cases.
Package processors provides built-in post-processors for common use cases.
Package render provides template rendering functionality.
Package render provides template rendering functionality.
Package state provides a manifest for tracking the state of generated files.
Package state provides a manifest for tracking the state of generated files.
Package testing provides utilities for testing and benchmarking.
Package testing provides utilities for testing and benchmarking.
Package write provides a generic interface for writing files.
Package write provides a generic interface for writing files.

Jump to

Keyboard shortcuts

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