Skip to content

Commit

Permalink
cli: Expose knobs for date, version
Browse files Browse the repository at this point in the history
Provide a way to override the date and version used in generated man
pages. This can be useful where you want to generate man pages before
actually releasing something and don't want to manually edit them.

Signed-off-by: Stephen Finucane <[email protected]>
  • Loading branch information
stephenfin committed Dec 10, 2024
1 parent fe80f37 commit 71e3910
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 8 deletions.
23 changes: 18 additions & 5 deletions click_man/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,17 @@ def get_short_help_str(command, limit=45):
return command.short_help or command.help and click.utils.make_default_short_help(command.help, limit) or ''


def generate_man_page(ctx, version=None):
def generate_man_page(ctx, version=None, date=None):
"""
Generate documentation for the given command.
:param click.Context ctx: the click context for the
cli application.
cli application.
:param str version: The version information to include in the man page.
:param str date: The date information to include in the man page.
:rtype: str
:returns: the generate man page from the given click Context.
:rtype: str
"""
# Create man page with the details from the given context
man_page = ManPage(ctx.command_path)
Expand All @@ -43,6 +45,10 @@ def generate_man_page(ctx, version=None):
man_page.description = ctx.command.help
man_page.synopsis = ' '.join(ctx.command.collect_usage_pieces(ctx))
man_page.options = [x.get_help_record(ctx) for x in ctx.command.params if isinstance(x, click.Option) and not getattr(x, 'hidden', False)]

if date:
man_page.date = date

commands = getattr(ctx.command, 'commands', None)
if commands:
man_page.commands = [
Expand All @@ -52,7 +58,9 @@ def generate_man_page(ctx, version=None):
return str(man_page)


def write_man_pages(name, cli, parent_ctx=None, version=None, target_dir=None):
def write_man_pages(
name, cli, parent_ctx=None, version=None, target_dir=None, date=None,
):
"""
Generate man page files recursively
for the given click cli function.
Expand All @@ -62,6 +70,7 @@ def write_man_pages(name, cli, parent_ctx=None, version=None, target_dir=None):
:param click.Context parent_ctx: the parent click context
:param str target_dir: the directory where the generated
man pages are stored.
:param date: the date to include in the header
"""
ctx = click.Context(cli, info_name=name, parent=parent_ctx)

Expand All @@ -80,4 +89,8 @@ def write_man_pages(name, cli, parent_ctx=None, version=None, target_dir=None):
if command.hidden:
# Do not write a man page for a hidden command
continue
write_man_pages(name, command, parent_ctx=ctx, version=version, target_dir=target_dir)

write_man_pages(
name, command, parent_ctx=ctx, version=version,
target_dir=target_dir, date=date,
)
21 changes: 18 additions & 3 deletions click_man/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
:license: MIT, see LICENSE for more details.
"""

from datetime import datetime
import os
import click
from pkg_resources import iter_entry_points, get_distribution

import click

from click_man.core import write_man_pages


Expand All @@ -22,9 +24,11 @@
type=click.Path(file_okay=False, dir_okay=True, resolve_path=True),
help='Target location for the man pages'
)
@click.option('--man-version', help='Version to use in generated man page(s)')
@click.option('--man-date', help='Date to use in generated man page(s)')
@click.version_option(get_distribution('click-man').version, '-V', '--version')
@click.argument('name')
def cli(target, name):
def cli(target, name, man_version, man_date):
"""
Generate man pages for the scripts defined in the ``console_scripts`` entry
point.
Expand All @@ -50,6 +54,17 @@ def cli(target, name):
except OSError:
pass

if not man_version:
man_version = entry_point.dist.version

if man_date:
try:
datetime.strptime(man_date, '%Y-%m-%d')
except ValueError:
raise click.ClickException(
'"{0}" is not a valid date.'.format(man_date)
)

click.echo('Load entry point {0}'.format(name))
cli = entry_point.resolve()

Expand Down Expand Up @@ -81,5 +96,5 @@ def cli(target, name):

click.echo('Generate man pages for {0} in {1}'.format(name, target))
write_man_pages(
name, cli, version=entry_point.dist.version, target_dir=target,
name, cli, version=man_version, target_dir=target, date=man_date,
)
33 changes: 33 additions & 0 deletions tests/test_shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,37 @@ def test_is_click_command(mock_entry_points, mock_echo, mock_write):
])
mock_write.assert_called_once_with(
'foo', fake_command, version=fake_version, target_dir=fake_target,
date=None,
)


@mock.patch('os.makedirs', new=mock.Mock())
@mock.patch.object(shell, 'write_man_pages')
@mock.patch.object(click, 'echo')
@mock.patch.object(shell, 'iter_entry_points')
def test_man_date_version(mock_entry_points, mock_echo, mock_write):
fake_target = os.path.join(os.getcwd(), 'man')
fake_command = click.Command(name='foo')
entry_point = mock.Mock()
entry_point.resolve.return_value = fake_command

mock_entry_points.return_value = iter([entry_point])

runner = CLIRunner()
result = runner.invoke(
shell.cli,
['foo', '--man-version', '3.2.1', '--man-date', '2020-01-01'],
)

assert result.exit_code == 0, result.output

mock_entry_points.assert_called_once_with('console_scripts', name='foo')
entry_point.dist.version.assert_not_called()
mock_echo.assert_has_calls([
mock.call('Load entry point foo'),
mock.call('Generate man pages for foo in %s' % fake_target),
])
mock_write.assert_called_once_with(
'foo', fake_command, version='3.2.1', target_dir=fake_target,
date='2020-01-01',
)

0 comments on commit 71e3910

Please sign in to comment.