aboutsummaryrefslogtreecommitdiff
path: root/internal/engine/match.go
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-09-16 01:34:45 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-09-16 01:34:45 +0200
commitecfaeabf2a92e26c6a521d5fac404a0fff6263b6 (patch)
tree4147dd6809a45fe5b773447352354dbee2295900 /internal/engine/match.go
parentbe4b1275c76b9cad984dfafaa8023db94eb3eecf (diff)
downloadkrino-ecfaeabf2a92e26c6a521d5fac404a0fff6263b6.tar.gz
krino-ecfaeabf2a92e26c6a521d5fac404a0fff6263b6.zip
milestone 1 review: claims span the run, explain's chain is opt-in and its own, overrides keyed by clean path, splice and enum guards
Diffstat (limited to 'internal/engine/match.go')
-rw-r--r--internal/engine/match.go23
1 files changed, 19 insertions, 4 deletions
diff --git a/internal/engine/match.go b/internal/engine/match.go
index 591f686..59cea42 100644
--- a/internal/engine/match.go
+++ b/internal/engine/match.go
@@ -251,9 +251,12 @@ type Explanation struct {
Excluded string // the first exclude that matches, which sets the file aside; "" when none does
Rules []RuleTrace
NoDelete string // why a delete from the matching rules would be skipped (spec §5.5); "" when it would not
- // Chain is what the matching rules would do to the file: the same steps
- // the directory's plan builds for it, placeholders expanded and
- // conflicts resolved (GUI design §1.3).
+ // Chain is what the matching rules would do to this file alone:
+ // placeholders expanded and conflicts resolved against the disk, but
+ // not against the other files of a plan, which can still take a name
+ // this chain shows (the plan itself is where those are resolved). It is
+ // nil unless ExplainWithChain asked for it, and nil for a file the scan
+ // would skip or an exclude sets aside, which no rule acts on.
Chain []plan.Step
}
@@ -263,6 +266,18 @@ type Explanation struct {
// match if the file were looked at; a rule reached after an earlier
// matching (stop) is recorded as Stopped, with no trace.
func (e *Engine) Explain(ctx context.Context, path string) (*Explanation, error) {
+ return e.explain(ctx, path, false)
+}
+
+// ExplainWithChain is Explain with Explanation.Chain filled in: the steps
+// this file alone would get. Building them resolves conflicts against the
+// disk, which can read files (a copy whose target holds the same bytes), so
+// the command line's explain does not ask for it (plan 13 review F1).
+func (e *Engine) ExplainWithChain(ctx context.Context, path string) (*Explanation, error) {
+ return e.explain(ctx, path, true)
+}
+
+func (e *Engine) explain(ctx context.Context, path string, withChain bool) (*Explanation, error) {
abs, err := filepath.Abs(path)
if err != nil {
return nil, err
@@ -358,7 +373,7 @@ func (e *Engine) Explain(ctx context.Context, path string) (*Explanation, error)
}
var chain []plan.Step
- if len(matched) > 0 {
+ if withChain && skip == "" && excluded == "" && len(matched) > 0 {
in := []plan.Input{{File: sf, Rules: planRules(matched), NoDelete: noDel}}
if built := plan.Build(d.Root, in, now, plan.OS{}, plan.NewClaims()); len(built) == 1 {
chain = built[0].Steps