Skip to main content

Module go

Module go 

Source
Expand description

Emitting Go parse tables from a spec.

The Go side of usage has no derive macro to emit its tables, because Go has no macros: what a Rust CLI gets from #[derive(Cli)] at compile time, a Go CLI gets from this, at build time, through go:generate. The output is a plain Go file an author checks in and a reviewer can read.

§What it emits, and what it does not

Two tables, kept apart on purpose. The hot one is what binding reads: which token becomes which flag or argument, and nothing else. The cold one — Meta — carries what the rules decided after the last token need: required, choices, default, env, the var bounds, and the four that compare one entry against another. A parse never touches the second.

Help text is in neither. mise’s runs to several hundred kilobytes, and a table carrying it would put all of that in front of the parser; rendering help is its own cold table and its own piece of work.

§Why package-level var and not const

Go has no const for composite data. What it does have is a linker that statically initializes package-level variables holding plain data, which is the property the whole design rests on: go tool nm reports these symbols as type D, and the generated package has no init function. So a 211-command table costs bytes in the binary and no instructions at startup — the thing cobra and kong each pay a million or more for.

Commands are emitted as separate variables rather than one nested literal because default_subcommand has to point at a node inside the tree, and a composite literal cannot refer to its own interior.

Structs§

GoOptions
How to emit.

Functions§

generate
Turn a spec into a Go source file declaring its parse tables.
is_valid_package
Whether a string can be written after package and then imported.