about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNguyễn Gia Phong <cnx@loang.net>2025-06-18 16:29:13 +0900
committerNguyễn Gia Phong <cnx@loang.net>2025-06-18 16:29:13 +0900
commit2ad9177830e41802b673d1fe513bca883c5e496b (patch)
tree10c364208340ae5404b46e06efe932e3649735f9
parent63f17a58145b827a56c4963ad306157cf2dff887 (diff)
downloadscadere-2ad9177830e41802b673d1fe513bca883c5e496b.tar.gz
Follow help2man's recommendations
* Use argv[0] as help text's prog
* End help text with bug report instruction
* Include copyright and authorship in version text
-rw-r--r--doc/Makefile7
-rw-r--r--doc/common.h2m12
-rw-r--r--src/scadere/__init__.py17
-rw-r--r--src/scadere/check.py9
-rw-r--r--src/scadere/listen.py10
-rw-r--r--tst/test_help.py8
6 files changed, 34 insertions, 29 deletions
diff --git a/doc/Makefile b/doc/Makefile
index 47e8669..ed6b571 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -23,16 +23,15 @@ PREFIX ?= /usr/local
 BINDIR ::= $(DESTDIR)$(PREFIX)/bin
 MANDIR ::= $(DESTDIR)$(PREFIX)/share/man
 MAN1 ::= scadere-check.1 scadere-listen.1
-MAN1FLAGS ::= -s 1 --source=Scadere --locale=en_US.UTF-8\
-	--include=common.h2m --no-info
+MAN1FLAGS ::= -s 1 --source=Scadere --locale=en_US.UTF-8 --no-info
 
 all: $(MAN1)
 
-scadere-check.1: $(BINDIR)/scadere-check check.h2m common.h2m
+scadere-check.1: $(BINDIR)/scadere-check check.h2m
 	help2man --name='TLS certificate expiration checker'\
 		$(MAN1FLAGS) --include=check.h2m --output=$@ $<
 
-scadere-listen.1: $(BINDIR)/scadere-listen listen.h2m common.h2m
+scadere-listen.1: $(BINDIR)/scadere-listen listen.h2m
 	help2man --name='Atom feed server to remind of TLS certificate renewal'\
 		$(MAN1FLAGS) --include=listen.h2m --output=$@ $<
 
diff --git a/doc/common.h2m b/doc/common.h2m
deleted file mode 100644
index 4ec20c3..0000000
--- a/doc/common.h2m
+++ /dev/null
@@ -1,12 +0,0 @@
-[author]
-Written by Nguyễn Gia Phong.
-
-[reporting bugs]
-Issues should be reported to <chung@loa.loang.net>.
-
-[copyright]
-This is free software: you are can redistribute and/or modify it
-under the terms of the GNU Affero General Public License version 3 or later
-<https://gnu.org/licenses/agpl>.
-
-There is NO WARRANTY, to the extent permitted by law.
diff --git a/src/scadere/__init__.py b/src/scadere/__init__.py
index f2b41bd..bd67de9 100644
--- a/src/scadere/__init__.py
+++ b/src/scadere/__init__.py
@@ -18,7 +18,8 @@
 
 from argparse import HelpFormatter, ONE_OR_MORE
 
-__all__ = ['__version__', 'GNUHelpFormatter', 'NetLoc', 'format_examples']
+__all__ = ['__version__', 'GNUHelpFormatter', 'NetLoc',
+           'format_epilog', 'format_version']
 __version__ = '0.1.0'
 
 
@@ -92,10 +93,22 @@ class NetLoc:
         return hostname, int(port)  # ValueError to be handled by argparse
 
 
-def format_examples(examples):
+def format_epilog(examples):
     """Format example commands and their description ."""
     lines = ['Examples:']
     for example, description in examples:
         lines.append(EXAMPLE_PREFIX+example)
         lines.append(EXAMPLE_DESCRIPTION_PREFIX+description)
+    lines.append('\nReport bugs to <chung@loa.loang.net>.')
     return '\n'.join(lines)
+
+
+def format_version(prog, copyright_years, authors):
+    """Format version information."""
+    return (f'{prog} {__version__}\n\n'
+            f'Copyright (C) {copyright_years} {authors}.\n\n'
+            'This is free software: you are can redistribute and/or modify it'
+            ' under the terms of the GNU Affero General Public License'
+            ' version 3 or later <https://gnu.org/licenses/agpl>.\n\n'
+            'There is NO WARRANTY, to the extent permitted by law.\n\n'
+            f'Written by {authors}.')
diff --git a/src/scadere/check.py b/src/scadere/check.py
index 80bee5f..bc5d3f5 100644
--- a/src/scadere/check.py
+++ b/src/scadere/check.py
@@ -27,7 +27,7 @@ from sys import argv, stderr, stdout
 from unicodedata import category as unicode_category
 from uuid import uuid4
 
