]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
help-util: add helpers for generating uniform --help texts
authorLennart Poettering <lennart@amutable.com>
Thu, 23 Apr 2026 22:09:00 +0000 (00:09 +0200)
committerLennart Poettering <lennart@amutable.com>
Fri, 24 Apr 2026 13:04:16 +0000 (15:04 +0200)
Let's introduce some helpers for generating uniform --help texts with
some minimal ANSI styling.

This shortens the help() functions generally, and allows us to change
the style at a single, central place.

This mostly just follows our current styling for --help, but it makes
two updates to it:

1. The command line summary at the very top of the --help text is now
   prefixes with a grey ">" character to indicate it's a command line.

2. The human language introductionary description/abstract right after
   that command line is set in italics, to emphasize it's not dry,
   technical, structural information, but more human friendly prose.

src/shared/help-util.c [new file with mode: 0644]
src/shared/help-util.h [new file with mode: 0644]
src/shared/meson.build

diff --git a/src/shared/help-util.c b/src/shared/help-util.c
new file mode 100644 (file)
index 0000000..b88da2d
--- /dev/null
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "alloc-util.h"
+#include "ansi-color.h"
+#include "help-util.h"
+#include "pretty-print.h"
+
+/* These are helpers for putting together --help texts in a uniform way with a common output style. Each
+ * function generates a separate part of the --help text:
+ *
+ *   1. help_cmdline() outputs a brief summary of the command line syntax. (used at least once, in some cases
+ *      multiple times.) This generally comes first in the output.
+ *
+ *   2. help_abstract() outputs a brief prose abstract of the command, should carry a single line of text
+ *      that gives the user a hint what this tool does. Use only once, right after the last help_cmdline().
+ *
+ *   3. help_section() can be used to format multiple sections of the --help text. It should be used at least
+ *      once for an "Options:" section, but can be used more than once, for programs with many
+ *      options/verbs. The first invocation should come right after help_abstract().
+ *
+ *   4. Finally, help_man_page_reference() adds a final line linking the man page of the tool. This should be
+ *      used only once, and terminates the --help text.
+ *
+ *   Switches and verbs documentation should be inserted after each help_section(). For that ideally use
+ *   options.[ch] APIs. */
+
+void help_cmdline(const char *arguments) {
+        assert(arguments);
+
+        printf("%s>%s %s %s\n",
+               ansi_grey(),
+               ansi_normal(),
+               program_invocation_short_name,
+               arguments);
+}
+
+void help_abstract(const char *text) {
+        assert(text);
+
+        printf("\n%s%s%s%s\n",
+               ansi_highlight(),
+               ansi_add_italics(),
+               text,
+               ansi_normal());
+}
+
+void help_section(const char *title) {
+        assert(title);
+
+        printf("\n%s%s%s\n",
+               ansi_underline(),
+               title,
+               ansi_normal());
+}
+
+void help_man_page_reference(const char *page, const char *section) {
+        assert(page);
+        assert(section);
+
+        /* Displaying --help texts generally should not fail, hence let's fall back to a simple string in
+         * case of OOM. */
+        _cleanup_free_ char *link = NULL;
+        if (terminal_urlify_man(page, section, &link) < 0)
+                printf("\nSee the %s(%s) man page for details.\n", page, section);
+        else
+                printf("\nSee the %s for details.\n", link);
+}
diff --git a/src/shared/help-util.h b/src/shared/help-util.h
new file mode 100644 (file)
index 0000000..3804872
--- /dev/null
@@ -0,0 +1,10 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+#pragma once
+
+void help_cmdline(const char *arguments);
+
+void help_abstract(const char *text);
+
+void help_section(const char *title);
+
+void help_man_page_reference(const char *page, const char *section);
index 741dbb60a451a086b570eed67e74c314558d168d..7cae1ff23e2e3ea9cfc494d678b9fcb7a059c7f0 100644 (file)
@@ -94,6 +94,7 @@ shared_sources = files(
         'gnutls-util.c',
         'gpt.c',
         'group-record.c',
+        'help-util.c',
         'hibernate-util.c',
         'hostname-setup.c',
         'hwdb-util.c',