Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions NEWS.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -480,6 +480,12 @@ https://github.com/networkupstools/nut/milestone/13
Directory names are based on hashes of strings that identify the content,
which are size-limited to some 8 characters.
[issues #3108, #3390, #1711, #3526, PR #3109]
* Introduced `tools/asciidoc-github-links.pl` to simplify `docs/Makefile.am`
generation of `*.adoc-parsed` files with substituted GitHub links, and to
allow that logic to be executed separately from `make` and potentially be
re-used by other projects. Added support for lists of PRs/issues as used
in this document, and support for GitHub Security Advisories (GHSA).
[PR #3594, issue #1953]
* Rearranged the GHA job to prepare Dist and Docs Tarballs. [PR #3460]
* Updated `scripts/Windows/dllldd.sh` helper script to better detect DLL
names not exposed with dynamic linking metadata (e.g. some Mozilla NSS
Expand Down
35 changes: 14 additions & 21 deletions docs/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -449,27 +449,20 @@ MAINTAINER_ASCIIDOCS_CHANGELOG_DEBUG = no
fi ; \
exit 0 ; \
fi ; \
echo " DOC-ASCIIDOC-GITHUB-LINKS Parsing GitHub link patterns $< => $@"; \
if [ x"$(MAINTAINER_ASCIIDOCS_CHANGELOG_DEBUG)" != xno ] ; then \
ls -lad $@ $< || true ; \
stat $@ $< || true ; \
fi ; \
cat '$<' | { $(SED) \
-e 's%\(link:https*://github.com/networkupstools/[a-zA-Z0-9./-]*/[1-9][0-9]*/*\[[^]]*\)\#\([1-9][0-9]*\)%\1\#\#\2%g' \
-e 's%\[\([^]]*\)](\(https*://[^ ]*\))%link:\2[\1]%g' \
-e 's%\(link:https*://github.com/[^ ]*\)\.\.\.\([^ ]*\)%\1..\2%g' \
-e 's%\(issue\) *\#\([1-9][0-9]*\)\([^0-9]\|$$\)%link:https://github.com/networkupstools/nut/issues/\2[\1 \#\#\2]\3%g' \
-e 's%\(PR\|pull request\) *\#\([1-9][0-9]*\)\([^0-9]\|$$\)%link:https://github.com/networkupstools/nut/pull/\2[\1 \#\#\2]\3%g' \
-e 's%\([[ ,]\)\#\([1-9][0-9]*\)\([^0-9]\|$$\)%\1link:https://github.com/networkupstools/nut/issues/\2[\#\#\2]\3%g' \
-e 's%\(issue\) networkupstools/\([^ ][^ ]*\)\#\([1-9][0-9]*\)\([^0-9]\|$$\)%link:https://github.com/networkupstools/\2/issues/\3[\1 \2\#\#\3]\4%g' \
-e 's%\(PR\|pull request\) *networkupstools/\([^ ][^ ]*\)\#\([1-9][0-9]*\)\([^0-9]\|$$\)%link:https://github.com/networkupstools/\2/pull/\3[\1 \2\#\#\3]\4%g' \
-e 's%\([[ ,]\)networkupstools/\([^ ][^ ]*\)\#\([1-9][0-9]*\)\([^0-9]\|$$\)%\1link:https://github.com/networkupstools/\2/issues/\3[\2\#\#\3]\4%g' \
-e 's%\#\(\#[1-9][0-9]*\)%\1%g' \
-e 's,\(https*://[^ \+]*\)[\]*[+],\1%2B,g' \
; } > "$@.tmp.$$$$" \
&& test -s "$@.tmp.$$$$" \
&& mv -f "$@.tmp.$$$$" '$@' \
|| { RES="$$?" ; rm -f "$@.tmp.$$$$" ; exit $$RES ; }
if perl -e 1; then \
echo " DOC-ASCIIDOC-GITHUB-LINKS Parsing GitHub link patterns $< => $@"; \
if [ x"$(MAINTAINER_ASCIIDOCS_CHANGELOG_DEBUG)" != xno ] ; then \
ls -lad $@ $< || true ; \
stat $@ $< || true ; \
fi ; \
$(top_srcdir)/tools/asciidoc-github-links.pl < '$<' > "$@.tmp.$$$$" \
&& test -s "$@.tmp.$$$$" \
&& mv -f "$@.tmp.$$$$" '$@' \
|| { RES="$$?" ; rm -f "$@.tmp.$$$$" ; exit $$RES ; } ; \
else \
echo " DOC-ASCIIDOC-GITHUB-LINKS SKIP: perl not available" >&2 ; \
cat '$<' > '$@' ; \
fi
@if [ x'$@' = x'$(top_builddir)/ChangeLog.adoc-parsed' ] ; then \
touch -r '$@' '$(top_builddir)/docs/.ChangeLog.adoc-parsed.latest' || touch '$(top_builddir)/docs/.ChangeLog.adoc-parsed.latest' ; \
fi
Expand Down
5 changes: 3 additions & 2 deletions docs/nut.dict
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
personal_ws-1.1 en 3818 utf-8
personal_ws-1.1 en 3819 utf-8
AAC
AAS
ABI
Expand Down Expand Up @@ -449,6 +449,7 @@ GES
GETADDRINFO
GETPID
GHA
GHSA
GID
GIO
GITREV
Expand Down Expand Up @@ -3153,10 +3154,10 @@ renderer
renderers
renice
repindex
replug
repo
reportId
reposurgeon
replug
repotec
req
resetter
Expand Down
17 changes: 16 additions & 1 deletion tools/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ PYTHON_DEFAULT = @PYTHON_DEFAULT@

EXTRA_DIST = nut-usbinfo.pl nut-recorder.sh nut-ddl-dump.sh nut-dumpdiff.sh \
gitlog2changelog.py.in gitlog2version.sh semver-compare.sh \
nut-snmpinfo.py.in driver-list-format.sh check-source-nonascii.pl
nut-snmpinfo.py.in driver-list-format.sh check-source-nonascii.pl \
asciidoc-github-links.pl

# These files are generated for nut-scanner builds (and cleaned as any others),
# and can change as respective SNMP/USB subdriver sources are iterated by a
Expand Down Expand Up @@ -164,6 +165,20 @@ dist-hook:
echo "----------------------------------------------------------------------"; \
fi

# Using $? here for "sources newer than target",
# note that $< is not portable in non-suffix rules:
check-asciidoc-github-links: $(top_srcdir)/tools/asciidoc-github-links.pl
@echo "Checking for perl support of github links parser..."
@if perl -e 1; then \
OUT="`echo 'Some changes. [#333, PRs #123, #345; issues #789, #99, advisories GHSA-1234-5678-90ab, #12345]' | perl '$?'`" || exit ; \
test x"$$OUT" = x'Some changes. [link:https://github.com/networkupstools/nut/issues/333[#333], PRs link:https://github.com/networkupstools/nut/pull/123[#123], link:https://github.com/networkupstools/nut/pull/345[#345]; issues link:https://github.com/networkupstools/nut/issues/789[#789], link:https://github.com/networkupstools/nut/issues/99[#99], advisories link:https://github.com/networkupstools/nut/security/advisories/GHSA-1234-5678-90ab[GHSA-1234-5678-90ab], link:https://github.com/networkupstools/nut/issues/12345[#12345]]' || exit ; \
echo "OK: $? returned expected output" ; \
else \
echo "SKIPPED: perl not available"; \
fi

check-local: check-asciidoc-github-links

MAINTAINERCLEANFILES = Makefile.in .dirstamp

# Can be recreated by `make` or `configure`,
Expand Down
133 changes: 133 additions & 0 deletions tools/asciidoc-github-links.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
#!/usr/bin/env perl
#
# Convert certain text patterns into ASCIIDOC markup for GitHub links to
# issues, PRs, security advisories, etc.
#
# Copyright (C) 2023-2026 by Jim Klimov <jimklimov+nut@gmail.com>
# Based on earlier work with a stack of SED expressions in NUT::docs/Makefile.am

use strict;

# These may be eventually overridden by caller to re-use with other projects
# (need to add CLI or envvar inputs):
my $gh_orgname = "networkupstools";
my $gh_prjname = "nut";

# NOTE: Schema in regexes would vary, but in injected URLs must be specific
my $gh_schema_re = qr/[Hh][Tt][Tt][Pp][Ss]?:\/\//;
my $gh_schema = "https://";
my $gh_hostname_re = qr/github\.com/;
my $gh_hostname = "github.com";

# URI parts (under a project base URI) for singular item; note not all are
# consistently named singular/plural - for item vs. list). Also note that
# historically "issues" and "pulls" were handled by the same github-side
# handler so their URI parts could be interchangeable:
my $gh_uripart_pull = "pull";
my $gh_uripart_issue = "issues";
my $gh_uripart_secadv = "security/advisories";

my $issue_id_re = qr/[1-9][0-9]*/;
my $ghsa_id_re = qr/GHSA-[A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]-[A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]-[A-Za-z0-9][A-Za-z0-9][A-Za-z0-9][A-Za-z0-9]/;

my $end_issue_id_re = qr/[^0-9]|$/;
my $end_ghsa_id_re = qr/[^A-Za-z0-9]|$/;

# Values for easier substitution below:
my $gh_url_site = "${gh_schema}${gh_hostname}";
my $gh_url_org = "${gh_url_site}/${gh_orgname}";
my $gh_url_prj = "${gh_url_org}/${gh_prjname}";

local $/ = undef;
while (<>) {
# 1. link to a sibling project's issue/pull/advisory e.g. [networkupstools/nut#2048]
s/(link:${gh_schema_re}${gh_hostname_re}\/${gh_orgname}\/[a-zA-Z0-9.\/-]+\/[1-9][0-9]*\/*\[[^]]*)\#([1-9][0-9]*)/$1##$2/g;

# 2. markdown links [text](url) -> link:url[text]
s/\[([^]]*)\]\((${gh_schema_re}[^ ]*)\)/{ "link:" . $2 . "[" . $1 . "]" }/ge;

# 3. link ellipsis ...
s/(link:${gh_schema_re}${gh_hostname_re}\/[^ ]*)\.\.\.([^ ]*)/$1..$2/g;

# 4. Lists of references: PRs/issues/advisories token followed by
# comma and/or space-separated identifiers, with state memory
s%\b(PRs|issues|advisories)\b(.*)%{
my $plural = $1;
my $rest = $2;
my $out = "";

while ($rest ne "") {
my $uripart =
($plural eq 'PRs') ? $gh_uripart_pull :
($plural eq 'issues') ? $gh_uripart_issue :
$gh_uripart_secadv;

$out .= $plural;
my $id_matcher = $plural eq 'advisories' ? qr/\#?(${ghsa_id_re})/ : qr/\#(${issue_id_re})/;
while ($rest =~ s/^(\s*(?:[;,]\s*)?)${id_matcher}//s) {
my $sep = $1;
my $id = $2;

$out .= $sep;
if ($id =~ /^${ghsa_id_re}/) {
$out .= "link:${gh_url_prj}/${uripart}/" . $id . "[" . $id . "]";
}
else {
my $num = $id;
$num =~ s/^\#+//;
$out .= "link:${gh_url_prj}/${uripart}/" . $num . "[#" . $num . "]";
}
}

if ($rest =~ s/^([;,]?\s*)(PRs|issues|advisories)(.*)//s) {
my $sep = $1;
$plural = $2;
$rest = $3;

$out .= $sep;
} else {
last;
}
}

$out . $rest;
}%ges;

# 5. single [#GHSA-...]
s%(^|[^A-Za-z0-9])\[#?(${ghsa_id_re})\]%{ $1 . "[link:${gh_url_prj}/${gh_uripart_secadv}/" . $2 . "[" . $2 . "]]" }%ge;

# 6. "advisory GHSA-..." or "advisory #GHSA-..." (multiple words / space separated, can be broken across lines)
s%\b(advisory)\s*\#?(${ghsa_id_re})(${end_ghsa_id_re})%{ "link:${gh_url_prj}/${gh_uripart_secadv}/" . $2 . "[" . $1 . " " . $2 . "]" . $3 }%ge;

# 7. issue #123
s%\b(issue)\s*\#(${issue_id_re})(${end_issue_id_re})%{ "link:${gh_url_prj}/${gh_uripart_issue}/" . $2 . "[" . $1 . " ##" . $2 . "]" . $3 }%ge;

# 8. PR #123 or pull request #123 (multi-word "pull request" can be broken across lines)
s%\b(PR|pull\s+request)\s*\#(${issue_id_re})(${end_issue_id_re})%{ "link:${gh_url_prj}/${gh_uripart_pull}/" . $2 . "[" . $1 . " ##" . $2 . "]" . $3 }%ge;

# 9. " #123" or ",#123"
s%([,\s])\#(${issue_id_re})(${end_issue_id_re})%{ $1 . "link:${gh_url_prj}/${gh_uripart_issue}/" . $2 . "[##" . $2 . "]" . $3 }%ge;

# 10. "...[#123..."
s%(^|\D)\[\#(${issue_id_re})(${end_issue_id_re})%{ $1 . "[link:${gh_url_prj}/${gh_uripart_issue}/" . $2 . "[##" . $2 . "]" . $3 }%ge;

# 11. issue networkupstools/foo#123
s%\b(issue)\s+${gh_orgname}\/([^ \s]+)\#(${issue_id_re})(${end_issue_id_re})%{ "link:${gh_url_org}/" . $2 . "/" . $gh_uripart_issue . "/" . $3 . "[" . $1 . " " . $2 . "##" . $3 . "]" . $4 }%ge;

# 12. PR networkupstools/foo#123 or pull request networkupstools/foo#123 (multi-word)
s%\b(PR|pull\s+request)\s+${gh_orgname}\/([^ \s]+)\#(${issue_id_re})(${end_issue_id_re})%{ "link:${gh_url_org}/" . $2 . "/" . $gh_uripart_pull . "/" . $3 . "[" . $1 . " " . $2 . "##" . $3 . "]" . $4 }%ge;

# 13. [ ,]networkupstools/foo#123
s%([,\s])${gh_orgname}\/([^ \s]+)\#(${issue_id_re})(${end_issue_id_re})%{ $1 . "link:${gh_url_org}/" . $2 . "/" . $gh_uripart_issue . "/" . $3 . "[" . $2 . "##" . $3 . "]" . $4 }%ge;

# 14. ##123 -> #123
s/\#(\#${issue_id_re})/$1/g;

# 15. URL plus sign encoding
s/(${gh_schema_re}[^\s\+]*)([\]]*\+)/{
"$1%2B";
# printf stderr "[%2B]: Matched for '$1'\n";
}/ge;

print $_;
}
Loading