Syntax & Conventions
Basics
leaf command: leaf commands are the commands at the last of the CLI that takes arguments, options and flags, e.g the show command below
node command: node commands are the commands at the middle or first of the CLI that contains sub-commands, e.g the remote command below
git remote show originarguments: arguments are command line arguments that required at the leaf command
flags: flags are command line options that has no arguments, e.g --flag or -f (short flag).
options: options are command line options that has arguments, e.g --name Sam or -n Sam, also --name=Sam or -nSam.
When used on function expressions, @cast and @main have the same convention on how they convert your expressions to commands, these are
- function arguments are parsed as command arguments:- value will be converted automatically if arguments has type annotation
- optional arguments are allowed
 
- function keyword arguments are parsed as command flags or options:- keyword arguments must have default value
- keyword arguments of type Boolcan only havefalseas default value, which will be treated as flags that allow short flags.
- value will be converted automatically if keyword arguments has type annotation
 
- function doc string can use section names: Arguments, Options and Flags to annotate your CLI:- short options or short flags can be declared via -f, flagor-o, --option <name>(see example below)
 
- short options or short flags can be declared via 
to be compatible with shell options, variable names with underscore _ will be automatically replaced with dash -.   As a result, the corresponding doc string should use dash - instead of _ as well, e.g kwargs name dash_dash will be converted to --dash-dash option/flag in terminal, and its corresponding doc string should be - `--dash-dash`: <arg>.
Help and Version
There are two flags are always generated and always have highest priority, they are -h,--help and --version. The version is automatically read from the corresponding project's Project.toml if it's not found then it's set to 0.0.0.
Doc String Syntax
the docstring of each @cast or @main annotated object have a few special section. The function or module signature is ignored for generating CLI help page, 
Description
The description of the command is seperated as brief and detailed description. The special sections are organized as following:
- The brief description is the first paragraph of the docstring.
- The long detailed description can be specified using #Introor#Introductionsection.
for example
"""
    command(args1, args2, args3, args4)
the brief description of the command.
# Intro
the long description of the command,
asdmwds dasklsam xasdklqm dasdm, qwdjiolkasjdsa
dasklmdas weqwlkjmdas kljnsadlksad qwlkdnasd
dasklmdlqwoi, dasdasklmd qw,asd. dasdjklnmldqw.
"""Arguments
The argument description can be specified using #Args or #Arguments section. The syntax must be
- `<arg name>`: <description of the argument>for example
"""
    command(args1, args2, args3, args4)
the brief description of the command.
# Intro
the long description of the command,
asdmwds dasklsam xasdklqm dasdm, qwdjiolkasjdsa
dasklmdas weqwlkjmdas kljnsadlksad qwlkdnasd
dasklmdlqwoi, dasdasklmd qw,asd. dasdjklnmldqw.
# Args
- `arg1`: argument 1.
- `arg2`: argument 2.
- `arg3`: argument 3.
- `arg4`: argument 4.
"""Options
the options can be specified in #Options section, the option must have a prefix --, and optionally have -<first letter> to specify its short option. All underscore _ in the option name will be converted to a dash - for option names, for example.
The value string after = (e.g -s=<value>) can give user specified hint or the default hint will be the default value's Julia expression.
# Options
- `--short, -s`: short option using default hint.
- `--short-space, -s <value>`: short option using given hint.
- `--short-assign, -s=<value>`: short option using given hint.
- `--long`: long option using default hint.
- `--long-space <value>`: long option using given hint.
- `--long-assign=<value>`: long option using given hint.
- `--short_underscore, -s <value>`: short option with underscore.Flags
the flags can be specified using #Flags section, the rest are similar to #Options except there are no value hints.
Special Arugment/Options Types
there are a few special argument/option types defined to generate special shell completions.
Comonicon.Arg.ArgType — Typeabstract type ArgTypeAbstract type for special CLI arguments. These types are useful for generating shell autocompletions and argument checks. All the ArgType should implement a corresponding Base.tryparse method, otherwise it will fallback to passing the raw string as the content field.
Comonicon.Arg.DirName — Typestruct DirName <: ArgType
DirName(content)A DirName object denotes a directory name as CLI input.
Comonicon.Arg.FileName — Typestruct FileName <: ArgType
FileName(content)A FileName object denotes a file name as CLI input.
Comonicon.Arg.Path — Typestruct Path <: ArgType
Path(content)A Path object denotes a path as CLI input.
Comonicon.Arg.Prefix — Typestruct Prefix{name} <: ArgType
Prefix{name}(content)Denotes strings with prefix name as CLI input, e.g data-xxx
Comonicon.Arg.Suffix — Typestruct Suffix{name} <: ArgType
Suffix{name}(content)Denotes strings with suffix name as CLI input, e.g xxxxx.jl.
Comonicon.Arg.UserName — Typestruct UserName <: ArgType
UserName(content)A UserName object denotes a Linux/MacOS user name as CLI input.
Comonicon.Arg.@Prefix_str — Macromacro Prefix_str
Prefix"<name>"Syntax sugar for creating a prefix type, e.g Predix"data" is the same as Prefix{:data}.
Comonicon.Arg.@Suffix_str — Macromacro Suffix_str
Suffix"<name>"Syntax sugar for creating a suffix type, e.g Suffix"data" is the same as Suffix{:data}.
Working with option types from Configurations
If the option type is defined using @option then Comonicon can provide the following syntax to read a configuration file.
using Test
using Comonicon
using Configurations
@option struct OptionA
    a::Int
    b::Int
end
@option struct OptionB
    option::OptionA
    c::Int
end
"""
# Options
- `-c, --config <path/to/option/or/specific field>`: config.
"""
@main function run(;config::OptionB)
    @test config == OptionB(OptionA(1, 1), 1)
endcan be used with the following syntax
command --config.c=1 --config.option.a=1 --config.option.b=1
command --config=config.toml
command -c config.toml
command -c config.toml --config.option.b=2 # change a field of config.tomlDash Seperator
Dash seperator -- is useful when the CLI program contains scripts that accepts command line inputs, e.g a custom command run that execute Julia script
run --flag -- script.jl a b cone will need to seperate the input of run and script.jl for disambiguity sometimes,then the dash seperator comes useful for this case.
Plugins
Most complicated CLIs support plugins, this is acheived by checking if there is a command line executable with the following name pattern
<main command name>-<plugin name>for example, git have plugin program called git-shell and can be called as git shell, this is by default turned off, but one can enable this feature by setting the following in (Julia)Comonicon.toml
[command]
plugin=true