File: sections.rst

package info (click to toggle)
python-cloup 3.0.8-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 936 kB
  • sloc: python: 5,371; makefile: 120
file content (146 lines) | stat: -rw-r--r-- 4,772 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
.. highlight:: none

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 :class:`~cloup.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 <https://github.com/janLuke/cloup/blob/master/examples/git_sections.py>`_.
The code below is based on that example.

.. tabbed:: Code
    :new-group:

    .. code-block:: python

        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)


.. tabbed:: Generated help

    .. code-block:: none

        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 :class:`Group.section` instantiates a new :class:`~cloup.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 :func:`cloup.group`:

.. code-block:: python

    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``.

.. code-block:: python

    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.