-from . import __version__, GNUHelpFormatter, NetLoc, format_examples
+from . import GNUHelpFormatter, NetLoc, format_epilog, format_version
 
 __all__ = ['main']
 
@@ -94,7 +94,7 @@ def check(netlocs, after, output, fake_ca=None):
                       base64_from_str(ca), file=output)
 
 
-def main(prog='scadere-check', arguments=argv[1:]):
+def main(prog=argv[0], arguments=argv[1:]):
     """Run TLS checker."""
     desc = ('Check TLS certificate expiration of HOST,'
             ' where PORT defaults to 443.\n\n'
@@ -107,10 +107,11 @@ def main(prog='scadere-check', arguments=argv[1:]):
                   ' then write the result to /var/lib/scadere/certificates.'))]
 
     parser = ArgumentParser(prog=prog, allow_abbrev=False, description=desc,
-                            epilog=format_examples(examples),
+                            epilog=format_epilog(examples),
                             formatter_class=GNUHelpFormatter)
     parser.add_argument('-v', '--version', action='version',
-                        version=f'%(prog)s {__version__}')
+                        version=format_version('scadere-check',
+                                               '2025', 'Nguyễn Gia Phong'))
     parser.add_argument('netloc', metavar='HOST[:PORT]',
                         nargs='+', type=NetLoc(443))
     parser.add_argument('-d', '--days', type=float, default=7,
diff --git a/src/scadere/listen.py b/src/scadere/listen.py
index 03f5c96..824a566 100644
--- a/src/scadere/listen.py
+++ b/src/scadere/listen.py
@@ -32,7 +32,8 @@ from xml.etree.ElementTree import (Element as xml_element,
                                    indent, tostring as string_from_xml)
 from sys import argv
 
-from . import __version__, GNUHelpFormatter, NetLoc, format_examples
+from . import (__version__, GNUHelpFormatter, NetLoc,
+               format_epilog, format_version)
 from .check import base64_from_str
 
 __all__ = ['main']
@@ -315,7 +316,7 @@ def with_trailing_slash(base_url):
     return base_url if base_url.endswith('/') else f'{base_url}/'
 
 
-def main(prog='scadere-listen', arguments=argv[1:]):
+def main(prog=argv[0], arguments=argv[1:]):
     """Launch server."""
     desc = ('Serve at URL Atom feeds for TLS certificate renewal reminder.'
             '  It is possible for clients to filter domains'
@@ -337,10 +338,11 @@ def main(prog='scadere-listen', arguments=argv[1:]):
                   ' its subdomains, and domains under the TLD NET'))]
 
     parser = ArgumentParser(prog=prog, allow_abbrev=False, description=desc,
-                            epilog=format_examples(examples),
+                            epilog=format_epilog(examples),
                             formatter_class=GNUHelpFormatter)
     parser.add_argument('-v', '--version', action='version',
-                        version=f'%(prog)s {__version__}')
+                        version=format_version('scadere-listen',
+                                               '2025', 'Nguyễn Gia Phong'))
     parser.add_argument('-t', '--title', help='title of Atom feeds')
     parser.add_argument('certs', metavar='PATH', type=Path)
     parser.add_argument('base_url', metavar='URL', type=with_trailing_slash)
diff --git a/tst/test_help.py b/tst/test_help.py
index 2a6c06a..630fff1 100644
--- a/tst/test_help.py
+++ b/tst/test_help.py
@@ -59,9 +59,11 @@ def test_long_option(help_string, short, long, metavar):
 
 @mark.parametrize('help_string', [check, listen], indirect=True)
 def test_examples(help_string):
-    index = help_string.find('\n\nExamples:\n')
-    assert index >= 0
-    lines = help_string[index:].removeprefix('\n\nExamples:\n').splitlines()
+    epilog_index = help_string.find('\n\nExamples:\n')
+    assert epilog_index >= 0
+    epilog = help_string[epilog_index:].removeprefix('\n\n')
+    examples = epilog[:epilog.find('\n\n')]
+    lines = examples.removeprefix('Examples:\n').splitlines()
 
     assert EXAMPLE_DESCRIPTION_PREFIX.startswith(EXAMPLE_PREFIX)
     assert not lines[0].startswith(EXAMPLE_DESCRIPTION_PREFIX)