[object Object]

← back to Cli Printing Press

feat(generator): auto-generate usage examples in command help

e993ba6e248c25b5f4d1986fedc1676a4e0a72da · 2026-03-23 18:56:25 -0700 · Matt Van Horn

Every generated Cobra command now includes an Example field showing
the full command path with positional args and a sample required flag.
Sub-resource commands include parent path (e.g. "discord-cli channels
messages create <channel_id>").

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Files touched

Diff

commit e993ba6e248c25b5f4d1986fedc1676a4e0a72da
Author: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Date:   Mon Mar 23 18:56:25 2026 -0700

    feat(generator): auto-generate usage examples in command help
    
    Every generated Cobra command now includes an Example field showing
    the full command path with positional args and a sample required flag.
    Sub-resource commands include parent path (e.g. "discord-cli channels
    messages create <channel_id>").
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---
 internal/generator/generator.go              | 32 ++++++++++++++++++++++++++++
 internal/generator/templates/command.go.tmpl |  1 +
 2 files changed, 33 insertions(+)

diff --git a/internal/generator/generator.go b/internal/generator/generator.go
index 3fed5e92..c16a784f 100644
--- a/internal/generator/generator.go
+++ b/internal/generator/generator.go
@@ -40,6 +40,7 @@ func New(s *spec.APISpec, outputDir string) *Generator {
 		"add":              func(a, b int) int { return a + b },
 		"oneline":          oneline,
 		"flagName":         flagName,
+		"exampleLine":      g.exampleLine,
 	}
 	return g
 }
@@ -86,11 +87,13 @@ func (g *Generator) Generate() error {
 		data := struct {
 			ResourceName string
 			FuncPrefix   string
+			CommandPath  string
 			Resource     spec.Resource
 			*spec.APISpec
 		}{
 			ResourceName: name,
 			FuncPrefix:   name,
+			CommandPath:  name,
 			Resource:     resource,
 			APISpec:      g.Spec,
 		}
@@ -104,11 +107,13 @@ func (g *Generator) Generate() error {
 			subData := struct {
 				ResourceName string
 				FuncPrefix   string
+				CommandPath  string
 				Resource     spec.Resource
 				*spec.APISpec
 			}{
 				ResourceName: subName,
 				FuncPrefix:   name + "-" + subName,
+				CommandPath:  name + " " + subName,
 				Resource:     subResource,
 				APISpec:      g.Spec,
 			}
@@ -293,6 +298,33 @@ func oneline(s string) string {
 	return s
 }
 
+func (g *Generator) exampleLine(commandPath, endpointName string, endpoint spec.Endpoint) string {
+	var parts []string
+	parts = append(parts, g.Spec.Name+"-cli")
+	parts = append(parts, strings.Fields(commandPath)...)
+	parts = append(parts, endpointName)
+
+	// Add positional arg placeholders
+	for _, p := range endpoint.Params {
+		if p.Positional {
+			parts = append(parts, "<"+p.Name+">")
+		}
+	}
+
+	// Add a sample flag for POST/PUT/PATCH
+	switch endpoint.Method {
+	case "POST", "PUT", "PATCH":
+		for _, p := range endpoint.Body {
+			if p.Required && p.Type == "string" {
+				parts = append(parts, "--"+strings.ReplaceAll(p.Name, "_", "-"), "value")
+				break
+			}
+		}
+	}
+
+	return "  " + strings.Join(parts, " ")
+}
+
 func flagName(name string) string {
 	return strings.ReplaceAll(name, "_", "-")
 }
diff --git a/internal/generator/templates/command.go.tmpl b/internal/generator/templates/command.go.tmpl
index da45809e..4b57355f 100644
--- a/internal/generator/templates/command.go.tmpl
+++ b/internal/generator/templates/command.go.tmpl
@@ -39,6 +39,7 @@ func new{{camel $.FuncPrefix}}{{camel $eName}}Cmd(flags *rootFlags) *cobra.Comma
 	cmd := &cobra.Command{
 		Use:   "{{$eName}}{{positionalArgs $endpoint}}",
 		Short: "{{oneline $endpoint.Description}}",
+		Example: "{{exampleLine $.CommandPath $eName $endpoint}}",
 		RunE: func(cmd *cobra.Command, args []string) error {
 			c, err := flags.newClient()
 			if err != nil {

← 33d06483 fix(openapi): handle nullable types in OpenAPI 3.1 specs  ·  back to Cli Printing Press  ·  feat(generator): auto-detect array responses and render as f c5618c08 →