Tags

root level

At the root level of the YAML document that is the source for cligen, there is mapping for which the following tags are recognised as keys (i.e. tags without argument or as part of keys.

!Cli
This tags a scalar number that is the version of the commandline specification. The number should be 0 (zero): !Cli 0. The value for this key should be a sequence of global settings, options and subcommands

!ImportFile
This tags a filename and expects a scalar as value. Without this the version number string used in the generated __main__.py will be imported from the __init__.py file using from . import __version__. When you specify

!ImportFile version.py : |

__version__ = '3.2.1'

then the import line will read from version import __version__, and file version.py is written with as content of the scalar. The tag is used in the test data for cligen

!File
This tags a filename and expects a sclar as value, usually a literal style scalar. The file with filename is written with the value as the content. If the filename is __main__.py the value is appended to the generate __main__.py. The tag is used in the test data for cligen.

Options and arguments

Options and arguments can be provided at the root level or for a subcommand. If subcommands are used the parent (root) level can have options, but should not have arguments.

Options

!Option (short forms: !Opt, !O)
This tags a sequence consisting of at least one scalar string zero or more tagged option modifiers.

The first multi-character scalar string is taken to be the option name and will be the destination attribute (unless !Dest is provided), other multi-character scalar strings are alternative names to specifiy the option. One or more single character scalars can be provided as altnerative short options. The length of scalar string determines whether something is a long or short option, -- or - are not included in the string.

- !Option [path, file, p, F]

Without further specification an option takes a single argument that is provided as the value for the attribute that is formed from the option name.

!Type
This tags a scalar string that specifies the type of a the attribute as which the option argument is stored. That scalar string should be selected from `bool', 'int', 'date'

!Action
This tags a scalar string that can provide a specific action name. That scalar string should be selected from 'append', 'splitappend', 'count'. Actions often force a specific attribute type ( list, int ).

!Default
This tags a scalar that provides a specific value assigned to the attribute before parsing a config file for other/additional defaults.

!Const
This tags a scalar that provides a specific value that might be used in conjunction with the action or type. As an example see the tri-state code.

!Dest
This tags a scalar string that is used as the attribute to store option information by the parser. If not specified the first long-option is used as attribute.

Help for the option can be provided using !Help.

Arguments

!Argument (short forms: !Arg, !A)
This tags a sequence consisting of at least one scalar string and optional tagged argument modifiers.

Without further specification multiple arguments can be specified and are appended to the attribute that is formed from the argument name.

!Nargs (short form: !N)
This tags a scalar string, integer or a sequence consisting of two integers. The number of arguments provided is checked to fall in the inclusive range of the two integers the list.

A single scalar int N would be the same as specifying [N, N], The scalar string '?', + and '*' are expanded to [0, 1], [1, -1] resp. [0, -1] (with -1 indicating only the first element is compared against) Note that ? and * have special meaning in YAML and should be quoted.

global settings

code calling

The generated __main__.py will import and call functions or methods, the following tags determine what is called specifically. Only one of these options should be specified.

!Instance
This tags a string scalar of the form path.to.filename.ClassName. This expects a Python class ClassName in the file filename.py living in the directory with path/to. The __init__ method of ClassName will be called with the result of the parsing and optionally the configuration instanced. The names of the subcommands should be available as method names with _subcommand attached (if not available, the plain name of the method is tried). If no subcommand is specified (and there is no default), the method run is called. Any method is called without parameter, so to access the result of the parsing (and the config), you have to store these.

Assuming two subcommands: doit and show, neither of which is the default, you would have something like:

class ClassName:
    def __init__(self, args, config=None):
        self._args = args
        self._config = config

    def run(self):
        print(f'no subcommand given: {self._args}')

    def doit(self):
        print(f'doit subcommand: {self._args}')

    def show_subcommand(self):
        print(f'show subcommand: {self._args}')

    def show(self, arg1, arg2):
        # this is never called from __main__.py, as `show_subcommand` exists
        print(arg1, arg2) 

in filename.py

!Module
This tags a string scalar of the form path.to.filename. This expects global functions in the file named filename.py (under directoriy path/to) that matches the subcommand names. These functions are called with the result of the parsing as the first parameter and optionally the configuration that was instanced.

For a subcommand process, use something like

def process(args, config=None):
    print(f'{args=}')

in filename.py

!Main
This tags a single function path of the form path.to.filename.funname. This expects the file filename.py in the directory path/to with a global function named funnname taking the result of parsing as first parameter and optionally the configuration that was instanced. This is intended for specifications without any subcommand:

def funname(args, config=None):
    print(f'{args=}')

in filename.py

config file

!Config
This tags a scalar string. The string can either be one of the supported config file formats (YAML/INI/PON), a path name like ~/.config/command.yaml (in which case the suffix determines the file type), or a two element sequence of a file format and a path name:

- !Config [PON, /etc/develop/develop.cnf]

The config file is used to populate default values, details can be found here

other global settings

!AddDefaults
The tags a scalar string that is added to all help text (from !Help) for all arguments and options that take an argument. If specified as !AddDefaults '(default: %(default)s)', this will cause the default value (from the YAML or config file) to be displayed in the help.

descriptive texts

!Help (short form: !H)
This tags a descriptive scalar string, that is shown as the second column of text in the help output after option/argument/subcommand in the first column.

If the scalar string contains %(default)s or %(metavar)s these are expanded (default with the value from the config file, if applicable)

If a subcommand has no !Prolog, the scalar for !Help is used.

!Prolog
This tags a descriptive text, usually a literal style scalar string that is displayed in help text between the usage line and the listing of subcommands/arguments/options.

If a subcommand has no !Help, the first line of the !Prolog is used.

!Epilog
This tags a descriptive text, usually a literal style scalar string that is displayed at the end of the help text, below the list of options.

subcommand tags

!DefaultSubCommand
This tag takes no option and designates the subcommand as the default if no explicit subcommand is given on the commandline.

!Alias
This tags a scalar string or a sequence of scalar strings. These provide alternative names for a subcommand. The preferred way to specify aliases is by using a sequence starting with the subommand name as key, so:

- [left, notright]:
  - !Help turning to the left

instead of

- left:
  - !Help turning to the left
  - !Alias notright