planner

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Dec 19, 2025 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package planner provides build planning for Buildfiles.

Build planning involves:

  • Target pattern matching (literal and pattern targets)
  • Dependency resolution
  • Staleness detection
  • Build task ordering

The planner operates on the validated AST and semantic analysis results to produce an executable build plan.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func LookupTarget

func LookupTarget(path string, targets []*ast.Target) (*ast.Target, map[string]string, error)

LookupTarget finds a target definition that matches the given path. It returns the matching target, capture values, and any error.

Lookup order:

  1. Exact literal matches are preferred over pattern matches
  2. Among patterns, first match in definition order wins

Phony targets can be referenced with or without the @ prefix.

func MatchTarget

func MatchTarget(pattern *ast.TargetPattern, path string) (bool, map[string]string)

MatchTarget attempts to match a concrete path against a target pattern. Returns true if the pattern matches, along with a map of capture values. For literal patterns (no captures), the map will be empty.

Matching rules:

  • Literal segments must match exactly
  • Captures match any sequence of characters (including slashes)
  • Duplicate capture names must have the same value
  • Phony targets match with or without @ prefix (@ is only for declaration)
  • Directory targets can match with or without trailing slash

func ParseAutodeps

func ParseAutodeps(content string) ([]string, error)

ParseAutodeps parses Makefile-style dependency content (from gcc -MD, etc.) and returns a list of dependency paths.

Format:

target: dep1 dep2 dep3
target: dep1 \
  dep2 \
  dep3

func ParseAutodepsFile

func ParseAutodepsFile(path string) ([]string, error)

ParseAutodepsFile reads and parses a .d file. Returns empty slice (not error) if file doesn't exist.

func ResolveDependencies

func ResolveDependencies(deps []ast.Dependency, captures map[string]string, ctx *eval.Context) ([]string, error)

ResolveDependencies resolves multiple dependencies to concrete paths.

It processes each dependency in order and returns a slice of resolved paths. If any dependency fails to resolve, an error is returned immediately.

Special handling: if a dependency consists of exactly one BraceExpr (e.g., {objects}), and the resolved value contains spaces, it is split into multiple paths. This allows variables like "objects = build/main.o build/utils.o" to expand into multiple dependencies.

func ResolveDependency

func ResolveDependency(dep ast.Dependency, captures map[string]string, ctx *eval.Context) (string, error)

ResolveDependency resolves a single dependency pattern to a concrete path.

Resolution order for {name} in dependency patterns:

  1. If name is in captures (from pattern matching), use capture value
  2. If name is defined in context (user variable or built-in), use variable value
  3. Otherwise, return error for undefined variable

This function is used during build planning to convert pattern-based dependencies into concrete file paths.

Types

type BuildPlan

type BuildPlan struct {
	Tasks []BuildTask
}

BuildPlan contains a topologically sorted list of build tasks.

func PlanBuild

func PlanBuild(requestedTarget string, targets []*ast.Target, ctx *eval.Context, fs FileSystem) (*BuildPlan, error)

PlanBuild creates a build plan for the requested target.

It performs:

  1. Target lookup (finding matching target definition)
  2. Dependency resolution (converting patterns to concrete paths)
  3. Recursive planning (planning all dependencies first)
  4. Staleness detection (determining if rebuild is needed)
  5. Topological sorting (ordering tasks for execution)

func PlanBuildWithEmitter

func PlanBuildWithEmitter(requestedTarget string, targets []*ast.Target, ctx *eval.Context, fs FileSystem, emitter *output.Emitter) (*BuildPlan, error)

PlanBuildWithEmitter creates a build plan with event emission. If emitter is non-nil, staleness check events are emitted.

func PlanBuildWithOptions

func PlanBuildWithOptions(requestedTarget string, targets []*ast.Target, ctx *eval.Context, fs FileSystem, autodepsCache *cache.AutodepsCache, verboseOutput io.Writer) (*BuildPlan, error)

PlanBuildWithOptions creates a build plan with all optional parameters. If autodepsCache is non-nil, .d file parsing results are cached. If verboseOutput is non-nil, staleness check decisions are written to it.

