Advanced Topics#
See Generator design principles for the function-and-comment-first design, execution ownership, scoped initializer decisions, and when advanced startup/template customization is appropriate. The architecture document clearly distinguishes current behaviour from proposed features.
See Project generation configuration for optional versioned generator settings and explicit CLI override precedence.
See Functionless command metadata for explicit root identity and help without an action, Go/config declarations, documentation and man appendices.
Man Page Generation#
go-subcommand can generate standard Unix man pages.
gosubc generate --man-dir ./manThis writes root and child roff pages directly under ./man, for example
my-app.1 and my-app-subcmd.1. Native config man appendices are included in the
selected command’s page.
The content is derived from:
- The command description.
- The extended help text in comments.
- Flag descriptions and defaults.
See Generated errors and process boundary for typed usage failures, wrapped explicit exit statuses, and the generated runner.
See No-command policy to require a selected command using functionless root metadata or native configuration.
Architecture#
The generator works by:
- Parsing: It scans
.gofiles in your module (usinggo/parserandgo/ast) to find functions with the magic// ... is a subcommand ...comment. - Modeling: It builds a tree of commands, handling implicit parent commands and resolving parameter details.
- Generating: It uses Go templates (embedded in the tool) to generate:
root.go: The entry point and root command logic.process.go: Testable error rendering, exit selection, and process runner.cmd.go: Helper interfaces and shared logic.- Subcommand files:
subcommand_xyz.gofor each command node. - Usage templates: Text files for usage output.
Runtime Logic#
The generated code uses a lightweight Command interface.
- Flags: It uses the standard
flagpackage. - Dispatch: Commands are organized in a map/tree structure.
Executemethods dispatch to subcommands or run the bound function. - Dependency-Free: The output does not import
github.com/arran4/go-subcommandat runtime.
Conditional Generation#
To ensure your project builds even if a contributor doesn’t have gosubc installed, use this go:generate directive:
//go:generate sh -c "command -v gosubc >/dev/null 2>&1 && gosubc generate || go run github.com/arran4/go-subcommand/cmd/gosubc generate"This attempts to use the installed binary first, falling back to go run (which compiles it from source) if missing.