[object Object]

← back to Cli Printing Press

fix(cli): accept backtick raw-string Use: in dogfood walkers (#1169)

7ba9c20a352c473cdffa8db492543a719f1518d2 · 2026-05-12 01:15:22 -0700 · Trevin Chow

* fix(cli): accept backtick raw-string Use: in dogfood walkers

The dogfood novel-features walker, reimplementation check, scorecard
helper, naming check, and command-tree walker all extracted the Cobra
Use: leaf with a regex that only matched the double-quoted form.
Commands declared with Go's backtick raw-string Use: (idiomatic when
the value contains a literal double-quote, e.g. `query "<sql>"`) were
silently reported as missing even when wired and working.

Extend the shared `cobraUseLeafRe` to accept either delimiter and
consolidate the parallel inline regexes onto it so future drift can't
reintroduce the silent miss. Pin the new behavior with tests for each
affected walker.

* docs(cli): note why checkNamingConsistency keeps a separate Use: regex

Greptile flagged the residual divergence from cobraUseLeafRe at
dogfood.go:1072 as a future-drift risk. The capture class is
deliberately tighter ([A-Za-z][A-Za-z0-9_-]* identifiers only) because
the naming check judges verb-shaped tokens, and a broader class would
let flag tokens or angle-bracket args masquerade as verbs. Spell that
out inline so the next reader doesn't try to consolidate it.

Files touched

Diff

commit 7ba9c20a352c473cdffa8db492543a719f1518d2
Author: Trevin Chow <trevin@trevinchow.com>
Date:   Tue May 12 01:15:22 2026 -0700

    fix(cli): accept backtick raw-string Use: in dogfood walkers (#1169)
    
    * fix(cli): accept backtick raw-string Use: in dogfood walkers
    
    The dogfood novel-features walker, reimplementation check, scorecard
    helper, naming check, and command-tree walker all extracted the Cobra
    Use: leaf with a regex that only matched the double-quoted form.
    Commands declared with Go's backtick raw-string Use: (idiomatic when
    the value contains a literal double-quote, e.g. `query "<sql>"`) were
    silently reported as missing even when wired and working.
    
    Extend the shared `cobraUseLeafRe` to accept either delimiter and
    consolidate the parallel inline regexes onto it so future drift can't
    reintroduce the silent miss. Pin the new behavior with tests for each
    affected walker.
    
    * docs(cli): note why checkNamingConsistency keeps a separate Use: regex
    
    Greptile flagged the residual divergence from cobraUseLeafRe at
    dogfood.go:1072 as a future-drift risk. The capture class is
    deliberately tighter ([A-Za-z][A-Za-z0-9_-]* identifiers only) because
    the naming check judges verb-shaped tokens, and a broader class would
    let flag tokens or angle-bracket args masquerade as verbs. Spell that
    out inline so the next reader doesn't try to consolidate it.
---
 internal/pipeline/dogfood.go                     | 17 ++--
 internal/pipeline/dogfood_test.go                | 99 ++++++++++++++++++++++++
 internal/pipeline/reimplementation_check.go      |  2 +-
 internal/pipeline/reimplementation_check_test.go | 40 ++++++++++
 internal/pipeline/scorecard.go                   |  9 ++-
 5 files changed, 157 insertions(+), 10 deletions(-)