func PlanBuildWithVerbose

func PlanBuildWithVerbose(requestedTarget string, targets []*ast.Target, ctx *eval.Context, fs FileSystem, verboseOutput io.Writer) (*BuildPlan, error)

PlanBuildWithVerbose creates a build plan with optional verbose output. If verboseOutput is non-nil, staleness check decisions are written to it.

type BuildReason

type BuildReason int

BuildReason indicates why a target needs to be rebuilt.

const (
	BuildReasonTargetMissing BuildReason = iota
	BuildReasonDependencyNewer
	BuildReasonPhonyTarget
	BuildReasonForcedRebuild
)

func (BuildReason) String

func (r BuildReason) String() string

type BuildTask

type BuildTask struct {
	// Target is the path to be built (with @ prefix for phony targets)
	Target string

	// Dependencies are the resolved paths of dependencies
	Dependencies []string

	// AutodepsDeps are additional dependencies from .autodeps file
	// These are learned from previous builds (e.g., header files)
	AutodepsDeps []string

	// OrderOnlyDeps are order-only dependencies (from .after: directives)
	// These must exist/be built before this target but don't affect staleness
	OrderOnlyDeps []string

	// Recipe is the recipe to execute (may be nil for phony without recipe)
	Recipe *ast.Recipe

	// Reason indicates why this target needs rebuilding
	Reason BuildReason

	// Captures holds pattern capture values (for pattern targets)
	Captures map[string]string

	// TargetDef is the AST target definition
	TargetDef *ast.Target

	// AutodepsPath is the .autodeps file path to update after build
	AutodepsPath string
}

BuildTask represents a single task in the build plan.

type CircularDependencyError

type CircularDependencyError struct {
	Path []string
}

CircularDependencyError is returned when a circular dependency is detected.

func (*CircularDependencyError) Error

func (e *CircularDependencyError) Error() string

type CompiledPattern

type CompiledPattern struct {
	Target       *ast.Target
	Prefix       string   // Literal prefix before first capture (empty if starts with capture)
	IsLiteral    bool     // True if no captures (after resolving interpolations)
	IsPhony      bool     // True if phony target
	PatternStr   string   // String representation for debugging (with interpolations resolved)
	Captures     []string // Capture names in order (only actual captures, not interpolations)
	ResolvedPath string   // Fully resolved path for literal patterns
}

CompiledPattern is a pre-processed target pattern for faster matching.

type FileSystem

type FileSystem interface {
	Exists(path string) bool
	ModTime(path string) (time.Time, error)
}

FileSystem abstracts file system operations for testability.

type MissingSourceError

type MissingSourceError struct {
	Path string
}

MissingSourceError is returned when a source file doesn't exist.

func (*MissingSourceError) Error

func (e *MissingSourceError) Error() string

type TargetIndex

type TargetIndex struct {
	// contains filtered or unexported fields
}

TargetIndex provides optimized target lookup using pre-compiled patterns. It groups targets by their literal prefix for faster lookup.

func NewTargetIndex

func NewTargetIndex(targets []*ast.Target, ctx *eval.Context) *TargetIndex

NewTargetIndex creates an optimized index for fast target lookup. The context is used to resolve variable interpolations in target patterns.

func (*TargetIndex) Lookup

func (idx *TargetIndex) Lookup(path string) (*ast.Target, map[string]string, error)

Lookup finds a target that matches the given path. Returns the target, capture values, and any error.

func (*TargetIndex) Size

func (idx *TargetIndex) Size() int

Size returns the number of targets in the index.

type TargetNotFoundError

type TargetNotFoundError struct {
	Path string
}

TargetNotFoundError is returned when a target path cannot be matched against any defined target.

func (*TargetNotFoundError) Error

func (e *TargetNotFoundError) Error() string

type UndefinedVariableError

type UndefinedVariableError struct {
	Name string
}

UndefinedVariableError is returned when a variable in a dependency pattern cannot be resolved.

func (*UndefinedVariableError) Error

func (e *UndefinedVariableError) Error() string

Jump to

Keyboard shortcuts

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