I began engaged on this venture a couple of month earlier than 1.27. In the present day I’m completely happy to announce that I’ve launched v1.0.0-rc.1 of Commandment, a Go framework for constructing typed command-line purposes. The v1 function set and public API are actually basically full; this RC is the purpose the place I need the design uncovered to actual use and criticism earlier than I freeze it as v1.0.0.
The principle motive Commandment exists is {that a} nontrivial CLI tends to build up a number of overlapping descriptions of itself. As an SRE marketing consultant, this has been an enormous thorn in my aspect for the higher a part of a decade. I’ve performed with totally different CLI libraries and design patterns inside these libraries, however nothing actually solved the issues I had for making manufacturing stage CLI-based apps with out a important quantity of customized code. Numerous my issues should do with how most typical Go CLI libraries are crucial by design.
Commandment as a substitute compiles a typed declaration into one semantic software mannequin. Working the CLI, producing assist and completion, inspecting it, and testing its semantics are totally different operations over that very same mannequin moderately than separate approximations of it. Its as near declarative as I may get it, and I believe it appears to be like fairly clear.
Let’s try an instance:
kind scanConfig struct {
World string
}
kind abductConfig struct {
Goal string
}
var definition = cli.Definition[struct{}]{
Title: "alienctl",
Declare: func(root *cli.CommandBuilder[struct{}]) {
root.Subcommands.Command(cli.Command[scanConfig]{
Title: "scan",
Declare: func(scan *cli.CommandBuilder[scanConfig]) {
scan.Arguments.String(&scan.Config.World, "world")
},
})
root.Subcommands.Command(cli.Command[abductConfig]{
Title: "abduct",
Declare: func(abduct *cli.CommandBuilder[abductConfig]){
abduct.Arguments.String(&abduct.Config.Goal, "goal")
},
})
},
}
The father or mother is authored via CommandBuilder[struct{}], whereas scan and abduct every maintain their very own concrete configuration kind. The kid kind belongs to the Command technique invocation moderately than turning into one other kind parameter of the father or mother.
Generic strategies are used all through the declaration API for comparable relationships. Typed locations, for instance, stay typed whereas being related to arguments, flags, atmosphere enter, defaults, guidelines, dependencies, info, and different components of the mannequin.
One other nice function of commandment, is that when the declaration is compiled, the ensuing software stays the authoritative semantic mannequin. Execution, assist, completion, inspection, diagnostics, and semantic checks devour that mannequin as a substitute of reconstructing the CLI independently.
Bearing on my declare of “feature-completeness,” I imply that I take into account the meant v1 capabilities and API design considerably closed. I actually can’t consider a single additional function so as to add to the entrance finish API. I’m really anticipating a little bit of push again on together with a Alerts API which I personally suppose is extremely badass however some purists on the market might not admire. You be the decide.
Additionally, I don’t imply that an RC doesn’t include bugs. The purpose of rc.1 is to search out errors earlier than I decide to a definitive v1.0.0 launch. If all goes nicely, I may see chopping an precise v1 someday subsequent month or early December.
Please evaluation the repo, make your individual CLI in case you really feel as much as it, and let me know what you suppose. I need you to be as brutal as you need. I’m so extremely bored with taking a look at this codebase and want recent pairs of eyes on it earlier than I really feel comfy assuring that commandment is prepared for “manufacturing” use.
Repo: GitHub – abstractionsinc/commandment: A full-feature CLI Library for Go · GitHub
Examples: commandment/examples at essential · abstractionsinc/commandment · GitHub

