Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,6 @@ ChangeLog

# Intellij
.idea

# VSCode
.vscode
4 changes: 4 additions & 0 deletions releasenotes/notes/print-usage-c83518ec412eca7c.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
features:
- |
Add a "Usage" label (rubric) before printing the command's usage format.
11 changes: 8 additions & 3 deletions sphinx_click/ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,15 +358,20 @@ def _format_command(

# usage

for line in _format_usage(ctx):
lines = list(_format_usage(ctx))
if lines:
# we use rubric to provide some separation without exploding the table
# of contents
yield '.. rubric:: Usage'
yield ''

for line in lines:
yield line

# options

lines = list(_format_options(ctx))
if lines:
# we use rubric to provide some separation without exploding the table
# of contents
yield '.. rubric:: Options'
yield ''

Expand Down
59 changes: 37 additions & 22 deletions tests/test_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ def test_basics(make_app, rootdir):
# section:
# title:
# paragraph:
# rubric: (Usage)
# literal_block:
# rubric:
# rubric: (Commands)
# index:
# desc:
# desc_signature:
Expand All @@ -38,16 +39,18 @@ def test_basics(make_app, rootdir):
assert section[0].astext() == 'greet'
assert isinstance(section[1], nodes.paragraph)
assert section[1].astext() == 'A sample command group.'
assert isinstance(section[2], nodes.literal_block)
assert isinstance(section[2], nodes.rubric)
assert section[2].astext() == 'Usage'
assert isinstance(section[3], nodes.literal_block)

assert isinstance(section[3], nodes.rubric)
assert section[3].astext() == 'Commands'
assert isinstance(section[4], sphinx_nodes.index)
assert isinstance(section[5], sphinx_nodes.desc)
assert section[5].astext() == 'hello\n\nGreet a user.'
assert isinstance(section[6], sphinx_nodes.index)
assert isinstance(section[7], sphinx_nodes.desc)
assert section[7].astext() == 'world\n\nGreet the world.'
assert isinstance(section[4], nodes.rubric)
assert section[4].astext() == 'Commands'
assert isinstance(section[5], sphinx_nodes.index)
assert isinstance(section[6], sphinx_nodes.desc)
assert section[6].astext() == 'hello\n\nGreet a user.'
assert isinstance(section[7], sphinx_nodes.index)
assert isinstance(section[8], sphinx_nodes.desc)
assert section[8].astext() == 'world\n\nGreet the world.'


def test_commands(make_app, rootdir):
Expand All @@ -66,8 +69,9 @@ def test_commands(make_app, rootdir):
# section:
# title:
# paragraph:
# rubric: (Usage)
# literal_block:
# rubric:
# rubric: (Commands)
# index:
# desc:
# desc_signature:
Expand All @@ -80,14 +84,16 @@ def test_commands(make_app, rootdir):
assert section[0].astext() == 'greet'
assert isinstance(section[1], nodes.paragraph)
assert section[1].astext() == 'A sample command group.'
assert isinstance(section[2], nodes.literal_block)
assert isinstance(section[2], nodes.rubric)
assert section[2].astext() == 'Usage'
assert isinstance(section[3], nodes.literal_block)

# we should only show a single command, 'world'
assert isinstance(section[3], nodes.rubric)
assert section[3].astext() == 'Commands'
assert isinstance(section[4], sphinx_nodes.index)
assert isinstance(section[5], sphinx_nodes.desc)
assert section[5].astext() == 'world\n\nGreet the world.'
assert isinstance(section[4], nodes.rubric)
assert section[4].astext() == 'Commands'
assert isinstance(section[5], sphinx_nodes.index)
assert isinstance(section[6], sphinx_nodes.desc)
assert section[6].astext() == 'world\n\nGreet the world.'


def test_nested_full(make_app, rootdir):
Expand All @@ -106,15 +112,18 @@ def test_nested_full(make_app, rootdir):
# section:
# title:
# paragraph:
# rubric: (Usage)
# literal_block:
# section:
# title
# paragraph
# rubric: (Usage)
# literal_block
# ...
# section:
# title
# paragraph
# rubric: (Usage)
# literal_block

section = content[0][1]
Expand All @@ -124,23 +133,29 @@ def test_nested_full(make_app, rootdir):
assert section[0].astext() == 'greet'
assert isinstance(section[1], nodes.paragraph)
assert section[1].astext() == 'A sample command group.'
assert isinstance(section[2], nodes.literal_block)
assert isinstance(section[2], nodes.rubric)
assert section[2].astext() == 'Usage'
assert isinstance(section[3], nodes.literal_block)

subsection_a = section[3]
subsection_a = section[4]
assert isinstance(subsection_a, nodes.section)

assert isinstance(subsection_a[0], nodes.title)
assert subsection_a[0].astext() == 'hello'
assert isinstance(subsection_a[1], nodes.paragraph)
assert subsection_a[1].astext() == 'Greet a user.'
assert isinstance(subsection_a[2], nodes.literal_block)
assert isinstance(subsection_a[2], nodes.rubric)
assert subsection_a[2].astext() == 'Usage'
assert isinstance(subsection_a[3], nodes.literal_block)
# we don't need to verify the rest of this: that's done elsewhere

subsection_b = section[4]
subsection_b = section[5]
assert isinstance(subsection_b, nodes.section)

assert isinstance(subsection_b[0], nodes.title)
assert subsection_b[0].astext() == 'world'
assert isinstance(subsection_b[1], nodes.paragraph)
assert subsection_b[1].astext() == 'Greet the world.'
assert isinstance(subsection_b[2], nodes.literal_block)
assert isinstance(subsection_b[2], nodes.rubric)
assert subsection_b[2].astext() == 'Usage'
assert isinstance(subsection_b[3], nodes.literal_block)
44 changes: 44 additions & 0 deletions tests/test_formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ def foobar():
A sample command.

.. program:: foobar
.. rubric:: Usage

.. code-block:: shell

foobar [OPTIONS]
Expand Down Expand Up @@ -79,6 +81,8 @@ def foobar(bar):
A sample command.

.. program:: foobar
.. rubric:: Usage

.. code-block:: shell

foobar [OPTIONS] ARG
Expand Down Expand Up @@ -152,6 +156,8 @@ def foobar(bar):
A sample command.

.. program:: foobar
.. rubric:: Usage

.. code-block:: shell

foobar [OPTIONS]
Expand Down Expand Up @@ -197,6 +203,8 @@ def foobar(bar):
A sample command.

.. program:: foobar
.. rubric:: Usage

.. code-block:: shell

foobar [OPTIONS] ARG ARG_NO_HELP
Expand Down Expand Up @@ -261,6 +269,8 @@ def foobar(bar):
A sample command.

.. program:: foobar
.. rubric:: Usage

.. code-block:: shell

foobar [OPTIONS]
Expand Down Expand Up @@ -313,6 +323,8 @@ def foobar():
A sample command.

.. program:: foobar
.. rubric:: Usage

.. code-block:: shell

foobar [OPTIONS]
Expand Down Expand Up @@ -374,6 +386,8 @@ def hello(name):
my_cli hello --name "Jack"

.. program:: hello
.. rubric:: Usage

.. code-block:: shell

hello [OPTIONS]
Expand Down Expand Up @@ -428,6 +442,8 @@ def foobar():
dash of bold and even some underlined words.

.. program:: foobar
.. rubric:: Usage

.. code-block:: shell

foobar [OPTIONS]
Expand Down Expand Up @@ -495,6 +511,8 @@ def cli():
:param click.core.Context ctx: Click context.

.. program:: cli
.. rubric:: Usage

.. code-block:: shell

cli [OPTIONS]
Expand Down Expand Up @@ -564,6 +582,8 @@ def cli():
that will be rewrapped again.

.. program:: cli
.. rubric:: Usage

.. code-block:: shell

cli [OPTIONS]
Expand Down Expand Up @@ -621,6 +641,8 @@ def cli():
A sample command group.

.. program:: cli
.. rubric:: Usage

.. code-block:: shell

cli [OPTIONS] COMMAND [ARGS]...
Expand Down Expand Up @@ -652,6 +674,8 @@ def cli():
A sample command group.

.. program:: cli
.. rubric:: Usage

.. code-block:: shell

cli [OPTIONS] ARG COMMAND [ARGS]...
Expand Down Expand Up @@ -724,6 +748,8 @@ def test_nested_short(self):
A sample command group.

.. program:: cli
.. rubric:: Usage

.. code-block:: shell

cli [OPTIONS] COMMAND [ARGS]...
Expand Down Expand Up @@ -753,6 +779,8 @@ def test_nested_full(self):
A sample command group.

.. program:: cli
.. rubric:: Usage

.. code-block:: shell

cli [OPTIONS] COMMAND [ARGS]...
Expand All @@ -776,6 +804,8 @@ def test_nested_none(self):
A sample command group.

.. program:: cli
.. rubric:: Usage

.. code-block:: shell

cli [OPTIONS] COMMAND [ARGS]...
Expand Down Expand Up @@ -818,6 +848,8 @@ def test_no_commands(self):
A sample command group.

.. program:: cli
.. rubric:: Usage

.. code-block:: shell

cli [OPTIONS] COMMAND [ARGS]...
Expand All @@ -840,6 +872,8 @@ def test_order_of_commands(self):
A sample command group.

.. program:: cli
.. rubric:: Usage

.. code-block:: shell

cli [OPTIONS] COMMAND [ARGS]...
Expand Down Expand Up @@ -902,6 +936,8 @@ def get_command(self, ctx, name):
A sample custom multicommand.

.. program:: cli
.. rubric:: Usage

.. code-block:: shell

cli [OPTIONS] COMMAND [ARGS]...
Expand Down Expand Up @@ -960,6 +996,8 @@ def get_command(self, ctx, name):
A sample custom multicommand.

.. program:: cli
.. rubric:: Usage

.. code-block:: shell

cli [OPTIONS] COMMAND [ARGS]...
Expand Down Expand Up @@ -1017,6 +1055,8 @@ def world():
A simple CommandCollection.

.. program:: cli
.. rubric:: Usage

.. code-block:: shell

cli [OPTIONS] COMMAND [ARGS]...
Expand All @@ -1033,6 +1073,8 @@ def world():
A simple CommandCollection.

.. program:: cli
.. rubric:: Usage

.. code-block:: shell

cli [OPTIONS] COMMAND [ARGS]...
Expand Down Expand Up @@ -1083,6 +1125,8 @@ def cli_with_auto_envvars():
A simple CLI with auto-env vars .

.. program:: cli
.. rubric:: Usage

.. code-block:: shell

cli [OPTIONS]
Expand Down