Documentation
¶
Overview ¶
Package interfaces contains interface definitions owned by the CLI commands.
Following ADR-002, interfaces are defined by their consumers, not providers. The CLI commands are the consumers, so they define the interfaces they need. Provider packages (generator, validation) implement these interfaces.
This pattern:
- Prevents import cycles (providers import interface package, not vice versa)
- Enables proper dependency inversion (high-level doesn't depend on low-level)
- Improves testability (easy to mock from consumer's perspective)
- Follows Go idiom: "accept interfaces, return structs"
Example:
// Consumer defines what it needs
type Validator interface {
ValidateProjectName(string) error
}
// Provider implements the interface
// internal/validation/validator.go
type Validator struct { ... }
func (v *Validator) ValidateProjectName(name string) error { ... }
// Command uses the interface
// internal/cli/commands/new.go
type NewCommand struct {
validator interfaces.Validator // Depends on interface, not implementation
}
See ADR-002 for the full decision rationale.
Package interfaces defines consumer-owned interfaces for CLI components.
Per ADR-002, interfaces should be defined in the consumer package, not the provider package. This enables dependency inversion and loose coupling.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Progress ¶
type Progress interface {
// Increment advances the progress by the specified amount.
// The total of all increments should equal ProgressSpec.Total.
Increment(n int64)
// Done marks the progress as complete and finalizes the display.
// Should be called after all increments are complete.
Done()
}
Progress tracks incremental updates for long-running operations.
Progress instances are created by calling Renderer.Progress() with a ProgressSpec. Use Increment to update progress and Done to mark completion.
Example:
progress := renderer.Progress(ProgressSpec{Label: "Processing", Total: 100})
for i := 0; i < 100; i++ {
// do work
progress.Increment(1)
}
progress.Done()
type ProgressSpec ¶
type ProgressSpec struct {
// Label is the human-readable description of the operation being tracked.
Label string
// Total is the maximum value representing 100% completion.
// Progress updates increment toward this value.
Total int64
}
ProgressSpec specifies the configuration for a progress tracker.
Used to create a Progress instance for tracking long-running operations such as file downloads, code generation, or batch processing.
Example:
spec := ProgressSpec{
Label: "Generating files",
Total: 42,
}
progress := renderer.Progress(spec)
type ProjectDetector ¶ added in v0.3.0
type ProjectDetector interface {
// Detect finds a Tracks project starting from the given directory.
// Searches upward through parent directories for .tracks.yaml.
// Returns project info and the directory containing .tracks.yaml.
// Returns an error if no .tracks.yaml is found.
Detect(ctx context.Context, startDir string) (*TracksProject, string, error)
// HasTemplUIConfig checks if .templui.json exists in the project directory.
HasTemplUIConfig(ctx context.Context, projectDir string) bool
}
ProjectDetector detects and reads Tracks project configuration.
Interface defined by consumer per ADR-002 to avoid import cycles. Context parameter enables request-scoped logger access per ADR-003.
type ProjectGenerator ¶
type ProjectGenerator interface {
Generate(ctx context.Context, cfg any) error
Validate(cfg any) error
}
ProjectGenerator generates new Tracks projects from templates.
This interface is owned by the CLI commands package, following ADR-002: interfaces are defined by consumers, not providers. The generator implementation will live in internal/generator/.
This pattern prevents import cycles and enables proper dependency inversion: CLI (high-level) defines interface, generator (low-level) implements it.
Note: The config parameter uses 'any' to avoid import cycles. The actual implementation uses generator.ProjectConfig. This follows the pattern of accepting concrete types from the provider package without importing it.
Example usage:
gen := generator.NewProjectGenerator()
cfg := generator.ProjectConfig{
Name: "myapp",
ModulePath: "github.com/user/myapp",
}
if err := gen.Generate(ctx, cfg); err != nil {
return err
}
type Renderer ¶
type Renderer interface {
// Title displays a prominent title or heading.
// Used for the main title of command output.
Title(s string)
// Section displays a titled section with body content.
// Used for grouping related information under a heading.
Section(sec Section)
// Table displays tabular data with headers and rows.
// Used for structured data like lists of items or summaries.
Table(t Table)
// Progress creates and returns a Progress tracker for long-running operations.
// The returned Progress interface allows incremental updates and completion.
Progress(spec ProgressSpec) Progress
// Flush ensures all buffered output is written.
// Should be called after all other methods to guarantee output visibility.
// Returns an error if the flush operation fails.
Flush() error
}
Renderer is the interface that wraps the basic CLI output methods.
Defined in consumer package per ADR-002: Interface Placement in Consumer Packages.
Implementations of this interface handle different output modes:
- ConsoleRenderer: Human-friendly output with colors and formatting
- JSONRenderer: Machine-readable JSON output for scripting
- TUIRenderer: Interactive terminal UI (future implementation)
All Renderer methods are designed to be called sequentially during command execution, with Flush called at the end to ensure all output is written.
type Section ¶
type Section struct {
// Title is the section heading, displayed prominently.
Title string `json:"title"`
// Body is the section content, may span multiple lines.
Body string `json:"body"`
}
Section represents a titled content block.
Sections are used to organize output into logical groups, each with a heading (Title) and descriptive content (Body).
Example:
Section{
Title: "Project Configuration",
Body: "Using Chi router with templ templates and SQLC for database access.",
}
type Table ¶
type Table struct {
// Headers are the column names displayed at the top of the table.
Headers []string `json:"headers"`
// Rows contains the table data, where each row is a slice of cell values.
// Rows with fewer cells than Headers will be padded with empty strings.
// Extra cells beyond the number of headers are ignored.
Rows [][]string `json:"rows"`
}
Table represents structured tabular data.
Tables display data in rows and columns with headers. All rows should have the same number of columns as Headers.
Example:
Table{
Headers: []string{"Name", "Type", "Status"},
Rows: [][]string{
{"user.go", "model", "created"},
{"user_test.go", "test", "created"},
},
}
type TracksProject ¶ added in v0.3.0
TracksProject contains metadata from .tracks.yaml.
type UIComponent ¶ added in v0.3.0
UIComponent represents a templUI component.
type UIExecutor ¶ added in v0.3.0
type UIExecutor interface {
// Version returns the templUI CLI version string.
Version(ctx context.Context, projectDir string) (string, error)
// Add installs one or more components into the project.
// If ref is non-empty, uses that version (e.g., "v0.1.0").
// If force is true, overwrites existing components.
Add(ctx context.Context, projectDir, ref string, components []string, force bool) error
// List returns available components from the templUI registry.
// If ref is non-empty, lists components from that version.
List(ctx context.Context, projectDir, ref string) ([]UIComponent, error)
// Upgrade updates the templUI tool.
// If ref is non-empty, upgrades to that version; otherwise upgrades to latest.
Upgrade(ctx context.Context, projectDir, ref string) error
// IsAvailable checks if templui tool is installed and accessible.
IsAvailable(ctx context.Context, projectDir string) bool
}
UIExecutor wraps templUI CLI commands for UI component management.
Interface defined by consumer per ADR-002 to avoid import cycles. Context parameter enables request-scoped logger access per ADR-003.
type Validator ¶
type Validator interface {
ValidateProjectName(ctx context.Context, name string) error
ValidateModulePath(ctx context.Context, path string) error
ValidateDirectory(ctx context.Context, path string) error
ValidateDatabaseDriver(ctx context.Context, driver string) error
ValidateEnvPrefix(ctx context.Context, prefix string) error
}
Validator validates project configuration values.
Interface defined by consumer per ADR-002 to avoid import cycles. Context parameter enables request-scoped logger access per ADR-003.