Flag
What is Flags
need rewrite this article with english
Flags
What is Flag, and Option?
Inside cmdr.v2
, terms Flag
and Option
are used confusingly, and constantly. But, these two terms are different in fact.
A Flag
, means that an object created via the interfaces like app.Flg()
/builder.Flg()
, which will be used for interpreting an cmdline option, and there is also a coresponding Option
item in Option Store
that is mapping to it.
A Option
item, means that a key-value pair in Option Store
. For instance, “app.debug” => true
is a kv pair entry. The hierarchical layout of its yaml representation is,
In the most scenes, we would like use Option
to represent a key-value pair identified by keyPath
, whatever it is a Flag
exactly, or not.
Integrated with Option Store
We knew Option Store
is a in-memory config manager for hierarchical key-value pairs dataset identified by dottedPath
/keyPath
. And, an Option
can be associated with a Flag
, or not. But there is always an Option
binded to a Flag
.
For the top level flag --debug
, the store entry associated with it is app.cmd.debug
, since app.cmd
is a hard-coded prefix for command line options.
For those flags of subcmds, such as --cacert
under subcmd cert / create
, the entry dotted path would be app.cmd.cert.create.cacert
.
cmd.Store()
vs cmd.Set()
Programmatically, you can code with app.Store()/app.Set()
.
The cmd.Store()
returns a subset of app's whole Store, which have a root key pointed to key path app.cmd.jump.to
. That means, cmd.Store().MustBool("full")
can read and write the state of a command line flag --full
.
The cmd.Set()
returns the app's whole Store, which equals to app.Set()
,So you need a cmd.Set().MustBool("app.cmd.jump.to.full")
to access the state of --full
. Another way is,
The similar call to app.Store()
will get a subtree pointed to app.cmd
, which stores the values of all of command-line flags. So app.Store().MustBool("jump.to.full")
can query the same key above.
For a short and concise calling statement, it's useful by using GetXXX
/MustXXX
on the object of cmd.Store()
/app.Store()
.
The prefix app.cmd
is used for serializing the Option Store
, such as YAML, TOML, etc.. The notable point is app
will be stripped when you're really serializing it. So a key app.some.path.debug
will be stored as some.path.debug
in a YAML file:
As a sample, here is a Store's YAML file content:
keyPath
/dottedPath
keyPath
/dottedPath
/dottedKeyPath
is a exclusive term specially for Option Store
, which provides an anchor to any entries in the Store
by the form prefix.subcmds...flag
.
For an intance, a dottedPath app.cmd.cert.create.cacert
has app.cmd
as a special prefix for command-line flags, and cert.create
is subcommands cert
and its child create
, and cacert
is the long title of a flag, which belongs to subcmds cert.create
.
The flag cacert
can be specified by --cacert
from command-line.
Long Flag, Short and Alias
The term Long Flag
is required for a command-line flag. It is the unique identifier in cmdr
system.
A Long Flag
has prefix --
in the command-line. For example, --cacert
is a flag of subcmds cert.create
:
The Short Flag
can be attached to a command-line flag. It uses prefix -
in the command-line. It is a shortcut to a flag.
Under cmdr.v2
system, multiple short flags can be attached with one flag by using call like b.Flg(longTitle, shortTitle...).ExtraShorts(...)
.
Short flag is constantly a single char in POSIX standard. So we can use -v
as the shortcut to --verbose
flag.
But in cmdr
system (both v1 and v2), a short flag can be a string with any length. As a sample, -ap
has short title ap
, shortcut to --extra-files
, this is legal too.
Golang flags
uses a wired form different than POSIX standard, which has no short or long flag, all flags have the single hyphen char as its leading prefix. That is why in a golang app -port
will be used for setting the listening port number rather than --port
.
cmdr
is a POSIX-compliant command-line argument parser. So we recommend using -p
and --port
to specify port number. But you can still make a golang flag like app by specifying a short flag with title name port
, this is legal option.
By using the builder interface, Flg(longTitle, shortTitle, ...)
allows more alias titles associated with a flag. The alias titles are equavalent to long flag, with the leading double hyphen chars --
.
As a sample, b.Flg("version", "V", "ver")
defines a version flag with both long, short and alias titles. So the following command-line inputs are avaliable:
Totally you can always organize your command and flag system in a freestanding form. Keep it concise. Too much command depthes and too much more flags are not kindly enough to end-user.
Compat short flags
Multiple short flags can be compated into one leading hyphen char -
, this is POSIX-compliant. The compat form is equavalent to the split form:
Default Value
You can specify the default value to a flag, with different types.
b.Flg("count", "c").Default(3)
defined its default value is int(3)
.
The primitive value, including integer, float, complex, boolean, or string, time, duration, slice can be specified as the default value of a flag.
So b.Flg("interval", "i").Default(3*time.Second)
defined a time duration value 3s
. End user can input the new value with Golang literal convension, for a example::
It specifys a duration value with 8 minutes, which overrides the default value when you defined it.
Duplicated inputs
In general, duplicated inputs of a flag causes the old value to be overlapped by the new one.
So app -c 3 -c 4 -c 5
means the final value of -c
is 5.
The exception is slice value. The duplicated inputs of a flag with default slice value causes the new value to apppend to the old. And, the delimiter char ,
is used for splitting the items in one input string.
This means, as for a flag b.Flg("add", "a").Default([]string{"a", "b"})
, the input app -a z,y -a x -a u,v,w
will get the final value []string{"z","y","x","u","v","w"}
.
Input in command-line
Stripping quotes
cmdr support stripping the quote chars for a flag:
--host=localhost
--hostlocalhost
--host localhost
"--hostlocalhost"
'--hostlocalhost'
--host"localhost"
--host'localhost'
--host "localhost"
and so on.
These quote chars will be removed by shell automatically. If not, cmdr
will do it.
Slice value
While a flag is associated with a default slice value, such as []string
, cmdr
will merge the duplicated inputs as once slice. That means, -f a -f b -f c
will be translated to the final value []string{"a", "b", "c"}
. Since the comma ,
character will be treated as delimiter for splitting a string into slice, so -f a,b -f c
will get the same final value.
Hit info
cmdr
maintains a hit info record, including the flag title string, short or long, untranslated raw value, and hit times. Sometimes you could change the bizlogic with these records.
Default behavior of --verbose
The builtin flag --verbose
has these behaviors:
-
nothing input,
The hidden flags/commands wouldn't be shown on help screen
-
once (
-v
),The hidden flags/commands could be shown
-
triple times (
-v -v -v
or-vvv
)The vendor-hidden flags/commands will be shown onto help screen
You can redefined the hit times or other hit info. As a case, you could treat the hit times of --verbose
as a level in 0..9, and uses the level for how many tip messages can be visible in logging.
For the builtin flags, such as verbose
, quiet
, debug
, the final state, hit-times (level) are organized into Env
manager inside package hedzr/is
,
Refer these topics for the details:
is.VerboseModeEnabled()
,is.GetVerboseLevel()
is.QuietModeEnabled()
,is.GetQuietLevel()
is.NoColorModeEnabled()
,is.GetNoColorLevel()
is.DebugMode()
,is.GetDebugLevel()
is.TraceMode()
,is.GetTraceLevel()
Styles of short flag
Short flags can have multiple characters rather than single one
We supports a phrase as a short flag title.
In another words, you can blur out the differences between short and long flag, so that the golang flag style and GNU getopt style could live at a same app together.
Golang flag style: the flags are always leading by single hyphen character: -host abc -port 9999
GNU getopt style: both the leading hyphen -
and double hyphen --
are avaliable for short and long flag. A short flag has single character or number as its title, mostly in POSIX. The sample: -d -t --retry 3
。
cmdr style: beyond getopt style, remote the limit about single char title for the short flag. So -host abc
and -host abc --retry 3
are legal.
Mixing in flag title and value
Once no ambiguities, any combinations of short flags are ok, even mixing the flag title and raw value string in together:
Therefore -dr3t
would be interpted to --debug --retry 3 --timeout
。
cmdr can backtrace and regress to the up level to solve the matches in parsing time.
额外的话题
How is this guide?
Last updated on