_Cobra is an excellent framework for the development of command line applications, but is missing a few features that would make it a bit easier to work with. This package aims to fulfil this purpose, especially in regards to creation of commands, encapsulating commands into a container and providing an export mechanism to re-create cli data in a form that is free from cobra (and indeed sundae) abstractions. The aim of this last aspect to to be able to inject data into the core of an application in a way that removes tight coupling to the Cobra
framework, which is achieved by representing data only in terms of client defined (native) abstractions.
... tbd
- Cobra container; collection of cobra commands that can be independently referenced by name as opposed to via child/parent relationship. The container also takes care of adding commands to the root or any other as required.
- A
parameter set
groups together all the flag option values, so that they don't have to be handled separately. A single entity (the ParamSet) can be created and passed into the core of the client application. - unit testing with Ginkgo/Gomega
- implemented with 🐍 Cobra cli framework
- i18n with go-i18n
- linting configuration and pre-commit hooks, (see: linting-golang).
The container serves as a repository for Cobra
commands and Cobrass
parameter sets. Commands in Cobra
are related to each other via parent child relationships. The container, flattens this hierarchy so that a command can be queried for, simply by its name, as opposed to getting the commands by parent command, ie parentCommand.Commands().
The methods on the container, should not fail. Any failures that occur are due to programming errors. For this reason, when an error scenario occurs, a panic is raised.
Registering commands/parameter sets with the container, obviates the need to use specific Cobra
api calls as they are handled on the clients behalf by the container. For parameter sets, the type specific methods on the various FlagSet definitions, such as Float32Var, do not have to be called by the client. For commands, AddCommand does not have to be called explicitly either.
The rationale behind the concept of a parameter set came from initial discovery of how the Cobra
api worked. Capturing user defined command line input requires binding option values into disparate variables. Having to manage independently defined variables usually at a package level could lead to a scattering of these variables on an adhoc basis. Having to then pass all these items independently into the core of a client application could easily become disorganised.
To manage this, the concept of a parameter set
was introduced to bring about a consistency of design to the implementation of multiple cli applications. The aim of this is to reduce the number package level global variables that have to be managed. Instead of handling multiple option variables independently, the client can group them together into a parameter set.
Each Cobra
command can define multiple parameter sets which reflects the different ways that a particular command can be invoked by the user. However, to reduce complexity, it's probably best to stick with a single parameter set per command. Option values not defined by the user can already be defaulted by the Cobra
api itself, but it may be, that distinguishing the way that a command is invoked (ie what combination of flags/options appear on the command line) may be significant to the application, in which case the client can define multiple parameter sets.
The ParamSet also handles flag definition on each command. The client defines the flag info and passes this into the appropriate binder
method depending on the option value type. The binder methods are of the form:
- Bind<Type> : where <Type> represents the type, (eg BindString), the client passes in 'info', a FlagInfo object and 'to' a pointer to a variable to which
Cobra
will bind the option value to.
By default, binding a flag is performed on the default flag set. This flag set is the one you get from calling command.Flags() (this is performed automatically by NewFlagInfo). However, there are a few more options for defining flags in Cobra
. There are multiple flag set methods on the Cobra
command, eg command.PersistentFlags(). To utilise an alternative flag set, the client should use NewFlagInfoOnFlagSet instead of NewFlagInfo. NewFlagInfoOnFlagSet requires that an extra parameter be provided and that is the alternative flag set, which can be derived from calling the appropriate method on the command
, eg:
paramSet.BindString(
assistant.NewFlagInfoOnFlagSet("pattern", "p", "default-pattern",
widgetCommand.PersistentFlags()), ¶mSet.Native.Pattern,
)
The flag set defined for the flag (in the above case 'pattern'), will always override the default one defined on the parameter set.
Please see Powershell Code Generation