From 3b36a48b7ce5a53a9366f3b31f94311f178e2553 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Sat, 12 Sep 2026 01:22:12 +0200 Subject: krino: matching — scan, ignore, conditions, extraction, duplicates, explain, dry run MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/krino/explain.go | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 cmd/krino/explain.go (limited to 'cmd/krino/explain.go') 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) + } +} -- cgit v1.3