Skip to content

Commit

Permalink
feat: add documentation link in help messages
Browse files Browse the repository at this point in the history
Signed-off-by: Callahan Kovacs <callahankovacs@gmail.com>
  • Loading branch information
mr-cal committed Oct 30, 2024
1 parent 1bdb2b5 commit 3c5ff52
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 34 deletions.
7 changes: 5 additions & 2 deletions craft_cli/dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -209,19 +209,22 @@ class Dispatcher:
:param extra_global_args: other automatic global arguments than the ones
provided automatically
:param default_command: the command to run if none was specified in the command line
:param docs_base_url: The base address of the documentation, for help messages.
"""

def __init__(
def __init__( # noqa: PLR0913 (too-many-arguments)
self,
appname: str,
commands_groups: list[CommandGroup],
*,
summary: str = "",
extra_global_args: list[GlobalArgument] | None = None,
default_command: type[BaseCommand] | None = None,
docs_base_url: str | None = None,
) -> None:
self._default_command = default_command
self._help_builder = HelpBuilder(appname, summary, commands_groups)
self._docs_base_url = docs_base_url
self._help_builder = HelpBuilder(appname, summary, commands_groups, docs_base_url)

self.global_arguments = _DEFAULT_GLOBAL_ARGS[:]
if extra_global_args is not None:
Expand Down
62 changes: 46 additions & 16 deletions craft_cli/helptexts.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,25 @@ class HelpBuilder:
"""Produce the different help texts."""

def __init__(
self, appname: str, general_summary: str, command_groups: list[CommandGroup]
self,
appname: str,
general_summary: str,
command_groups: list[CommandGroup],
docs_base_url: str | None = None,
) -> None:
"""Initialize the help builder.
:param appname: The name of the application.
:param general_summary: A summary of the application.
:param command_groups: The CommandGroups for the application.
:param docs_base_url: The base URL for the documentation.
"""
self.appname = appname
self.general_summary = general_summary
self.command_groups = command_groups
self._docs_base_url = docs_base_url
if docs_base_url and docs_base_url.endswith("/"):
self._docs_base_url = docs_base_url[:-1]

def get_usage_message(self, error_message: str, command: str = "") -> str:
"""Build a usage and error message.
Expand Down Expand Up @@ -156,7 +170,7 @@ def get_full_help(self, global_options: list[tuple[str, str]]) -> str:
- summary
- common commands listed and described shortly
- all commands grouped, just listed
- more help
- more help and documentation
"""
textblocks = []

Expand Down Expand Up @@ -207,11 +221,17 @@ def get_full_help(self, global_options: list[tuple[str, str]]) -> str:
textwrap.dedent(
f"""
For more information about a command, run '{self.appname} help <command>'.
For a summary of all commands, run '{self.appname} help --all'.
"""
For a summary of all commands, run '{self.appname} help --all'."""
)
)

# append documentation links to block for more help
if self._docs_base_url:
textblocks[-1] += (
f"\nFor more information about {self.appname}, "
f"check out: {self._docs_base_url}"
)

# join all stripped blocks, leaving ONE empty blank line between
return "\n\n".join(block.strip() for block in textblocks) + "\n"

Expand All @@ -228,6 +248,7 @@ def get_detailed_help(self, global_options: list[tuple[str, str]]) -> str:
- global options
- all commands shown with description, grouped
- more help
- more help and documentation
"""
textblocks = []

Expand Down Expand Up @@ -264,18 +285,24 @@ def get_detailed_help(self, global_options: list[tuple[str, str]]) -> str:
textblocks.append(
textwrap.dedent(
f"""
For more information about a specific command, run '{self.appname} help <command>'.
"""
For more information about a specific command, run '{self.appname} help <command>'."""
)
)

# append documentation links to block for more help
if self._docs_base_url:
textblocks[-1] += (
f"\nFor more information about {self.appname}, "
f"check out: {self._docs_base_url}"
)

# join all stripped blocks, leaving ONE empty blank line between
return "\n\n".join(block.strip() for block in textblocks) + "\n"

def _build_plain_command_help(
self,
command: BaseCommand,
usage: str,
overview: str,
parameters: list[tuple[str, str]],
options: list[tuple[str, str]],
other_command_names: list[str],
Expand All @@ -289,7 +316,7 @@ def _build_plain_command_help(
- positional arguments (only if parameters are not empty)
- options
- other related commands
- footer
- help for all commands and documentation
"""
textblocks = []

Expand All @@ -302,7 +329,7 @@ def _build_plain_command_help(
)
)

overview = textwrap.indent(overview, " ")
overview = textwrap.indent(command.overview, " ")
textblocks.append(f"Summary:{overview}")

# column alignment is dictated by longest options title
Expand All @@ -326,19 +353,23 @@ def _build_plain_command_help(
see_also_block.extend((" " + name) for name in sorted(other_command_names))
textblocks.append("\n".join(see_also_block))

# footer
# help for all commands
textblocks.append(
f"""
For a summary of all commands, run '{self.appname} help --all'.
"""
For a summary of all commands, run '{self.appname} help --all'."""
)

# documentation link
if self._docs_base_url:
command_url = f"{self._docs_base_url}/reference/commands/{command.name}"
textblocks[-1] += f"\nFor more information, check out: {command_url}"

return textblocks

def _build_markdown_command_help(
self,
command: BaseCommand,
usage: str,
overview: str,
parameters: list[tuple[str, str]],
options: list[tuple[str, str]],
other_command_names: list[str],
Expand All @@ -352,7 +383,6 @@ def _build_markdown_command_help(
- positional arguments (only if parameters are not empty)
- options
- other related commands
- footer
"""
textblocks = []

Expand All @@ -367,7 +397,7 @@ def _build_markdown_command_help(
)
)

overview = process_overview_for_markdown(overview)
overview = process_overview_for_markdown(command.overview)
textblocks.append(f"## Summary:\n\n{overview}")

if parameters:
Expand Down Expand Up @@ -444,7 +474,7 @@ def get_command_help(
builder = self._build_markdown_command_help
else:
builder = self._build_plain_command_help
textblocks = builder(usage, command.overview, parameters, options, other_command_names)
textblocks = builder(command, usage, parameters, options, other_command_names)

# join all stripped blocks, leaving ONE empty blank line between
return "\n\n".join(block.strip() for block in textblocks) + "\n"
9 changes: 7 additions & 2 deletions tests/unit/test_dispatcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,17 @@
# --- Tests for the Dispatcher


def test_dispatcher_help_init():
@pytest.mark.parametrize("docs_base_url", [None, "www.craft-app.com/docs/3.14159"])
def test_dispatcher_help_init(docs_base_url):
"""Init the help infrastructure properly."""
groups = [CommandGroup("title", [create_command("somecommand")])]
dispatcher = Dispatcher("test-appname", groups, summary="test summary")
dispatcher = Dispatcher(
"test-appname", groups, summary="test summary", docs_base_url=docs_base_url
)

assert dispatcher._help_builder.appname == "test-appname"
assert dispatcher._help_builder.general_summary == "test summary"
assert dispatcher._help_builder._docs_base_url == docs_base_url


def test_dispatcher_pre_parsing():
Expand Down
Loading

0 comments on commit 3c5ff52

Please sign in to comment.