Subcommand sections¶
Cloup allows you to organize the subcommand of a Group
(or, more in general, of
a MultiCommand
) in multiple help sections. Each such help section is
represented by a Section
instance, which is just a titled
container for commands.
A Section
can be:
sorted – it lists the commands in alphabetical order
unsorted – it lists the commands in the order they are added to the section.
All sections defined by the developer are unsorted by default. You can create a
sorted section by passing sorted=True
or by using the static method
Section.sorted(*commands)
.
Adding full sections¶
This is my favourite way of structuring my sections. You can find a runnable example that implements part of the help of Git here. The code below is based on that example.
import cloup
from .commands import ( # import your subcommands
git_clone, git_init, git_rm, git_sparse_checkout, git_mv,
git_status, git_log)
@cloup.group('git')
def git():
return 0
git.section(
'Start a working area (see also: git help tutorial)',
git_clone,
git_init
)
git.section(
'Work on the current change (see also: git help everyday)',
git_rm,
git_sparse_checkout,
git_mv
)
# Subcommands that are not assigned to a specific section
# populate the "default section"
git.add_command(git_status)
git.add_command(git_log)
Usage: git [OPTIONS] COMMAND [ARGS]...
Options:
--help Show this message and exit.
Start a working area (see also: git help tutorial):
clone Clone a repository into a new directory
init Create an empty Git repository or reinitialize an...
Work on the current change (see also: git help everyday):
rm Remove files from the working tree and from the index
sparse-checkout Initialize and modify the sparse-checkout
mv Move or rename a file, a directory, or a symlink
Other commands:
log Show commit logs
status Show the working tree status
All commands that are not explicitly assigned to a section are assigned to a
default (sorted) section. This section is titled “Other commands”,
unless it is the only section defined, in which case cloup.Group
behaves
like a normal click.Group
, naming it just “Commands”.
Each call of Group.section
instantiates a new Section
and adds it to the Group
. Of course, when you add a section, all its
commands added to the Group
.
In alternative, you can create a list of Section
objects and pass it as the
sections
argument of cloup.group()
:
import cloup
from cloup import Section
# [...] omitting import/definition of subcommands
SECTIONS = [
Section('Start a working area (see also: git help tutorial)',
[git_clone, git_init]),
Section('Work on the current change (see also: git help everyday)',
[git_rm, git_sparse_checkout, git_mv])
]
@cloup.group('git', sections=SECTIONS)
def git():
return 0
Adding subcommands one at a time¶
In Cloup, all Group
methods for adding subcommands, i.e. Group.command
,
Group.group
and Group.add_command
, have an additional section
argument that you can (optionally) use to assign a subcommand to a Section
.
import cloup
from cloup import Section
# Define sections without filling them.
# I'm using a class as a namespace here.
class Sect:
START_WORKING_AREA = Section(
'Start a working area (see also: git help tutorial)')
WORK_CURRENT_CHANGE = Section(
'Work on the current change (see also: git help everyday)'
@cloup.group('git')
def git():
return 0
@git.command('init', section=Sect.START_WORKING_AREA)
def git_init():
pass
@git.command('mv', section=Sect.WORK_CURRENT_CHANGE)
def git_mv():
pass
Note that – differently from OptionGroup
instances – Section
instances
don’t act as simple markers, they act as containers from the start: they are
mutated every time you assign a subcommand to them.