diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index e391a2ba..ba3e8417 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -229,6 +229,10 @@ Use conventional commit format (feat:, fix:, chore:, etc.) for commit titles. 5. Run `slack docgen ./docs/reference` to generate docs 6. Consider adding command alias in `AliasMap` if appropriate +### Command Descriptions and Documentation + +Command `Long` descriptions are parsed as Go `text/template` by `docgen` and rendered as MDX for the documentation site. Escape `{` and `[` as `\{` and `\[` in description text to prevent build errors on the docs site. Available template functions: `{{Emoji "name"}}`, `{{LinkText "url"}}`, `{{ToBold "text"}}`. + ### Adding New Dependencies 1. Update `go.mod` with the new module version diff --git a/cmd/root_test.go b/cmd/root_test.go index 9ca2b472..e1a964dd 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -18,6 +18,7 @@ import ( "context" "fmt" "os" + "regexp" "strings" "testing" @@ -290,3 +291,29 @@ func testExecCmd(ctx context.Context, args []string) (string, error) { } return clientsMock.GetCombinedOutput(), nil } + +func Test_CommandDescriptionsRenderForDocs(t *testing.T) { + ctx := slackcontext.MockContext(t.Context()) + tmp, _ := os.MkdirTemp("", "") + _ = os.Chdir(tmp) + defer os.RemoveAll(tmp) + + cmd, _ := Init(ctx) + + // Matches a lone { that is not escaped (\{) and not part of a Go template ({{) + unescapedBrace := regexp.MustCompile(`[^\\{]\{[^{]`) + + var walk func(*cobra.Command) + walk = func(c *cobra.Command) { + if c.Long != "" { + t.Run(c.CommandPath(), func(t *testing.T) { + assert.NotRegexp(t, unescapedBrace, c.Long, + "description contains unescaped '{' which breaks the MDX docs site; escape as \\{") + }) + } + for _, child := range c.Commands() { + walk(child) + } + } + walk(cmd) +}