diff --git a/internal/pipeline/dogfood.go b/internal/pipeline/dogfood.go
index 6b3653be..8c8dd3ab 100644
--- a/internal/pipeline/dogfood.go
+++ b/internal/pipeline/dogfood.go
@@ -496,7 +496,7 @@ func collectRegisteredCommands(dir string) (paths, leaves map[string]bool) {
 	// (Execute / helpers) isn't a new*Cmd constructor.
 	rootAddRe := regexp.MustCompile(`rootCmd\.AddCommand\(\s*(new\w+Cmd)\b`)
 	funcHeaderRe := regexp.MustCompile(`func\s+(new\w+Cmd)\s*\(`)
-	useRe := regexp.MustCompile(`Use:\s*"([^"\s]+)`)
+	useRe := cobraUseLeafRe
 	addChildRe := regexp.MustCompile(`\.AddCommand\(\s*(new\w+Cmd)\b`)
 
 	for _, file := range files {
@@ -1066,9 +1066,16 @@ func checkNamingConsistency(dir string) NamingCheckResult {
 	result := NamingCheckResult{Checked: len(files)}
 
 	// Extract the first token of a cobra Use: declaration:
-	//   Use:  "get",       -> "get"
-	//   Use:  "list [id]", -> "list"
-	useRe := regexp.MustCompile(`(?m)Use:\s*"([A-Za-z][A-Za-z0-9_-]*)`)
+	//   Use:  "get",                  -> "get"
+	//   Use:  "list [id]",            -> "list"
+	//   Use:  `query "<sql>"`,        -> "query"
+	//
+	// Deliberately not consolidated onto cobraUseLeafRe: the naming check
+	// only judges identifier-shaped verbs, so the capture class is tightened
+	// to [A-Za-z][A-Za-z0-9_-]* — anything broader would let a flag token
+	// or angle-bracket arg masquerade as a verb. Both regexes accept the
+	// same delimiters; only the capture differs.
+	useRe := regexp.MustCompile("(?m)Use:\\s*[\"`]([A-Za-z][A-Za-z0-9_-]*)")
 
 	// Extract long-form flag names from the common cobra registration
 	// patterns: StringVar, BoolVar, IntVar, Int64Var, StringVarP, BoolVarP,
@@ -1921,7 +1928,7 @@ func checkCommandTree(dir string) CommandTreeResult {
 	// A constructor is func newXxxCmd(...) — we extract both the function name
 	// and the cobra Use: field (the command name users see).
 	constructorRe := regexp.MustCompile(`(?m)^func\s+(new\w+Cmd)\s*\(`)
-	useFieldRe := regexp.MustCompile(`(?m)Use:\s*"([^"\s]+)`)
+	useFieldRe := cobraUseLeafRe
 
 	type cmdDef struct {
 		constructor string // e.g. "newBookingsCmd"
diff --git a/internal/pipeline/dogfood_test.go b/internal/pipeline/dogfood_test.go
index 41e7339a..473b0819 100644
--- a/internal/pipeline/dogfood_test.go
+++ b/internal/pipeline/dogfood_test.go
@@ -388,6 +388,33 @@ func newOrphanCmd() { cmd := &cobra.Command{Use: "orphan"} }
 	assert.Equal(t, []string{"orphan"}, result.Unregistered)
 }
 
+// TestCheckCommandTree_BacktickUse pins that the constructor walker reads
+// the Use: leaf name from a backtick raw-string literal, which authors reach
+// for when the command name contains a literal double-quote. Without
+// backtick support, useName silently falls back to the constructor name
+// and the command surfaces with the wrong identity in CommandTreeResult.
+func TestCheckCommandTree_BacktickUse(t *testing.T) {
+	dir := t.TempDir()
+	cliDir := filepath.Join(dir, "internal", "cli")
+	require.NoError(t, os.MkdirAll(cliDir, 0o755))
+
+	writeTestFile(t, filepath.Join(cliDir, "root.go"), `package cli
+func newRootCmd() {
+	rootCmd.AddCommand(newQueryCmd())
+}
+`)
+	writeTestFile(t, filepath.Join(cliDir, "query.go"),
+		"package cli\n"+
+			"func newQueryCmd() *cobra.Command {\n"+
+			"\treturn &cobra.Command{Use: `query <project> \"<sql>\"`}\n"+
+			"}\n")
+
+	result := checkCommandTree(dir)
+	assert.Equal(t, 1, result.Defined)
+	assert.Equal(t, 1, result.Registered)
+	assert.Empty(t, result.Unregistered)
+}
+
 func TestCheckCommandTree_DeeplyNested(t *testing.T) {
 	dir := t.TempDir()
 	cliDir := filepath.Join(dir, "internal", "cli")
@@ -1012,6 +1039,36 @@ func newHealthCmd() *cobra.Command {
 	})
 }
 
+// TestCheckNovelFeatures_BacktickUse pins that the walker matches commands
+// declared with Go's backtick raw-string Use: form. Authors reach for
+// backticks when the command name contains a literal double-quote (e.g.,
+// `query <project> "<sql>"`), and the walker must not silently report
+// those as missing.
+func TestCheckNovelFeatures_BacktickUse(t *testing.T) {
+	cliDir := t.TempDir()
+	cliCodeDir := filepath.Join(cliDir, "internal", "cli")
+	require.NoError(t, os.MkdirAll(cliCodeDir, 0o755))
+	writeTestFile(t, filepath.Join(cliCodeDir, "query.go"),
+		"package cli\n"+
+			"func newQueryCmd() *cobra.Command {\n"+
+			"\treturn &cobra.Command{Use: `query <project> \"<sql>\"`}\n"+
+			"}\n")
+
+	researchDir := t.TempDir()
+	research := &ResearchResult{
+		APIName: "test",
+		NovelFeatures: []NovelFeature{
+			{Name: "SQL query", Command: "query"},
+		},
+	}
+	require.NoError(t, writeResearchJSON(research, researchDir))
+
+	result := checkNovelFeatures(cliDir, researchDir)
+	assert.Equal(t, 1, result.Planned)
+	assert.Equal(t, 1, result.Found)
+	assert.Empty(t, result.Missing)
+}
+
 func TestCheckNovelFeatures_ZeroSurvivors(t *testing.T) {
 	// All planned features missing — novel_features_built should be a non-nil
 	// empty slice (not omitted), so the fallback to the aspirational list
@@ -1399,6 +1456,48 @@ func newCmd() *cobra.Command {
 	assert.Empty(t, result.Violations, "--yes is allowed; only --skip-confirmations variants are banned")
 }
 
+// TestCheckNamingConsistency_BacktickUse pins that the verb extractor reads
+// the leading identifier from a backtick raw-string Use: declaration. A
+// banned verb hidden in a backtick literal must still surface as a
+// violation; symmetrically, a permitted verb in the same form must not
+// produce a false positive.
+func TestCheckNamingConsistency_BacktickUse(t *testing.T) {
+	t.Run("permitted verb in backtick Use", func(t *testing.T) {
+		dir := t.TempDir()
+		require.NoError(t, os.MkdirAll(filepath.Join(dir, "internal", "cli"), 0o755))
+		writeTestFile(t, filepath.Join(dir, "internal", "cli", "cmd.go"),
+			"package cli\n"+
+				"\n"+
+				"import \"github.com/spf13/cobra\"\n"+
+				"\n"+
+				"func newQueryCmd() *cobra.Command {\n"+
+				"\treturn &cobra.Command{Use: `query <project> \"<sql>\"`}\n"+
+				"}\n")
+
+		result := checkNamingConsistency(dir)
+		assert.Equal(t, 1, result.Checked)
+		assert.Empty(t, result.Violations)
+	})
+
+	t.Run("banned verb in backtick Use", func(t *testing.T) {
+		dir := t.TempDir()
+		require.NoError(t, os.MkdirAll(filepath.Join(dir, "internal", "cli"), 0o755))
+		writeTestFile(t, filepath.Join(dir, "internal", "cli", "cmd.go"),
+			"package cli\n"+
+				"\n"+
+				"import \"github.com/spf13/cobra\"\n"+
+				"\n"+
+				"func newInfoCmd() *cobra.Command {\n"+
+				"\treturn &cobra.Command{Use: `info <project> \"<filter>\"`}\n"+
+				"}\n")
+
+		result := checkNamingConsistency(dir)
+		require.Len(t, result.Violations, 1)
+		assert.Equal(t, "info", result.Violations[0].Banned)
+		assert.Equal(t, "verb", result.Violations[0].Category)
+	})
+}
+
 func TestCheckNamingConsistency_NoFalsePositiveOnIdentifierWithBannedSubstring(t *testing.T) {
 	dir := t.TempDir()
 	require.NoError(t, os.MkdirAll(filepath.Join(dir, "internal", "cli"), 0o755))
diff --git a/internal/pipeline/reimplementation_check.go b/internal/pipeline/reimplementation_check.go
index 2dde2d4b..514851eb 100644
--- a/internal/pipeline/reimplementation_check.go
+++ b/internal/pipeline/reimplementation_check.go
@@ -178,7 +178,7 @@ func checkReimplementation(cliDir, researchDir string) ReimplementationCheckResu
 		"doctor.go":  true,
 		"auth.go":    true,
 	}
-	useLineRe := regexp.MustCompile(`Use:\s*"([^"\s]+)`)
+	useLineRe := cobraUseLeafRe
 	for _, e := range entries {
 		name := e.Name()
 		if e.IsDir() || !strings.HasSuffix(name, ".go") {
diff --git a/internal/pipeline/reimplementation_check_test.go b/internal/pipeline/reimplementation_check_test.go
index 5ec301d1..1f260a0e 100644
--- a/internal/pipeline/reimplementation_check_test.go
+++ b/internal/pipeline/reimplementation_check_test.go
@@ -510,6 +510,46 @@ func newFakeCmd(flags *rootFlags) *cobra.Command {
 	}
 }
 
+// TestCheckReimplementation_BacktickUse pins that the file index recognizes
+// commands declared with Go's backtick raw-string Use: form. Authors reach
+// for backticks when the command name contains a literal double-quote
+// (e.g., `query <project> "<sql>"`); without backtick support the file
+// drops out of leafToFiles and the reimplementation check silently skips
+// the command entirely.
+func TestCheckReimplementation_BacktickUse(t *testing.T) {
+	files := map[string]string{
+		"query.go": "package cli\n" +
+			"\n" +
+			"import \"github.com/spf13/cobra\"\n" +
+			"\n" +
+			"func newQueryCmd(flags *rootFlags) *cobra.Command {\n" +
+			"\treturn &cobra.Command{\n" +
+			"\t\tUse: `query <project> \"<sql>\"`,\n" +
+			"\t\tRunE: func(cmd *cobra.Command, args []string) error {\n" +
+			"\t\t\tc, err := flags.newClient()\n" +
+			"\t\t\tif err != nil { return err }\n" +
+			"\t\t\t_ = c\n" +
+			"\t\t\treturn nil\n" +
+			"\t\t},\n" +
+			"\t}\n" +
+			"}\n",
+	}
+	cliDir, pipelineDir := seedReimplementationFixture(t, files, []NovelFeature{
+		{Name: "SQL query", Command: "query"},
+	})
+
+	got := checkReimplementation(cliDir, pipelineDir)
+	if got.Skipped {
+		t.Fatalf("expected non-skipped result, got Skipped=true (backtick Use: not indexed)")
+	}
+	if got.Checked != 1 {
+		t.Fatalf("Checked: want 1, got %d", got.Checked)
+	}
+	if len(got.Suspicious) != 0 {
+		t.Fatalf("Suspicious: want 0, got %d (%v)", len(got.Suspicious), got.Suspicious)
+	}
+}
+
 // Skip path: when research.json is missing the check returns Skipped
 // rather than crashing.
 func TestCheckReimplementation_NoResearchDir_Skipped(t *testing.T) {
diff --git a/internal/pipeline/scorecard.go b/internal/pipeline/scorecard.go
index 85cddb59..b2813303 100644
--- a/internal/pipeline/scorecard.go
+++ b/internal/pipeline/scorecard.go
@@ -1152,10 +1152,11 @@ func scoreVision(dir string) int {
 	return score
 }
 
-// cobraUseLeafRe extracts the first whitespace-delimited token from a Cobra
-// `Use: "..."` literal — the leaf command name (e.g., `"trajectory <slug>"`
-// → `trajectory`).
-var cobraUseLeafRe = regexp.MustCompile(`Use:\s*"([^"\s]+)`)
+// cobraUseLeafRe extracts the leaf command name from a Cobra Use: literal.
+// Accepts both Go string forms — double-quoted and backtick raw-string —
+// because authors reach for backticks when the value contains a literal
+// double-quote.
+var cobraUseLeafRe = regexp.MustCompile("Use:\\s*[\"`]([^\"`\\s]+)")
 
 // manifestNovelFeatureLeaves returns the leaves of every novel_features[].command
 // in dir/.printing-press.json. Returns nil when the manifest is missing,

← f88a10b3 fix(cli): preserve novel-command keys in --compact partial-s  ·  back to Cli Printing Press  ·  fix(cli): handle PascalCase .NET-shape API responses in sync 84138f91 →