docsite: fix fencedCarlosVerbs to catch all invocations
Three fixes for false negatives in carlos verb extraction: 1. Change break to continue after finding a verb: allows multiple carlos invocations on the same line (e.g., compound && statements) to all be extracted rather than stopping after the first. 2. Treat # as comment-start only at line start or after space/tab: URLs with fragments (https://example.com/#cli) were truncating valid examples that followed them. 3. Skip backslash tokens: line-continued invocations (carlos \) would extract the backslash as a verb, causing legitimate examples to fail validation. Adds three test cases pinning each fix and verifying the existing six-line test still passes with the same expected output.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 file changed,
+53
−3
internal/docsite/fences_test.go+53 −3
diff --git a/internal/docsite/fences_test.go b/internal/docsite/fences_test.go| index e89ccaf21..95961381a 100644 |
| --- a/internal/docsite/fences_test.go |
| +++ b/internal/docsite/fences_test.go |
| @@ -95,7 +95,10 @@ func fencedCarlosVerbs(body string) []string { |
| for _, line := range strings.Split(body, "\n") { |
| line = strings.TrimSpace(line) |
| line = strings.TrimPrefix(line, "$ ") |
| - if i := strings.Index(line, "#"); i >= 0 { |
| + // Treat # as starting a comment only when it is at index 0 or |
| + // preceded by a space or tab. A # with a non-space before it |
| + // (like a URL fragment) is not a comment. |
| + if i := strings.Index(line, "#"); i >= 0 && (i == 0 || line[i-1] == ' ' || line[i-1] == '\t') { |
| line = strings.TrimSpace(line[:i]) |
| } |
| fields := strings.Fields(line) |
| @@ -111,10 +114,13 @@ func fencedCarlosVerbs(body string) []string { |
| } |
| next := fields[i+1] |
| if strings.HasPrefix(next, "-") { |
| - break |
| + continue |
| + } |
| + if next == "\\" { |
| + continue |
| } |
| out = append(out, next) |
| - break |
| + continue |
| } |
| } |
| return out |
| @@ -143,3 +149,47 @@ func TestFencedCarlosVerbsIgnoresNoise(t *testing.T) { |
| } |
| } |
| } |
| + |
| +// TestFencedCarlosVerbsCompoundLines verifies the extractor finds |
| +// multiple carlos invocations on a single line (Finding 1 fix). |
| +func TestFencedCarlosVerbsCompoundLines(t *testing.T) { |
| + body := "carlos ship -app hello ./dist && carlos promote -app hello abc123 edge" |
| + got := fencedCarlosVerbs(body) |
| + want := []string{"ship", "promote"} |
| + if len(got) != len(want) { |
| + t.Fatalf("got %v, want %v", got, want) |
| + } |
| + for i := range want { |
| + if got[i] != want[i] { |
| + t.Fatalf("got %v, want %v", got, want) |
| + } |
| + } |
| +} |
| + |
| +// TestFencedCarlosVerbsURLFragment verifies the extractor does not |
| +// mistake URL fragments for comments (Finding 2 fix). |
| +func TestFencedCarlosVerbsURLFragment(t *testing.T) { |
| + body := "curl -s https://carlosframework.com/docs/#cli && carlos ship -app website ./dist" |
| + got := fencedCarlosVerbs(body) |
| + want := []string{"ship"} |
| + if len(got) != len(want) { |
| + t.Fatalf("got %v, want %v", got, want) |
| + } |
| + for i := range want { |
| + if got[i] != want[i] { |
| + t.Fatalf("got %v, want %v", got, want) |
| + } |
| + } |
| +} |
| + |
| +// TestFencedCarlosVerbsBackslashContinuation verifies the extractor |
| +// does not extract backslash as a verb in line-continued invocations |
| +// (Finding 3 fix). |
| +func TestFencedCarlosVerbsBackslashContinuation(t *testing.T) { |
| + body := "carlos \\" |
| + got := fencedCarlosVerbs(body) |
| + want := []string{} |
| + if len(got) != len(want) { |
| + t.Fatalf("got %v, want %v", got, want) |
| + } |
| +} |