Skip to content

Commit 43ae645

Browse files
Hugo Osvaldo Barrerastephenfin
Hugo Osvaldo Barrera
andcommitted
Make show-nested more granualar
I want to entirely hide commands (and render them elsewhere) because of how my documentation is structured. This change allows a more flexible show-nested, but retains backwards-compatibility to avoid breaking any existing integrations. Co-authored-by: Stephen Finucane <[email protected]>
1 parent ef86b06 commit 43ae645

File tree

4 files changed

+125
-45
lines changed

4 files changed

+125
-45
lines changed

README.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ documentation.
5353
5454
.. click:: module:parser
5555
:prog: hello-world
56-
:show-nested:
56+
:nested: full
5757
5858
Detailed information on the various options available is provided in the
5959
`documentation <https://sphinx-click.readthedocs.io>`_.

docs/usage.rst

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Once enabled, *sphinx-click* enables automatic documentation for
2020
2121
.. click:: module:parser
2222
:prog: hello-world
23-
:show-nested:
23+
:nested: full
2424
2525
The directive takes the import name of a *click* object as its sole
2626
argument. This should be a subclass of |click.core.BaseCommand|_, such as
@@ -35,12 +35,26 @@ Once enabled, *sphinx-click* enables automatic documentation for
3535

3636
The following options are optional:
3737

38-
``:show-nested:``
39-
Enable full documentation for sub-commands.
38+
``:nested:``
39+
Whether subcommands should also be shown. One of:
40+
41+
``full``
42+
List sub-commands with full documentation.
43+
44+
``short``
45+
List sub-commands with short documentation.
46+
47+
``none``
48+
Do not list sub-commands.
49+
50+
Defaults to ``short`` unless ``show-nested`` (deprecated) is set.
4051

4152
``:commands:``
4253
Document only listed commands.
4354

55+
``:show-nested:``
56+
This option is deprecated; use ``nested`` instead.
57+
4458
The generated documentation includes anchors for the generated commands,
4559
their options and their environment variables using the `Sphinx standard
4660
domain`_.
@@ -84,14 +98,28 @@ To document this, use the following:
8498
.. click:: hello_world:greet
8599
:prog: hello-world
86100
87-
If you wish to include full documentation for the subcommand, ``hello``, in the
88-
output, add the ``show-nested`` flag.
101+
By default, the subcommand, ``hello``, is listed but no documentation provided.
102+
If you wish to include full documentation for the subcommand in the output,
103+
configure the ``nested`` flag to ``full``.
104+
105+
.. code-block:: rst
106+
107+
.. click:: hello_world:greet
108+
:prog: hello-world
109+
:nested: full
110+
111+
.. note::
112+
113+
The ``nested`` flag replaces the deprecated ``show-nested`` flag.
114+
115+
Conversely, if you do not wish to list these subcommands or wish to handle them
116+
separately, configure the ``nested`` flag to ``none``.
89117

90118
.. code-block:: rst
91119
92120
.. click:: hello_world:greet
93121
:prog: hello-world
94-
:show-nested:
122+
:nested: none
95123
96124
You can also document only selected commands by using ``:commands:`` option.
97125

@@ -123,7 +151,7 @@ Modifying ``sys.path``
123151
----------------------
124152

125153
If the application or script you wish to document is not installed (i.e. you
126-
have not installed it with `pip` or run ``python setup.py``), then you may need
154+
have not installed it with *pip* or run ``python setup.py``), then you may need
127155
to modify ``sys.path``. For example, given the following application::
128156

129157
git
@@ -150,7 +178,7 @@ the application:
150178
151179
.. click:: git.git:cli
152180
:prog: git
153-
:show-nested:
181+
:nested: full
154182
155183
assuming the group or command in ``git.git`` is named ``cli``.
156184

sphinx_click/ext.py

Lines changed: 43 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import traceback
2+
import warnings
23

34
import click
45
from docutils import nodes
@@ -11,6 +12,10 @@
1112
LOG = logging.getLogger(__name__)
1213
CLICK_VERSION = tuple(int(x) for x in click.__version__.split('.')[0:2])
1314

15+
NESTED_FULL = 'full'
16+
NESTED_SHORT = 'short'
17+
NESTED_NONE = 'none'
18+
1419

