]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemctl: link to all non-man-page files in help
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 8 Sep 2023 15:02:57 +0000 (17:02 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 21 Sep 2023 16:09:48 +0000 (18:09 +0200)
For file:// links, we urlify the link so that the user can click and either
open the file in a editor or some viewer. The detection is chosen via some
mechanism implemented by the terminal emulator. This seems too DTRT for text
files and PDFs, which should cover the majority of realistic cases. If the file
is not viable, the terminal emulator will say
  "Could not open file://…. No application is registered to view this file type."
or similar.

For all other links, which are primarily http:// and https://, we just show the
link, letting the terminal handle the hyperlinking. The user can then ctrl-click
and open the file it their browser. If we tried to open the files automatically,
we'd would need to open many pages, and we'd need to figure out what browser to
use, etc. When the user picks whether to open the file, this leads to a nicer
user experience.

Man pages are separated by an empty line from preceding in and following output.
In my testing, this makes the output easier to read. A bit of explicit flushing
is needed to make sure that various outputs are not interleaved.

Fixes https://github.com/systemd/systemd/issues/29061.

src/systemctl/systemctl-show.c

index e11339633158a47597bf5e554bb1e5d9ed0a6883..c0f9747dd814a2743ef885ffb87e2a89b0ebc0bc 100644 (file)
@@ -821,6 +821,8 @@ static void print_status_info(
 }
 
 static void show_unit_help(UnitStatusInfo *i) {
+        bool previous_man_page = false;
+
         assert(i);
 
         if (!i->documentation) {
@@ -828,11 +830,29 @@ static void show_unit_help(UnitStatusInfo *i) {
                 return;
         }
 
-        STRV_FOREACH(p, i->documentation)
-                if (startswith(*p, "man:"))
-                        show_man_page(*p + 4, false);
-                else
-                        log_info("Can't show: %s", *p);
+        STRV_FOREACH(doc, i->documentation) {
+                const char *p;
+
+                p = startswith(*doc, "man:");
+
+                if (p ? doc != i->documentation : previous_man_page) {
+                        puts("");
+                        fflush(stdout);
+                }
+
+                previous_man_page = p;
+
+                if (p)
+                        show_man_page(p, /* null_stdio= */ false);
+                else {
+                        _cleanup_free_ char *t = NULL;
+
+                        if ((p = startswith(*doc, "file://")))
+                                (void) terminal_urlify_path(p, NULL, &t);
+
+                        printf("Additional documentation: %s\n", t ?: p ?: *doc);
+                }
+        }
 }
 
 static int map_main_pid(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {