Skip to content

Commit

Permalink
Add support for post-processing nodes
Browse files Browse the repository at this point in the history
By providing the option ":post-process: module.path:funcion", the user
can direct the directive to run the provided function on the command and
its generated node for each command processed. This allows for full
per-command customization of the output.
  • Loading branch information
TomerGodinger authored and stephenfin committed Jun 28, 2022
1 parent 54d5c11 commit 2701ed4
Showing 1 changed file with 36 additions and 13 deletions.
49 changes: 36 additions & 13 deletions sphinx_click/ext.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,9 +464,10 @@ class ClickDirective(rst.Directive):
'commands': directives.unchanged,
'show-nested': directives.flag,
'hide-header': directives.flag,
'post-process': directives.unchanged_required,
}

def _load_module(self, module_path: str) -> ty.Union[click.Command, click.Group]:
def _load_module(self, module_path: str) -> ty.Any:
"""Load the module."""

try:
Expand Down Expand Up @@ -494,14 +495,7 @@ def _load_module(self, module_path: str) -> ty.Union[click.Command, click.Group]
'Module "{}" has no attribute "{}"'.format(module_name, attr_name)
)

parser = getattr(mod, attr_name)

if not isinstance(parser, (click.Command, click.Group)):
raise self.error(
'"{}" of type "{}" is not click.Command or click.Group.'
'"click.BaseCommand"'.format(type(parser), module_path)
)
return parser
return getattr(mod, attr_name)

def _generate_nodes(
self,
Expand Down Expand Up @@ -572,13 +566,13 @@ def _generate_nodes(
)
)
else:
commands = _filter_commands(ctx, commands)
for command in commands:
# We use the term "subcommand" here but these can be main commands as well
for subcommand in _filter_commands(ctx, commands):
parent = ctx if not semantic_group else ctx.parent
subcommand_nodes.extend(
self._generate_nodes(
command.name,
command,
subcommand.name,
subcommand,
parent=parent,
nested=nested,
hide_header=False, # Hiding the header should not propagate to children
Expand Down Expand Up @@ -610,13 +604,37 @@ def _generate_nodes(
section.append(node)
final_nodes = [section]

self._post_process(command, final_nodes)

return final_nodes

def _post_process(
self,
command: click.Command,
nodes: ty.List[nodes.section],
) -> None:
"""Runs the post-processor, if any, for the given command and nodes.
If a post-processor for the created nodes was set via the
:post-process: option, every set of nodes generated by the directive is
run through the post-processor.
This allows for per-command customization of the output.
"""
if self.postprocessor:
self.postprocessor(command, nodes)

def run(self) -> ty.Iterable[nodes.section]:
self.env = self.state.document.settings.env

command = self._load_module(self.arguments[0])

if not isinstance(command, (click.Command, click.Group)):
raise self.error(
'"{}" of type "{}" is not click.Command or click.Group.'
'"click.BaseCommand"'.format(type(command), self.arguments[0])
)

if 'prog' not in self.options:
raise self.error(':prog: must be specified')

Expand All @@ -625,6 +643,11 @@ def run(self) -> ty.Iterable[nodes.section]:
nested = self.options.get('nested')
hide_header = 'hide-header' in self.options

self.postprocessor = None
if 'post-process' in self.options:
postprocessor_module_path = self.options.get('post-process')
self.postprocessor = self._load_module(postprocessor_module_path)

if show_nested:
if nested:
raise self.error(
Expand Down

0 comments on commit 2701ed4

Please sign in to comment.