diff options
| author | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-12 01:22:12 +0200 |
|---|---|---|
| committer | Lukasz Kasprzak <lukas@labunix.xyz> | 2026-09-12 01:22:12 +0200 |
| commit | 3b36a48b7ce5a53a9366f3b31f94311f178e2553 (patch) | |
| tree | ecbb277ff916b719f2ee45fba017792b85d5faf9 /cmd/krino/explain.go | |
| parent | 42b02c47be9b285099203e44a2570636d4ca6f03 (diff) | |
| download | krino-3b36a48b7ce5a53a9366f3b31f94311f178e2553.tar.gz krino-3b36a48b7ce5a53a9366f3b31f94311f178e2553.zip | |
krino: matching — scan, ignore, conditions, extraction, duplicates, explain, dry run
Diffstat (limited to 'cmd/krino/explain.go')
| -rw-r--r-- | cmd/krino/explain.go | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/cmd/krino/explain.go b/cmd/krino/explain.go new file mode 100644 index 0000000..a4d0253 --- /dev/null +++ b/cmd/krino/explain.go @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package main + +import ( + "bytes" + "context" + "fmt" + "io" + "strings" + + "krino/internal/cond" + "krino/internal/engine" + "krino/internal/xdg" +) + +func init() { commands["explain"] = cmdExplain } + +// cmdExplain evaluates every rule of FILE's directory against it and shows +// each test's result. +func cmdExplain(g *globals, args []string, stdout, stderr io.Writer) int { + fs := flagSet("explain", g) + if code, ok := parse(fs, args, stdout, stderr); !ok { + return code + } + if fs.NArg() != 1 { + return usageError(stderr, "usage: krino explain FILE") + } + + e, errs := engine.Load(mainFile(g)) + if len(errs) > 0 { + printDiags(stderr, errs) + return 2 + } + + x, err := e.Explain(context.Background(), xdg.Expand(fs.Arg(0))) + if err != nil { + fmt.Fprintf(stderr, "krino: %v\n", err) + return 2 + } + + fmt.Fprintf(stdout, "%s (directory %s)\n", xdg.Abbrev(x.File.Path), x.Dir.Name) + if x.Skip != "" { + fmt.Fprintf(stdout, "krino would not look at this file: %s\n", x.Skip) + } + fmt.Fprintln(stdout) + for _, rt := range x.Rules { + if rt.Stopped != "" { + fmt.Fprintf(stdout, "rule %s: not evaluated, %s\n", rt.Rule.Name, rt.Stopped) + continue + } + status := "no" + if rt.Match { + status = "MATCH" + } + fmt.Fprintf(stdout, "rule %s: %s\n", rt.Rule.Name, status) + printTrace(stdout, rt.Trace) + } + return 0 +} + +// printTrace writes t's Format output with every line prefixed by two +// spaces. +func printTrace(w io.Writer, t *cond.Trace) { + var buf bytes.Buffer + t.Format(&buf) + for _, line := range strings.Split(strings.TrimRight(buf.String(), "\n"), "\n") { + fmt.Fprintf(w, " %s\n", line) + } +} |
