Documentation
¶
Overview ¶
Package filter provides a parser and evaluator for filter query strings used to select Terragrunt components.
Overview ¶
The filter package implements a three-stage compiler architecture:
- Lexer: Tokenizes the input filter query string
- Parser: Builds an Abstract Syntax Tree (AST) from tokens
- Evaluator: Applies the filter logic to discovered Terragrunt components
This design follows the classic compiler pattern and provides a clean separation of concerns between syntax analysis and semantic evaluation.
Filter Syntax ¶
The filter package supports the following syntax elements:
## Path Filters
Path filters match components by their file system path. They support glob patterns:
./apps/frontend # Exact path match ./apps/* # Single-level wildcard ./apps/**/api # Recursive wildcard /absolute/path # Absolute path
## Attribute Filters
Attribute filters match components by their attributes:
name=my-app # Match by config name (directory basename) type=unit # Match components of type "unit" type=stack # Match components of type "stack" external=true # Match external dependencies external=false # Match internal dependencies (not external) foo # Shorthand for name=foo
## Negation Operator (!)
The negation operator excludes matching components:
!name=legacy # Exclude components named "legacy" !./apps/old # Exclude components at path ./apps/old !foo # Exclude components named "foo" !external=true # Exclude external dependencies
## Intersection Operator (|)
The intersection operator refines/narrows results by applying filters from left to right. Each filter in the chain further restricts the results from the previous filter. The pipe character (|) is the only delimiter between filter expressions. Whitespace is optional around operators but is NOT a delimiter itself.
./apps/* | name=web # Components in ./apps/* AND named "web" ./apps/*|name=web # Same as above (spaces optional) ./foo* | !./foobar* # Components in ./foo* AND NOT in ./foobar* type=unit | !external=true # Internal components only
Spaces within component names and paths are preserved:
my app # Component named "my app" (with space) ./my path/file # Path with spaces
## Braced Path Syntax ({})
Use braces to explicitly mark a path expression. This is useful when: - The path doesn't start with ./ or / - You want to be explicit that something is a path, not an identifier
{./apps/*} # Explicitly a path
{my path/file} # Path without ./ prefix
{apps} # Treat "apps" as a path, not a name filter
## Graph Traversal Operators (...)
Graph traversal operators include dependencies and/or dependents in the result:
foo... # foo and all its dependencies (transitive) ...foo # foo and all its dependents (transitive) ...foo... # foo, all its dependencies, and all its dependents ^foo... # All dependencies of foo, excluding foo itself ...^foo # All dependents of foo, excluding foo itself
Depth-limited traversal allows specifying how many levels to traverse. Place the depth number on the outside of the ellipsis:
foo...1 # foo and its direct dependencies only foo...2 # foo and dependencies up to 2 levels deep 1...foo # foo and its direct dependents only 2...foo # foo and dependents up to 2 levels deep 1...foo...2 # Direct dependents and dependencies up to 2 levels
When depth is not specified, traversal is unlimited (default behavior).
## Numeric Directory Disambiguation
When a purely numeric token appears adjacent to "...", it is interpreted as a depth:
1...1 # Parsed as: dependent depth 1, target "1"
# (first 1 is depth, second 1 is target)
To explicitly specify a numeric directory as the target, use escape hatches:
Braced path syntax (for path filters):
{1}...1 # target path "1", dependency depth 1
1...{1} # dependent depth 1, target path "1"
1...{1}...1 # depth 1 dependents, path "1", depth 1 dependencies
Explicit name attribute (for name filters):
name=1...1 # target name=1, dependency depth 1 1...name=1 # dependent depth 1, target name=1
Alphanumeric names are not ambiguous (only purely numeric tokens are depths):
1...1foo # dependent depth 1, target "1foo" foo1...1 # target "foo1", dependency depth 1
Operator Precedence ¶
Operators are evaluated with the following precedence (highest to lowest):
- Prefix operators (!)
- Infix operators (| - intersection/refinement, left-to-right)
This means !foo | bar is evaluated as (!foo) | bar, not !(foo | bar). The intersection operator applies filters left-to-right, each filter refining/narrowing the results from the previous filter.
Usage Examples ¶
## Basic Usage
// Parse a filter query
filter, err := filter.Parse("./apps/* | !legacy", ".")
if err != nil {
log.Fatal(err)
}
// Apply the filter to discovered components
// (typically obtained from discovery.Discover())
components := []*component.Component{
{Path: "./apps/app1", Kind: component.Unit},
{Path: "./apps/legacy", Kind: component.Unit},
{Path: "./libs/db", Kind: component.Unit},
}
result, err := filter.Evaluate(components)
if err != nil {
log.Fatal(err)
}
## Multiple Filters (Union)
Multiple filter queries can be combined using the Filters type, which applies union (OR) semantics. This is different from using | within a single filter, which applies intersection (AND) semantics.
// Parse multiple filter queries
filters, err := filter.ParseFilterQueries([]string{
"./apps/*", // Select all apps
"name=db", // OR select db
}, ".")
if err != nil {
log.Fatal(err)
}
result, err := filters.Evaluate(components)
// Returns: all components in ./apps/* OR components named "db"
Multiple filters are evaluated in two phases:
- Positive filters (non-negated) are evaluated and their results are unioned
- Negative filters (starting with !) are applied to remove matching components
The ExcludeByDefault() method signals whether filters operate in exclude-by-default mode. This is true if ANY filter doesn't start with a negation expression:
filters.ExcludeByDefault() // true if any filter is positive
When true, discovery should start with an empty set and add matches. When false (all filters are negated), discovery should start with all components and remove matches.
## One-Shot Usage
// Parse and evaluate in one step
result, err := filter.Apply("./apps/* | name=web", ".", components)
Implementation Details ¶
## Lexer
The lexer (lexer.go) scans the input string and produces tokens:
- IDENT: Identifiers (foo, name, etc.)
- PATH: Paths (./apps/*, /absolute, etc.)
- BANG: Negation operator (!)
- PIPE: Intersection operator (|)
- EQUAL: Assignment operator (=)
- LBRACE: Left brace ({)
- RBRACE: Right brace (})
- EOF: End of input
## Parser
The parser (parser.go) uses recursive descent parsing with Pratt parsing for operators. It produces an AST with the following node types:
- PathFilter: Path/glob filter
- AttributeFilter: Key-value attribute filter
- PrefixExpression: Negation operator
- InfixExpression: Union operator
## Evaluator
The evaluator (evaluator.go) walks the AST and applies the filter logic:
- PathFilter: Uses glob matching (github.com/gobwas/glob) with eager compilation and caching via sync.Once for performance
- AttributeFilter: Matches attributes by key-value pairs:
- name: Matches filepath.Base(component.Path)
- type: Matches component.Kind (unit or stack)
- external: Matches component.External (true or false)
- PrefixExpression: Returns the complement of the right side
- InfixExpression: Returns the intersection by applying right filter to left results
Path filters compile their glob pattern once on first evaluation and cache the compiled result for reuse in subsequent evaluations, providing significant performance improvements when filters are evaluated multiple times.
Related ¶
This package implements the filter syntax described in RFC #4060: https://github.com/gruntwork-io/terragrunt/issues/4060
The syntax is inspired by Turborepo's filter syntax: https://turbo.build/repo/docs/reference/run#--filter-string
Future Enhancements ¶
Future versions will support:
- Git-based filtering ([main...HEAD])
- Dependency traversal (name=foo...)
- Dependents traversal (...name=foo)
- Read-based filtering (reads=path/to/file)
Package filter provides telemetry support for git worktree operations and filter evaluation.
Example (AttributeFilter) ¶
Example_attributeFilter demonstrates filtering components by name attribute.
package main
import (
"fmt"
"github.com/gruntwork-io/terragrunt/internal/component"
"github.com/gruntwork-io/terragrunt/internal/filter"
"github.com/gruntwork-io/terragrunt/pkg/log"
)
func main() {
components := []component.Component{
component.NewUnit("./apps/frontend").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./apps/backend").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./services/api").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
}
l := log.New()
result, _ := filter.Apply(l, "name=api", components)
for _, c := range result {
fmt.Println(c.Path())
}
}
Output: ./services/api
Example (BasicPathFilter) ¶
Example_basicPathFilter demonstrates filtering components by path with a glob pattern.
package main
import (
"fmt"
"path/filepath"
"github.com/gruntwork-io/terragrunt/internal/component"
"github.com/gruntwork-io/terragrunt/internal/filter"
"github.com/gruntwork-io/terragrunt/pkg/log"
)
func main() {
components := []component.Component{
component.NewUnit("./apps/app1").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./apps/app2").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./libs/db").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
}
l := log.New()
result, _ := filter.Apply(l, "./apps/*", components)
for _, c := range result {
fmt.Println(filepath.Base(c.Path()))
}
}
Output: app1 app2
Example (ComplexQuery) ¶
Example_complexQuery demonstrates a complex filter combining paths and negation.
package main
import (
"fmt"
"path/filepath"
"github.com/gruntwork-io/terragrunt/internal/component"
"github.com/gruntwork-io/terragrunt/internal/filter"
"github.com/gruntwork-io/terragrunt/pkg/log"
)
func main() {
components := []component.Component{
component.NewUnit("./services/web").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./services/worker").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./libs/db").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./libs/api").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./libs/cache").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
}
// Select all services except worker
l := log.New()
result, _ := filter.Apply(l, "./services/* | !worker", components)
for _, c := range result {
fmt.Println(filepath.Base(c.Path()))
}
}
Output: web
Example (ErrorHandling) ¶
Example_errorHandling demonstrates handling parsing errors.
package main
import (
"fmt"
"github.com/gruntwork-io/terragrunt/internal/filter"
)
func main() {
// Invalid syntax - missing value after =
_, err := filter.Parse("name=")
if err != nil {
fmt.Println("Error occurred")
}
// Valid syntax
_, err = filter.Parse("name=foo")
if err == nil {
fmt.Println("Successfully parsed")
}
}
Output: Error occurred Successfully parsed
Example (ExclusionFilter) ¶
Example_exclusionFilter demonstrates excluding components using the negation operator.
package main
import (
"fmt"
"path/filepath"
"github.com/gruntwork-io/terragrunt/internal/component"
"github.com/gruntwork-io/terragrunt/internal/filter"
"github.com/gruntwork-io/terragrunt/pkg/log"
)
func main() {
components := []component.Component{
component.NewUnit("./apps/app1").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./apps/app2").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./apps/legacy").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
}
l := log.New()
result, _ := filter.Apply(l, "!legacy", components)
for _, c := range result {
fmt.Println(filepath.Base(c.Path()))
}
}
Output: app1 app2
Example (IntersectionFilter) ¶
Example_intersectionFilter demonstrates refining results with the intersection operator.
package main
import (
"fmt"
"path/filepath"
"github.com/gruntwork-io/terragrunt/internal/component"
"github.com/gruntwork-io/terragrunt/internal/filter"
"github.com/gruntwork-io/terragrunt/pkg/log"
)
func main() {
components := []component.Component{
component.NewUnit("./apps/frontend").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./apps/backend").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./libs/db").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./libs/api").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
}
// Select components in ./apps/ that are named "frontend"
l := log.New()
result, _ := filter.Apply(l, "./apps/* | frontend", components)
for _, c := range result {
fmt.Println(filepath.Base(c.Path()))
}
}
Output: frontend
Example (MultipleFilters) ¶
Example_multipleFilters demonstrates using multiple filters with union semantics.
package main
import (
"fmt"
"path/filepath"
"sort"
"github.com/gruntwork-io/terragrunt/internal/component"
"github.com/gruntwork-io/terragrunt/internal/filter"
"github.com/gruntwork-io/terragrunt/pkg/log"
"github.com/gruntwork-io/terragrunt/pkg/log/format"
)
// exampleLogger creates a logger for examples with a proper formatter.
func exampleLogger() log.Logger {
formatter := format.NewFormatter(format.NewKeyValueFormatPlaceholders())
formatter.SetDisabledColors(true)
return log.New(log.WithFormatter(formatter))
}
func main() {
components := []component.Component{
component.NewUnit("./apps/app1").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./apps/app2").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./libs/db").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./libs/api").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
}
l := exampleLogger()
// Parse multiple filters - results are unioned
filters, _ := filter.ParseFilterQueries(l, []string{
"./apps/*",
"name=db",
})
result, _ := filters.Evaluate(l, components)
// Sort for consistent output
names := make([]string, len(result))
for i, c := range result {
names[i] = filepath.Base(c.Path())
}
sort.Strings(names)
for _, name := range names {
fmt.Println(name)
}
}
Output: app1 app2 db
Example (ParseAndEvaluate) ¶
Example_parseAndEvaluate demonstrates the two-step process of parsing and evaluating.
package main
import (
"fmt"
"github.com/gruntwork-io/terragrunt/internal/component"
"github.com/gruntwork-io/terragrunt/internal/filter"
"github.com/gruntwork-io/terragrunt/pkg/log"
)
func main() {
components := []component.Component{
component.NewUnit("./apps/app1").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./apps/app2").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
}
// Parse the filter once
f, err := filter.Parse("app1")
if err != nil {
fmt.Println("Parse error:", err)
return
}
// Evaluate multiple times with different config sets
l := log.New()
result1, _ := f.Evaluate(l, components)
fmt.Printf("Found %d components\n", len(result1))
// You can also inspect the original query
fmt.Printf("Original query: %s\n", f.String())
}
Output: Found 1 components Original query: app1
Example (RecursiveWildcard) ¶
Example_recursiveWildcard demonstrates using recursive wildcards to match nested paths.
package main
import (
"fmt"
"path/filepath"
"github.com/gruntwork-io/terragrunt/internal/component"
"github.com/gruntwork-io/terragrunt/internal/filter"
"github.com/gruntwork-io/terragrunt/pkg/log"
)
func main() {
components := []component.Component{
component.NewUnit("./infrastructure/networking/vpc").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./infrastructure/networking/subnets").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
component.NewUnit("./infrastructure/compute/app-server").WithDiscoveryContext(&component.DiscoveryContext{
WorkingDir: ".",
}),
}
// Match all infrastructure components at any depth
l := log.New()
result, _ := filter.Apply(l, "./infrastructure/**", components)
for _, c := range result {
fmt.Println(filepath.Base(c.Path()))
}
}
Output: vpc subnets app-server
Index ¶
- Constants
- func Apply(l log.Logger, filterString string, components component.Components) (component.Components, error)
- func Evaluate(l log.Logger, expr Expression, components component.Components) (component.Components, error)
- func FormatDiagnostic(err *ParseError, filterIndex int, useColor bool) string
- func GetHint(code ErrorCode, token, query string, position int) string
- func IsNegated(expr Expression) bool
- func MatchComponent(c component.Component, expr Expression) bool
- func NewEvaluationError(message string) error
- func NewEvaluationErrorWithCause(message string, cause error) error
- func NewParseError(message string, position int) error
- func NewParseErrorWithContext(title, message string, position, errorPosition int, query, tokenLiteral string, ...) error
- func TraceFilterEvaluate(ctx context.Context, filterCount, componentCount int, ...) error
- func TraceFilterParse(ctx context.Context, query string, fn func(ctx context.Context) error) error
- func TraceGitDiff(ctx context.Context, fromRef, toRef, repoRemote string, ...) error
- func TraceGitFilterEvaluate(ctx context.Context, fromRef, toRef string, componentCount int, ...) error
- func TraceGitFilterExpand(ctx context.Context, fromRef, toRef string, ...) error
- func TraceGitWorktreeCreate(ctx context.Context, ...) error
- func TraceGitWorktreeDiscovery(ctx context.Context, pairCount int, fn func(ctx context.Context) error) error
- func TraceGitWorktreeFilterApply(ctx context.Context, filterCount, resultCount int, ...) error
- func TraceGitWorktreeRemove(ctx context.Context, ref, worktreeDir string, ...) error
- func TraceGitWorktreeStackWalk(ctx context.Context, fromRef, toRef string, fn func(ctx context.Context) error) error
- func TraceGitWorktreesCleanup(ctx context.Context, pairCount int, repoRemote string, ...) error
- func TraceGitWorktreesCreate(ctx context.Context, workingDir string, refCount int, ...) error
- func TraceGraphFilterTraverse(ctx context.Context, filterType string, componentCount int, ...) error
- func WalkExpressions(expr Expression, fn func(Expression) bool)
- type AttributeExpression
- func (a *AttributeExpression) Glob() glob.Glob
- func (a *AttributeExpression) IsRestrictedToStacks() bool
- func (a *AttributeExpression) Negated() Expression
- func (a *AttributeExpression) RequiresDiscovery() (Expression, bool)
- func (a *AttributeExpression) RequiresParse() (Expression, bool)
- func (a *AttributeExpression) String() string
- type CandidacyReason
- type ClassificationContext
- type ClassificationStatus
- type Classifier
- func (c *Classifier) Classify(comp component.Component, classCtx ClassificationContext) (ClassificationStatus, CandidacyReason, int)
- func (c *Classifier) GraphExpressions() []*GraphExpressionInfo
- func (c *Classifier) HasDependentFilters() bool
- func (c *Classifier) HasGraphFilters() bool
- func (c *Classifier) HasParseRequiredFilters() bool
- func (c *Classifier) HasPositiveFilters() bool
- func (c *Classifier) NegatedExpressions() []Expression
- func (c *Classifier) ParseExpressions() []Expression
- type ErrorCode
- type EvaluationContext
- type EvaluationError
- type Expression
- type Expressions
- type Filter
- type FilterQueryRequiresDiscoveryError
- type Filters
- func (f Filters) DependencyGraphExpressions() []Expression
- func (f Filters) DependentGraphExpressions() []Expression
- func (f Filters) Evaluate(l log.Logger, components component.Components) (component.Components, error)
- func (f Filters) EvaluateOnFiles(l log.Logger, files []string, workingDir string) (component.Components, error)
- func (f Filters) ExcludingGitFilters() Filters
- func (f Filters) HasPositiveFilter() bool
- func (f Filters) RequiresDiscovery() (Expression, bool)
- func (f Filters) RequiresParse() (Expression, bool)
- func (f Filters) RestrictToStacks() Filters
- func (f Filters) String() string
- func (f Filters) UniqueGitFilters() GitExpressions
- type GitExpression
- type GitExpressions
- type GraphDirection
- type GraphExpression
- func (g *GraphExpression) IsRestrictedToStacks() bool
- func (g *GraphExpression) Negated() Expression
- func (g *GraphExpression) RequiresDiscovery() (Expression, bool)
- func (g *GraphExpression) RequiresParse() (Expression, bool)
- func (g *GraphExpression) String() string
- func (g *GraphExpression) WithDependencies() *GraphExpression
- func (g *GraphExpression) WithDependents() *GraphExpression
- func (g *GraphExpression) WithExcludeTarget() *GraphExpression
- type GraphExpressionInfo
- type InfixExpression
- type Lexer
- type ParseError
- type Parser
- type PathExpression
- func (p *PathExpression) Glob() glob.Glob
- func (p *PathExpression) IsRestrictedToStacks() bool
- func (p *PathExpression) Negated() Expression
- func (p *PathExpression) RequiresDiscovery() (Expression, bool)
- func (p *PathExpression) RequiresParse() (Expression, bool)
- func (p *PathExpression) String() string
- type PrefixExpression
- type Token
- type TokenType
Examples ¶
Constants ¶
const ( AttributeName = "name" AttributeType = "type" AttributeExternal = "external" AttributeReading = "reading" AttributeSource = "source" AttributeTypeValueUnit = string(component.UnitKind) AttributeTypeValueStack = string(component.StackKind) AttributeExternalValueTrue = "true" AttributeExternalValueFalse = "false" // MaxTraversalDepth is the maximum depth to traverse the graph for both dependencies and dependents. MaxTraversalDepth = 1000000 )
const ( LOWEST int INTERSECTION // | PREFIX // ! )
Operator precedence levels
const ( // Git worktree operations TelemetryOpGitWorktreeCreate = "git_worktree_create" TelemetryOpGitWorktreeRemove = "git_worktree_remove" TelemetryOpGitWorktreesCreate = "git_worktrees_create" TelemetryOpGitWorktreesCleanup = "git_worktrees_cleanup" TelemetryOpGitDiff = "git_diff" TelemetryOpGitWorktreeDiscovery = "git_worktree_discovery" TelemetryOpGitWorktreeStackWalk = "git_worktree_stack_walk" TelemetryOpGitWorktreeFilterApply = "git_worktree_filter_apply" // Filter evaluation operations TelemetryOpFilterEvaluate = "filter_evaluate" TelemetryOpFilterParse = "filter_parse" TelemetryOpGitFilterExpand = "git_filter_expand" TelemetryOpGitFilterEvaluate = "git_filter_evaluate" TelemetryOpGraphFilterTraverse = "graph_filter_traverse" )
Telemetry operation names for git worktree and filter operations.
const ( AttrGitRef = "git.ref" AttrGitFromRef = "git.from_ref" AttrGitToRef = "git.to_ref" AttrGitWorktreeDir = "git.worktree_dir" AttrGitWorkingDir = "git.working_dir" AttrGitRefCount = "git.ref_count" AttrGitDiffAdded = "git.diff.added_count" AttrGitDiffRemoved = "git.diff.removed_count" AttrGitDiffChanged = "git.diff.changed_count" // Repository identification attributes AttrGitRepoRemote = "git.repo.remote" AttrGitRepoBranch = "git.repo.branch" AttrGitRepoCommit = "git.repo.commit" AttrFilterQuery = "filter.query" AttrFilterType = "filter.type" AttrFilterCount = "filter.count" AttrComponentCount = "component.count" AttrResultCount = "result.count" AttrWorktreePairCount = "worktree.pair_count" )
Telemetry attribute keys for git worktree operations.
Variables ¶
This section is empty.
Functions ¶
func Apply ¶
func Apply(l log.Logger, filterString string, components component.Components) (component.Components, error)
Apply is a convenience function that parses and evaluates a filter in one step. It's equivalent to calling Parse followed by Evaluate.
func Evaluate ¶
func Evaluate(l log.Logger, expr Expression, components component.Components) (component.Components, error)
Evaluate evaluates an expression against a list of components and returns the filtered components. If logger is provided, it will be used for logging warnings during evaluation.
func FormatDiagnostic ¶ added in v1.0.0
func FormatDiagnostic(err *ParseError, filterIndex int, useColor bool) string
FormatDiagnostic produces an error message from a ParseError.
These diagnostics are formatted like so:
``` Filter parsing error: Missing Git reference
--> --filter '[main...]'
[main...]
^ Expected second Git reference after '...'
hint: Git filters with '...' require a reference on each side. e.g. '[main...HEAD]'
```
func IsNegated ¶ added in v0.99.4
func IsNegated(expr Expression) bool
IsNegated returns true if the expression starts with a negation operator.
func MatchComponent ¶ added in v0.99.4
func MatchComponent(c component.Component, expr Expression) bool
MatchComponent checks if a single component matches an expression. This is the shared core used by both Classifier and Evaluate.
func NewEvaluationError ¶
NewEvaluationError creates a new EvaluationError with the given message.
func NewEvaluationErrorWithCause ¶
NewEvaluationErrorWithCause creates a new EvaluationError with the given message and cause.
func NewParseError ¶
NewParseError creates a new ParseError with the given message and position.
func NewParseErrorWithContext ¶ added in v0.99.4
func NewParseErrorWithContext(title, message string, position, errorPosition int, query, tokenLiteral string, tokenLength int, code ErrorCode) error
NewParseErrorWithContext creates a new ParseError with full context for rich diagnostics.
func TraceFilterEvaluate ¶ added in v0.96.1
func TraceFilterEvaluate(ctx context.Context, filterCount, componentCount int, fn func(ctx context.Context) error) error
TraceFilterEvaluate wraps filter evaluation with telemetry.
func TraceFilterParse ¶ added in v0.96.1
TraceFilterParse wraps filter parsing with telemetry.
func TraceGitDiff ¶ added in v0.96.1
func TraceGitDiff(ctx context.Context, fromRef, toRef, repoRemote string, fn func(ctx context.Context) error) error
TraceGitDiff wraps a git diff operation with telemetry.
func TraceGitFilterEvaluate ¶ added in v0.96.1
func TraceGitFilterEvaluate(ctx context.Context, fromRef, toRef string, componentCount int, fn func(ctx context.Context) error) error
TraceGitFilterEvaluate wraps git filter evaluation with telemetry.
func TraceGitFilterExpand ¶ added in v0.96.1
func TraceGitFilterExpand(ctx context.Context, fromRef, toRef string, addedCount, removedCount, changedCount int, fn func(ctx context.Context) error) error
TraceGitFilterExpand wraps git filter expansion with telemetry.
func TraceGitWorktreeCreate ¶ added in v0.96.1
func TraceGitWorktreeCreate(ctx context.Context, ref, worktreeDir, repoRemote, repoBranch, repoCommit string, fn func(ctx context.Context) error) error
TraceGitWorktreeCreate wraps a git worktree create operation with telemetry. The underlying Telemeter.Collect handles nil/unconfigured telemetry gracefully.
func TraceGitWorktreeDiscovery ¶ added in v0.96.1
func TraceGitWorktreeDiscovery(ctx context.Context, pairCount int, fn func(ctx context.Context) error) error
TraceGitWorktreeDiscovery wraps git worktree discovery operations with telemetry.
func TraceGitWorktreeFilterApply ¶ added in v0.96.1
func TraceGitWorktreeFilterApply(ctx context.Context, filterCount, resultCount int, fn func(ctx context.Context) error) error
TraceGitWorktreeFilterApply wraps filter application to git worktrees with telemetry.
func TraceGitWorktreeRemove ¶ added in v0.96.1
func TraceGitWorktreeRemove(ctx context.Context, ref, worktreeDir string, fn func(ctx context.Context) error) error
TraceGitWorktreeRemove wraps a git worktree remove operation with telemetry.
func TraceGitWorktreeStackWalk ¶ added in v0.96.1
func TraceGitWorktreeStackWalk(ctx context.Context, fromRef, toRef string, fn func(ctx context.Context) error) error
TraceGitWorktreeStackWalk wraps git worktree stack walking operations with telemetry.
func TraceGitWorktreesCleanup ¶ added in v0.96.1
func TraceGitWorktreesCleanup(ctx context.Context, pairCount int, repoRemote string, fn func(ctx context.Context) error) error
TraceGitWorktreesCleanup wraps git worktrees cleanup with telemetry.
func TraceGitWorktreesCreate ¶ added in v0.96.1
func TraceGitWorktreesCreate(ctx context.Context, workingDir string, refCount int, repoRemote, repoBranch, repoCommit string, fn func(ctx context.Context) error) error
TraceGitWorktreesCreate wraps multiple git worktree create operations with telemetry.
func TraceGraphFilterTraverse ¶ added in v0.96.1
func TraceGraphFilterTraverse(ctx context.Context, filterType string, componentCount int, fn func(ctx context.Context) error) error
TraceGraphFilterTraverse wraps graph filter traversal with telemetry.
func WalkExpressions ¶ added in v0.99.4
func WalkExpressions(expr Expression, fn func(Expression) bool)
WalkExpressions traverses the expression tree depth-first, calling fn for each node. The traversal continues to child nodes only if fn returns true. For GraphExpression nodes, traversal continues into the Target expression. For PrefixExpression nodes, traversal continues into the Right expression. For InfixExpression nodes, traversal continues into both Left and Right expressions.
Types ¶
type AttributeExpression ¶ added in v0.95.0
type AttributeExpression struct {
Key string
Value string
// contains filtered or unexported fields
}
AttributeExpression represents a key-value attribute filter (e.g., "name=my-app").
func NewAttributeExpression ¶ added in v0.95.0
func NewAttributeExpression(key string, value string) (*AttributeExpression, error)
NewAttributeExpression creates a new AttributeExpression with eager glob compilation for attributes that support glob matching (name, reading, source).
func NewTypeExpression ¶ added in v1.0.0
func NewTypeExpression(kind component.Kind) *AttributeExpression
NewTypeExpression creates a new AttributeExpression for the "type" attribute. Type filters do not support glob matching, so this constructor cannot fail.
func (*AttributeExpression) Glob ¶ added in v1.0.0
func (a *AttributeExpression) Glob() glob.Glob
Glob returns the pre-compiled glob pattern.
func (*AttributeExpression) IsRestrictedToStacks ¶ added in v0.95.0
func (a *AttributeExpression) IsRestrictedToStacks() bool
func (*AttributeExpression) Negated ¶ added in v0.98.0
func (a *AttributeExpression) Negated() Expression
func (*AttributeExpression) RequiresDiscovery ¶ added in v0.95.0
func (a *AttributeExpression) RequiresDiscovery() (Expression, bool)
func (*AttributeExpression) RequiresParse ¶ added in v0.95.0
func (a *AttributeExpression) RequiresParse() (Expression, bool)
func (*AttributeExpression) String ¶ added in v0.95.0
func (a *AttributeExpression) String() string
type CandidacyReason ¶ added in v0.99.4
type CandidacyReason int
CandidacyReason explains why a component is classified as a candidate.
const ( // CandidacyReasonNone indicates no candidacy reason (component is discovered or excluded). CandidacyReasonNone CandidacyReason = iota // CandidacyReasonGraphTarget indicates the component matches a graph expression target // and needs the graph phase to determine if it should be included. CandidacyReasonGraphTarget // CandidacyReasonRequiresParse indicates the component needs parsing to evaluate // attribute filters (e.g., reading=config/*). CandidacyReasonRequiresParse // CandidacyReasonPotentialDependent indicates the component is a potential dependent // when dependent filters (e.g., ...vpc) exist. These components need to be parsed // to build the dependency graph and determine if they are dependents of the target. CandidacyReasonPotentialDependent )
func (CandidacyReason) String ¶ added in v0.99.4
func (cr CandidacyReason) String() string
String returns a string representation of the CandidacyReason.
type ClassificationContext ¶ added in v0.99.4
type ClassificationContext struct {
// ParseDataAvailable indicates whether parsed data is available for classification.
ParseDataAvailable bool
}
ClassificationContext provides context for component classification.
type ClassificationStatus ¶ added in v0.99.4
type ClassificationStatus int
ClassificationStatus indicates whether a component is ready for filter evaluation, needs further processing, or is excluded from even being considered during filter evaluation.
const ( // StatusReadyForFilter indicates the component has passed classification and is // ready for the final filter evaluation step, which may still exclude it. StatusReadyForFilter ClassificationStatus = iota // StatusCandidate indicates the component might be included (needs further evaluation). StatusCandidate // StatusExcluded indicates the component is definitely excluded from results. StatusExcluded )
func (ClassificationStatus) String ¶ added in v0.99.4
func (cs ClassificationStatus) String() string
String returns a string representation of the ClassificationStatus.
type Classifier ¶ added in v0.99.4
type Classifier struct {
// contains filtered or unexported fields
}
Classifier analyzes filter expressions to efficiently classify components as discovered, candidate, or excluded without full evaluation.
func NewClassifier ¶ added in v0.99.4
func NewClassifier(filters Filters) *Classifier
NewClassifier creates a new Classifier that categorizes all filter expressions for efficient component classification. It separates filters into filesystem-evaluable, parse-required, and graph expressions.
func (*Classifier) Classify ¶ added in v0.99.4
func (c *Classifier) Classify(comp component.Component, classCtx ClassificationContext) (ClassificationStatus, CandidacyReason, int)
Classify determines whether a component should be discovered, is a candidate, or should be excluded based on the analyzed filters.
Returns the classification status, the reason for candidacy (if applicable), and the index of the matching graph expression (-1 if not a graph target match).
Classification algorithm:
- Check if component ONLY matches negated filters -> EXCLUDED
- Check if parse expressions exist and parse data unavailable -> CANDIDATE (RequiresParse)
- Check if component matches any positive filesystem filter -> DISCOVERED
- Check if component matches any git expression -> DISCOVERED
- Check if component matches any graph expression target -> CANDIDATE (GraphTarget, returns index)
- Check if dependent filters exist and parse data unavailable -> CANDIDATE (PotentialDependent)
- If negated expressions exist and component doesn't match any -> DISCOVERED (negation acts as inclusion)
- If positive filters exist but no match -> EXCLUDED (exclude-by-default)
- If no positive filters exist -> DISCOVERED (include-by-default)
func (*Classifier) GraphExpressions ¶ added in v0.99.4
func (c *Classifier) GraphExpressions() []*GraphExpressionInfo
GraphExpressions returns the analyzed graph expressions.
func (*Classifier) HasDependentFilters ¶ added in v0.99.4
func (c *Classifier) HasDependentFilters() bool
HasDependentFilters returns whether any graph expressions include dependent traversal. This is used to determine if pre-graph dependency building is needed to populate reverse links before dependent discovery can work.
func (*Classifier) HasGraphFilters ¶ added in v0.99.4
func (c *Classifier) HasGraphFilters() bool
HasGraphFilters returns whether any graph traversal filters exist.
func (*Classifier) HasParseRequiredFilters ¶ added in v0.99.4
func (c *Classifier) HasParseRequiredFilters() bool
HasParseRequiredFilters returns whether any filters require HCL parsing.
func (*Classifier) HasPositiveFilters ¶ added in v0.99.4
func (c *Classifier) HasPositiveFilters() bool
HasPositiveFilters returns whether any positive (non-negated) filters exist.
func (*Classifier) NegatedExpressions ¶ added in v0.99.4
func (c *Classifier) NegatedExpressions() []Expression
NegatedExpressions returns the negated expressions.
func (*Classifier) ParseExpressions ¶ added in v0.99.4
func (c *Classifier) ParseExpressions() []Expression
ParseExpressions returns the expressions that require parsing.
type ErrorCode ¶ added in v0.99.4
type ErrorCode int
ErrorCode categorizes parse errors for hint lookup.
type EvaluationContext ¶ added in v0.95.0
type EvaluationContext struct {
// GitWorktrees maps Git references to temporary worktree directory paths.
// This is used by GitFilter expressions to access different Git references.
GitWorktrees map[string]string
// WorkingDir is the base working directory for resolving relative paths.
WorkingDir string
}
EvaluationContext provides additional context for filter evaluation, such as Git worktree directories.
type EvaluationError ¶
EvaluationError represents an error that occurred during evaluation.
func (EvaluationError) Error ¶
func (e EvaluationError) Error() string
type Expression ¶
type Expression interface {
// String returns a string representation of the expression for debugging.
String() string
// RequiresDiscovery returns the first expression that requires discovery of Terragrunt components if any do.
// Additionally, it returns a secondary value of true if any do.
RequiresDiscovery() (Expression, bool)
// RequiresParse returns the first expression that requires parsing Terragrunt HCL configurations if any do.
// Additionally, it returns a secondary value of true if any do.
RequiresParse() (Expression, bool)
// IsRestrictedToStacks returns true if the expression is restricted to stacks.
IsRestrictedToStacks() bool
// Negated returns the equivalent expression with negation flipped.
Negated() Expression
// contains filtered or unexported methods
}
Expression is the interface that all AST nodes must implement.
type Expressions ¶ added in v0.95.0
type Expressions []Expression
Expressions is a slice of expressions.
type Filter ¶
type Filter struct {
// contains filtered or unexported fields
}
Filter represents a parsed filter query that can be evaluated against discovered configs.
func NewFilter ¶ added in v0.95.0
func NewFilter(expr Expression, originalQuery string) *Filter
NewFilter creates a new Filter object.
func Parse ¶
Parse parses a filter query string and returns a Filter object. Returns an error if the query cannot be parsed.
func (*Filter) Evaluate ¶
func (f *Filter) Evaluate(l log.Logger, components component.Components) (component.Components, error)
Evaluate applies the filter to a list of components and returns the filtered result. If logger is provided, it will be used for logging warnings during evaluation.
func (*Filter) Expression ¶
func (f *Filter) Expression() Expression
Expression returns the parsed AST expression. This is useful for debugging or advanced use cases.
func (*Filter) Negated ¶ added in v0.98.0
Negated returns the equivalent filter with negation flipped.
If the filter is already negated, it will return the non-negated filter.
func (*Filter) RequiresParse ¶ added in v0.95.0
func (f *Filter) RequiresParse() (Expression, bool)
RequiresParse returns true if the filter requires parsing of Terragrunt HCL configurations.
type FilterQueryRequiresDiscoveryError ¶ added in v0.93.4
type FilterQueryRequiresDiscoveryError struct {
Query string
}
FilterQueryRequiresDiscoveryError is an error that is returned when a filter query requires discovery of Terragrunt configurations.
func (FilterQueryRequiresDiscoveryError) Error ¶ added in v0.93.4
func (e FilterQueryRequiresDiscoveryError) Error() string
type Filters ¶
type Filters []*Filter
Filters represents multiple filter queries that are evaluated with union (OR) semantics. Multiple filters in Filters are always unioned (as opposed to multiple filters within one filter string separated by |, which are intersected).
func ParseFilterQueries ¶
ParseFilterQueries parses multiple filter strings and returns a Filters object. Collects all parse errors and returns them as a joined error if any occur. Returns an empty Filters if filterStrings is empty. Color output for diagnostics is determined by the logger's color settings and terminal detection.
func (Filters) DependencyGraphExpressions ¶ added in v0.95.0
func (f Filters) DependencyGraphExpressions() []Expression
DependencyGraphExpressions returns all target expressions from graph expressions that require dependency traversal.
func (Filters) DependentGraphExpressions ¶ added in v0.95.0
func (f Filters) DependentGraphExpressions() []Expression
DependentGraphExpressions returns all target expressions from graph expressions that require dependent traversal.
func (Filters) Evaluate ¶
func (f Filters) Evaluate(l log.Logger, components component.Components) (component.Components, error)
Evaluate applies all filters with union (OR) semantics in two phases:
- Positive filters (non-negated) are evaluated and their results are unioned
- Negative filters (starting with negation) are evaluated against the combined results and remove matching components
If logger is provided, it will be used for logging warnings during evaluation.
func (Filters) EvaluateOnFiles ¶ added in v0.92.0
func (f Filters) EvaluateOnFiles(l log.Logger, files []string, workingDir string) (component.Components, error)
EvaluateOnFiles evaluates the filters on a list of files and returns the filtered result. This is useful for the hcl format command, where we want to evaluate filters on files rather than directories, like we do with components.
func (Filters) ExcludingGitFilters ¶ added in v1.0.1
ExcludingGitFilters returns all filters that do not contain a git expression. Git expressions are excluded because they are handled by the worktree phase itself and would cause infinite recursion if propagated to sub-discoveries.
func (Filters) HasPositiveFilter ¶ added in v0.91.2
HasPositiveFilter returns true if the filters have any positive filters.
func (Filters) RequiresDiscovery ¶ added in v0.93.4
func (f Filters) RequiresDiscovery() (Expression, bool)
RequiresDiscovery returns the first expression that requires discovery of Terragrunt components if any do.
func (Filters) RequiresParse ¶ added in v0.93.4
func (f Filters) RequiresParse() (Expression, bool)
RequiresParse returns the first expression that requires parsing of Terragrunt HCL configurations if any do.
func (Filters) RestrictToStacks ¶ added in v0.93.5
RestrictToStacks returns a new Filters object with only the filters that are restricted to stacks.
func (Filters) UniqueGitFilters ¶ added in v0.95.0
func (f Filters) UniqueGitFilters() GitExpressions
UniqueGitFilters returns all unique Git filters that require worktree discovery.
type GitExpression ¶ added in v0.95.0
GitExpression represents a Git-based filter expression (e.g., "[main...HEAD]" or "[main]"). It filters components based on changes between Git references.
func NewGitExpression ¶ added in v0.95.0
func NewGitExpression(fromRef, toRef string) *GitExpression
func (*GitExpression) IsRestrictedToStacks ¶ added in v0.95.0
func (g *GitExpression) IsRestrictedToStacks() bool
func (*GitExpression) Negated ¶ added in v0.98.0
func (g *GitExpression) Negated() Expression
func (*GitExpression) RequiresDiscovery ¶ added in v0.95.0
func (g *GitExpression) RequiresDiscovery() (Expression, bool)
func (*GitExpression) RequiresParse ¶ added in v0.95.0
func (g *GitExpression) RequiresParse() (Expression, bool)
func (*GitExpression) String ¶ added in v0.95.0
func (g *GitExpression) String() string
type GitExpressions ¶ added in v0.95.0
type GitExpressions []*GitExpression
GitExpressions is a slice of Git expressions.
func (GitExpressions) UniqueGitRefs ¶ added in v0.95.0
func (e GitExpressions) UniqueGitRefs() []string
UniqueGitRefs returns all unique Git references in a slice of expressions.
type GraphDirection ¶ added in v0.99.4
type GraphDirection int
GraphDirection represents the direction of graph traversal.
const ( // GraphDirectionNone indicates no graph traversal. GraphDirectionNone GraphDirection = iota // GraphDirectionDependencies indicates traversing dependencies (downstream). GraphDirectionDependencies // GraphDirectionDependents indicates traversing dependents (upstream). GraphDirectionDependents // GraphDirectionBoth indicates traversing both directions. GraphDirectionBoth )
func (GraphDirection) String ¶ added in v0.99.4
func (d GraphDirection) String() string
String returns a string representation of the GraphDirection.
type GraphExpression ¶ added in v0.93.4
type GraphExpression struct {
Target Expression
IncludeDependents bool
IncludeDependencies bool
ExcludeTarget bool
DependentDepth int
DependencyDepth int
}
GraphExpression represents a graph traversal expression (e.g., "...foo", "foo...", "..1foo", "foo..2"). Depth fields control how many levels of dependencies/dependents to traverse.
func NewGraphExpression ¶ added in v0.93.5
func NewGraphExpression(target Expression) *GraphExpression
NewGraphExpression creates a new GraphExpression for the given target. Use the builder methods WithDependents, WithDependencies, and WithExcludeTarget to configure graph traversal behavior.
func (*GraphExpression) IsRestrictedToStacks ¶ added in v0.93.5
func (g *GraphExpression) IsRestrictedToStacks() bool
func (*GraphExpression) Negated ¶ added in v0.98.0
func (g *GraphExpression) Negated() Expression
func (*GraphExpression) RequiresDiscovery ¶ added in v0.93.4
func (g *GraphExpression) RequiresDiscovery() (Expression, bool)
func (*GraphExpression) RequiresParse ¶ added in v0.93.4
func (g *GraphExpression) RequiresParse() (Expression, bool)
func (*GraphExpression) String ¶ added in v0.93.4
func (g *GraphExpression) String() string
func (*GraphExpression) WithDependencies ¶ added in v1.0.0
func (g *GraphExpression) WithDependencies() *GraphExpression
WithDependencies includes dependencies in the graph traversal.
func (*GraphExpression) WithDependents ¶ added in v1.0.0
func (g *GraphExpression) WithDependents() *GraphExpression
WithDependents includes dependents (reverse dependencies) in the graph traversal.
func (*GraphExpression) WithExcludeTarget ¶ added in v1.0.0
func (g *GraphExpression) WithExcludeTarget() *GraphExpression
WithExcludeTarget excludes the target itself from the graph traversal results.
type GraphExpressionInfo ¶ added in v0.99.4
type GraphExpressionInfo struct {
// Target is the target expression within the graph expression.
Target Expression
// FullExpression is the complete graph expression.
FullExpression *GraphExpression
// Index is the position of this expression in the original filter list.
Index int
// IncludeDependencies indicates if dependencies should be traversed.
IncludeDependencies bool
// IncludeDependents indicates if dependents should be traversed.
IncludeDependents bool
// ExcludeTarget indicates if the target itself should be excluded from results (^ prefix).
ExcludeTarget bool
// IsNegated indicates if this graph expression is within a negation (e.g., !...db).
IsNegated bool
// DependencyDepth is the maximum depth for dependency traversal.
DependencyDepth int
// DependentDepth is the maximum depth for dependent traversal.
DependentDepth int
}
GraphExpressionInfo contains information about a graph expression for the classifier.
type InfixExpression ¶
type InfixExpression struct {
Left Expression
Right Expression
Operator string
}
InfixExpression represents an infix operator expression (e.g., "./apps/* | name=bar").
func NewInfixExpression ¶ added in v0.93.5
func NewInfixExpression(left Expression, operator string, right Expression) *InfixExpression
NewInfixExpression creates a new InfixExpression.
func (*InfixExpression) IsRestrictedToStacks ¶ added in v0.93.5
func (i *InfixExpression) IsRestrictedToStacks() bool
func (*InfixExpression) Negated ¶ added in v0.98.0
func (i *InfixExpression) Negated() Expression
func (*InfixExpression) RequiresDiscovery ¶ added in v0.93.4
func (i *InfixExpression) RequiresDiscovery() (Expression, bool)
func (*InfixExpression) RequiresParse ¶ added in v0.93.4
func (i *InfixExpression) RequiresParse() (Expression, bool)
func (*InfixExpression) String ¶
func (i *InfixExpression) String() string
type Lexer ¶
type Lexer struct {
// contains filtered or unexported fields
}
Lexer tokenizes a filter query string.
type ParseError ¶
type ParseError struct {
// Title is a high-level error description (e.g., "Unclosed Git filter expression")
Title string
// Message is a detailed explanation shown at the problematic location (e.g., "this Git-based expression is missing a closing ']'")
Message string
// Query is the original filter query
Query string
// TokenLiteral is the problematic token
TokenLiteral string
// TokenLength is the length of the problematic token (used for underline width)
TokenLength int
// Position is the position of the problematic token
Position int
// ErrorPosition is the position to show the caret (e.g. for unclosed brackets, it points to the opening bracket)
ErrorPosition int
// ErrorCode is the error code, used for hint lookup
ErrorCode ErrorCode
}
ParseError represents an error that occurred during parsing.
func (ParseError) Error ¶
func (e ParseError) Error() string
Error returns a string representation of the error.
We suppress the gocritic "hugeParam" warning because this is a very large struct, but we need it to implement the error interface, not its pointer.
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser parses a filter query string into an AST.
func (*Parser) ParseExpression ¶
func (p *Parser) ParseExpression() (Expression, error)
ParseExpression parses and returns an expression from the input.
type PathExpression ¶ added in v0.95.0
type PathExpression struct {
Value string
// contains filtered or unexported fields
}
PathExpression represents a path or glob filter (e.g., "./path/**/*" or "/absolute/path").
func NewPathFilter ¶
func NewPathFilter(value string) (*PathExpression, error)
NewPathFilter creates a new PathFilter with eager glob compilation.
func (*PathExpression) Glob ¶ added in v1.0.0
func (p *PathExpression) Glob() glob.Glob
Glob returns the pre-compiled glob pattern.
func (*PathExpression) IsRestrictedToStacks ¶ added in v0.95.0
func (p *PathExpression) IsRestrictedToStacks() bool
func (*PathExpression) Negated ¶ added in v0.98.0
func (p *PathExpression) Negated() Expression
func (*PathExpression) RequiresDiscovery ¶ added in v0.95.0
func (p *PathExpression) RequiresDiscovery() (Expression, bool)
func (*PathExpression) RequiresParse ¶ added in v0.95.0
func (p *PathExpression) RequiresParse() (Expression, bool)
func (*PathExpression) String ¶ added in v0.95.0
func (p *PathExpression) String() string
type PrefixExpression ¶
type PrefixExpression struct {
Right Expression
Operator string
}
PrefixExpression represents a prefix operator expression (e.g., "!name=foo").
func NewPrefixExpression ¶ added in v0.93.5
func NewPrefixExpression(operator string, right Expression) *PrefixExpression
NewPrefixExpression creates a new PrefixExpression.
func (*PrefixExpression) IsRestrictedToStacks ¶ added in v0.93.5
func (p *PrefixExpression) IsRestrictedToStacks() bool
func (*PrefixExpression) Negated ¶ added in v0.98.0
func (p *PrefixExpression) Negated() Expression
func (*PrefixExpression) RequiresDiscovery ¶ added in v0.93.4
func (p *PrefixExpression) RequiresDiscovery() (Expression, bool)
func (*PrefixExpression) RequiresParse ¶ added in v0.93.4
func (p *PrefixExpression) RequiresParse() (Expression, bool)
func (*PrefixExpression) String ¶
func (p *PrefixExpression) String() string
type TokenType ¶
type TokenType int
TokenType represents the type of a token.
const ( // ILLEGAL represents an unknown token ILLEGAL TokenType = iota // EOF represents the end of the input EOF // IDENT represents an identifier (e.g., "foo", "name") IDENT // PATH represents a path (starts with ./, ../, or /) PATH // Operators BANG // negation operator (!) PIPE // intersection operator (|) EQUAL // attribute assignment (=) // Delimiters LBRACE // left brace ({) RBRACE // right brace (}) LBRACKET // left bracket ([) RBRACKET // right bracket (]) // Graph operators ELLIPSIS // ellipsis operator (...) CARET // caret operator (^) )