aboutsummaryrefslogtreecommitdiff
path: root/hack/xref-helpmsgs-manpages
diff options
context:
space:
mode:
Diffstat (limited to 'hack/xref-helpmsgs-manpages')
-rwxr-xr-xhack/xref-helpmsgs-manpages127
1 files changed, 127 insertions, 0 deletions
diff --git a/hack/xref-helpmsgs-manpages b/hack/xref-helpmsgs-manpages
index af54f05f3..6a2d627bb 100755
--- a/hack/xref-helpmsgs-manpages
+++ b/hack/xref-helpmsgs-manpages
@@ -54,6 +54,11 @@ option is listed in the appropriate man page and vice-versa.
$ME invokes '\$PODMAN' (default: $Default_Podman).
+In the spirit of shoehorning functionality where it wasn't intended,
+$ME also checks the SEE ALSO section of each man page
+to ensure that references and links are properly formatted
+and valid.
+
Exit status is zero if no inconsistencies found, one otherwise
OPTIONS:
@@ -286,6 +291,9 @@ sub podman_man {
elsif ($line =~ /^\#\#\s+(SUB)?COMMANDS/) {
$section = 'commands';
}
+ elsif ($line =~ /^\#\#\s+SEE\s+ALSO/) {
+ $section = 'see-also';
+ }
elsif ($line =~ /^\#\#[^#]/) {
$section = '';
}
@@ -340,6 +348,11 @@ sub podman_man {
}
}
}
+
+ # It's easy to make mistakes in the SEE ALSO elements.
+ elsif ($section eq 'see-also') {
+ _check_seealso_links( "$subpath:$.", $line );
+ }
}
close $fh;
@@ -427,5 +440,119 @@ sub podman_rst {
# END data gathering
###############################################################################
+# BEGIN sanity checking of SEE ALSO links
+
+##########################
+# _check_seealso_links # Check formatting and link validity.
+##########################
+sub _check_seealso_links {
+ my $path = shift;
+ my $line = shift;
+
+ return if ! $line;
+
+ # Line must be a comma-separated list of man page references, e.g.
+ # **foo(1)**, **[podman-bar(1)](podman-bar.1.md)**, **[xxx(8)](http...)**
+ TOKEN:
+ for my $token (split /,\s+/, $line) {
+ # Elements must be separated by comma and space. (We don't do further
+ # checks here, so it's possible for the dev to add the space and then
+ # have us fail on the next iteration. I choose not to address that.)
+ if ($token =~ /,/) {
+ warn "$ME: $path: please add space after comma: '$token'\n";
+ ++$Errs;
+ next TOKEN;
+ }
+
+ # Each token must be of the form '**something**'
+ if ($token !~ s/^\*\*(.*)\*\*$/$1/) {
+ if ($token =~ /\*\*/) {
+ warn "$ME: $path: '$token' has asterisks in the wrong place\n";
+ }
+ else {
+ warn "$ME: $path: '$token' should be bracketed by '**'\n";
+ }
+ ++$Errs;
+ next TOKEN;
+ }
+
+ # Is it a markdown link?
+ if ($token =~ /^\[(\S+)\]\((\S+)\)$/) {
+ my ($name, $link) = ($1, $2);
+ if ($name =~ /^(.*)\((\d)\)$/) {
+ my ($base, $section) = ($1, $2);
+ if (-e "$Markdown_Path/$base.$section.md" || -e "$Markdown_Path/links/$base.$section") {
+ if ($link ne "$base.$section.md") {
+ warn "$ME: $path: inconsistent link $name -> $link, expected $base.$section.md\n";
+ ++$Errs;
+ }
+ }
+ else {
+ if (! _is_valid_external_link($base, $section, $link)) {
+ warn "$ME: $path: invalid link $name -> $link\n";
+ ++$Errs;
+ }
+ }
+ }
+ else {
+ warn "$ME: $path: could not parse '$name' as 'manpage(N)'\n";
+ ++$Errs;
+ }
+ }
+
+ # Not a markdown link; it must be a plain man reference, e.g. 'foo(5)'
+ elsif ($token =~ m!^(\S+)\((\d+)\)$!) {
+ my ($base, $section) = ($1, $2);
+
+ # Unadorned 'podman-foo(1)' must be a link.
+ if (-e "$Markdown_Path/$base.$section.md" || -e "$Markdown_Path/links/$base.$section") {
+ warn "$ME: $path: '$token' should be '[$token]($base.$section.md)'\n";
+ ++$Errs;
+ }
+
+ # Link to man page foo(5) but without a link. This is not an error
+ # but Ed may sometimes want to see those on a manual test run.
+ warn "$ME: $path: plain '$token' would be so much nicer as a link\n"
+ if $verbose;
+ }
+ else {
+ warn "$ME: $path: invalid token '$token'\n";
+ ++$Errs;
+ }
+ }
+}
+
+#############################
+# _is_valid_external_link # Tries to validate links to external man pages
+#############################
+#
+# This performs no actual fetches, so we can't actually check for 404.
+# All we do is ensure that links conform to standard patterns. This is
+# good for catching things like 'conmon(8)' pointing to a .5 URL, or
+# linking to .md instead of .html.
+#
+# FIXME: we could actually rewrite this so as to offer hints on what to fix.
+# That's a lot of work, and a lot of convoluted code, for questionable ROI.
+#
+sub _is_valid_external_link {
+ my ($base, $section, $link) = @_;
+
+ return 1 if $link =~ m!^https://github\.com/\S+/blob/(main|master)(/.*)?/\Q$base\E\.$section\.md!;
+
+ return 1 if $link =~ m!^https://.*unix\.com/man-page/(linux|redhat)/$section/$base$!;
+ return 1 if $link eq "https://man7\.org/linux/man-pages/man$section/$base\.$section\.html";
+
+ if ($base =~ /systemd/) {
+ return 1 if $link eq "https://www.freedesktop.org/software/systemd/man/$base.html";
+ }
+
+ return;
+}
+
+
+
+
+# END sanity checking of SEE ALSO links
+###############################################################################
1;