]> git.ipfire.org Git - thirdparty/mkosi.git/commitdiff
Improve wrapping of long texts in --help
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 26 Apr 2022 12:52:07 +0000 (14:52 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 10 Jun 2022 08:34:17 +0000 (10:34 +0200)
The default formatter would wrap all text into a single paragraph,
which is rather hard to read in case when we have a list of options
and an explanation for each of the values. Let's add a custom formatter.

Also, never split option names or other words.

Part of output wrapped to the default 80 columns:
  --source-file-transfer-final METHOD
                        How to copy build sources to the final image:
                        'copy-all': normal file copy
                        'copy-git-cached': use git ls-files --cached, ignoring
                            any file that git itself ignores
                        'copy-git-others': use git ls-files --others, ignoring
                            any file that git itself ignores
                        'copy-git-more': use git ls-files --cached, ignoring
                            any file that git itself ignores, but include the
                            .git/ directory
                        (default: None)
  --source-resolve-symlinks [BOOL]
                        If true, symbolic links in the build sources are
                        followed and the file contents copied to the build
                        image. If false, they are left as symbolic links. Only
                        applies if --source-file-transfer-final is set to
                        'copy-all'.
                        (default: false)
  --source-resolve-symlinks-final [BOOL]
                        If true, symbolic links in the build sources are
                        followed and the file contents copied to the final
                        image. If false, they are left as symbolic links in
                        the final image. Only applies if
                        --source-file-transfer-final is set to 'copy-all'.
                        (default: false)
  --with-network [WITH_NETWORK]
                        Run build and postinst scripts with network access
                        (instead of private network)
  --settings PATH       Add in .nspawn settings file

mkosi/__init__.py

index 8f33751744cc2bceeed245b54cd283cf348ad448..0ed19f95b0a66969e2083f2af9bfbb7e83556394 100644 (file)
@@ -21,6 +21,7 @@ import glob
 import hashlib
 import http.server
 import importlib.resources
+import itertools
 import json
 import os
 import platform
@@ -32,6 +33,7 @@ import string
 import subprocess
 import sys
 import tempfile
+import textwrap
 import time
 import urllib.parse
 import urllib.request
@@ -5009,6 +5011,20 @@ class CustomHelpFormatter(argparse.HelpFormatter):
         args_string = self._format_args(action, default)
         return ", ".join(action.option_strings) + " " + args_string
 
+    def _split_lines(self, text: str, width: int) -> List[str]:
+        """Wraps text to width, each line separately.
+        If the first line of text ends in a colon, we assume that
+        this is a list of option descriptions, and subindent them.
+        Otherwise, the text is wrapped without indentation.
+        """
+        lines = text.splitlines()
+        subindent = '    ' if lines[0].endswith(':') else ''
+        return list(itertools.chain.from_iterable(
+            textwrap.wrap(line, width,
+                          break_long_words=False,
+                          break_on_hyphens=False,
+                          subsequent_indent=subindent)
+            for line in lines))
 
 class ArgumentParserMkosi(argparse.ArgumentParser):
     """ArgumentParser with support for mkosi.defaults file(s)
@@ -5644,9 +5660,9 @@ def create_parser() -> ArgumentParserMkosi:
         choices=[*list(SourceFileTransfer), None],
         metavar="METHOD",
         default=None,
-        help="Method used to copy build sources to the build image."
-        + "; ".join([f"'{k}': {v}" for k, v in SourceFileTransfer.doc().items()])
-        + " (default: copy-git-others if in a git repository, otherwise copy-all)",
+        help='\n'.join(('How to copy build sources to the build image:',
+                        *(f"'{k}': {v}" for k, v in SourceFileTransfer.doc().items()),
+                        '(default: copy-git-others if in a git repository, otherwise copy-all)')),
     )
     group.add_argument(
         "--source-file-transfer-final",
@@ -5654,25 +5670,30 @@ def create_parser() -> ArgumentParserMkosi:
         choices=[*list(SourceFileTransfer), None],
         metavar="METHOD",
         default=None,
-        help="Method used to copy build sources to the final image."
-        + "; ".join([f"'{k}': {v}" for k, v in SourceFileTransfer.doc().items() if k != SourceFileTransfer.mount])
-        + " (default: None)",
+        help='\n'.join(('How to copy build sources to the final image:',
+                        *(f"'{k}': {v}" for k, v in SourceFileTransfer.doc().items()
+                          if k != SourceFileTransfer.mount),
+                        '(default: None)')),
     )
     group.add_argument(
         "--source-resolve-symlinks",
         metavar="BOOL",
         action=BooleanAction,
-        help="If given, any symbolic links in the build sources are resolved and the file contents copied to the"
-        + " build image. If not given, they are left as symbolic links in the build image."
-        + " Only applies if --source-file-transfer is set to 'copy-all'. (default: keep as symbolic links)",
+        help=("If true, symbolic links in the build sources are followed and the "
+              "file contents copied to the build image. If false, they are left as "
+              "symbolic links. "
+              "Only applies if --source-file-transfer-final is set to 'copy-all'.\n"
+              "(default: false)"),
     )
     group.add_argument(
         "--source-resolve-symlinks-final",
         metavar="BOOL",
         action=BooleanAction,
-        help="If given, any symbolic links in the build sources are resolved and the file contents copied to the"
-        + " final image. If not given, they are left as symbolic links in the final image."
-        + " Only applies if --source-file-transfer-final is set to 'copy-all'. (default: keep as symbolic links)",
+        help=("If true, symbolic links in the build sources are followed and the "
+              "file contents copied to the final image. If false, they are left as "
+              "symbolic links in the final image. "
+              "Only applies if --source-file-transfer-final is set to 'copy-all'.\n"
+              "(default: false)"),
     )
     group.add_argument(
         "--with-network",
@@ -5820,8 +5841,8 @@ def create_parser() -> ArgumentParserMkosi:
         "--ephemeral",
         metavar="BOOL",
         action=BooleanAction,
-        help="If specified, the container/VM is run with a temporary snapshot of the output image that is "
-        "removed immediately when the container/VM terminates",
+        help=('If specified, the container/VM is run with a temporary snapshot of the output '
+              'image that is removed immediately when the container/VM terminates'),
     )
     group.add_argument(
         "--ssh",