1520
def _indent(text, level=1):
1621
prefix = ' ' * (4 * level)
@@ -263,7 +268,7 @@ def _filter_commands(ctx, commands=None):
263268
return [lookup[name] for name in names if name in lookup]
264269

265270

266-
def _format_command(ctx, show_nested, commands=None):
271+
def _format_command(ctx, nested, commands=None):
267272
"""Format the output of `click.Command`."""
268273
if CLICK_VERSION >= (7, 0) and ctx.command.hidden:
269274
return
@@ -318,7 +323,7 @@ def _format_command(ctx, show_nested, commands=None):
318323
yield line
319324

320325
# if we're nesting commands, we need to do this slightly differently
321-
if show_nested:
326+
if nested in (NESTED_FULL, NESTED_NONE):
322327
return
323328

324329
commands = _filter_commands(ctx, commands)
@@ -337,14 +342,29 @@ def _format_command(ctx, show_nested, commands=None):
337342
yield ''
338343

339344

345+
def nested(argument):
346+
values = (NESTED_FULL, NESTED_SHORT, NESTED_NONE)
347+
if not argument:
348+
return None
349+
350+
if argument not in values:
351+
raise ValueError(
352+
"%s is not a valid value for ':nested:'; allowed values: %s"
353+
% directives.format_values(values)
354+
)
355+
356+
return argument
357+
358+
340359
class ClickDirective(rst.Directive):
341360

342361
has_content = False
343362
required_arguments = 1
344363
option_spec = {
345364
'prog': directives.unchanged_required,
346-
'show-nested': directives.flag,
365+
'nested': nested,
347366
'commands': directives.unchanged,
367+
'show-nested': directives.flag,
348368
}
349369

350370
def _load_module(self, module_path):
@@ -387,17 +407,15 @@ def _load_module(self, module_path):
387407
)
388408
return parser
389409

390-
def _generate_nodes(
391-
self, name, command, parent=None, show_nested=False, commands=None
392-
):
410+
def _generate_nodes(self, name, command, parent, nested, commands=None):
393411
"""Generate the relevant Sphinx nodes.
394412
395413
Format a `click.Group` or `click.Command`.
396414
397415
:param name: Name of command, as used on the command line
398416
:param command: Instance of `click.Group` or `click.Command`
399417
:param parent: Instance of `click.Context`, or None
400-
:param show_nested: Whether subcommands should be included in output
418+
:param nested: The granularity of subcommand details.
401419
:param commands: Display only listed commands or skip the section if
402420
empty
403421
:returns: A list of nested docutil nodes
@@ -421,7 +439,7 @@ def _generate_nodes(
421439
source_name = ctx.command_path
422440
result = statemachine.ViewList()
423441

424-
lines = _format_command(ctx, show_nested, commands)
442+
lines = _format_command(ctx, nested, commands)
425443
for line in lines:
426444
LOG.debug(line)
427445
result.append(line, source_name)
@@ -430,12 +448,10 @@ def _generate_nodes(
430448

431449
# Subcommands
432450

433-
if show_nested:
451+
if nested == NESTED_FULL:
434452
commands = _filter_commands(ctx, commands)
435453
for command in commands:
436-
section.extend(
437-
self._generate_nodes(command.name, command, ctx, show_nested)
438-
)
454+
section.extend(self._generate_nodes(command.name, command, ctx, nested))
439455

440456
return [section]
441457

@@ -449,9 +465,23 @@ def run(self):
449465

450466
prog_name = self.options.get('prog')
451467
show_nested = 'show-nested' in self.options
468+
nested = self.options.get('nested')
469+
470+
if show_nested:
471+
if nested:
472+
raise self.error(
473+
"':nested:' and ':show-nested:' are mutually exclusive"
474+
)
475+
else:
476+
warnings.warn(
477+
"':show-nested:' is deprecated; use ':nested: full'",
478+
DeprecationWarning,
479+
)
480+
nested = NESTED_FULL if show_nested else NESTED_SHORT
481+
452482
commands = self.options.get('commands')
453483

454-
return self._generate_nodes(prog_name, command, None, show_nested, commands)
484+
return self._generate_nodes(prog_name, command, None, nested, commands)
455485

456486

457487
def setup(app):

0 commit comments

Comments
 (0)