From 76e1a0925fde2cbf25b75409cd353e20b9cfef48 Mon Sep 17 00:00:00 2001 From: EuAndreh Date: Sat, 1 Apr 2023 22:25:46 -0300 Subject: Revamp code under aux/ --- aux/.gitignore | 3 + aux/assert-shellcheck.sh | 6 - aux/checks/changelog.sh | 54 +++++++++ aux/checks/manpages.sh | 21 ++++ aux/checks/manpages/footer.en.0.in | 30 +++++ aux/checks/manpages/footer.eo.0.in | 13 +++ aux/checks/manpages/footer.es.0.in | 13 +++ aux/checks/manpages/footer.fr.0.in | 13 +++ aux/checks/manpages/footer.pt.0.in | 13 +++ aux/checks/readme.sh | 82 ++++++++++++++ aux/checks/repo.sh | 188 +++++++++++++++++++++++++++++++ aux/checks/shellcheck.sh | 6 + aux/checks/spelling.sh | 5 + aux/checks/todos.sh | 62 +++++++++++ aux/dev.mk | 101 +++++++++++++++++ aux/dist.sh | 88 +++++++++++++++ aux/ext2subdir.sh | 60 ++++++++++ aux/favicon.svg | 62 +++++++++++ aux/headers.html | 2 + aux/lib.sh | 2 + aux/po4a-cfg.sh | 85 ++++++++++++++ aux/preamble-md.in | 14 +++ aux/sign-tarballs.sh | 38 +++++++ aux/workflow/TODOs.sh | 71 ------------ aux/workflow/assert-changelog.sh | 66 ----------- aux/workflow/assert-manpages.sh | 220 ------------------------------------- aux/workflow/assert-readme.sh | 108 ------------------ aux/workflow/assert-spelling.sh | 78 ------------- aux/workflow/assert-todos.sh | 58 ---------- aux/workflow/commonmark.sh | 42 ------- aux/workflow/dist.sh | 99 ----------------- aux/workflow/favicon.html | 1 - aux/workflow/favicon.svg | 62 ----------- aux/workflow/l10n.sh | 75 ------------- aux/workflow/preamble.md | 14 --- aux/workflow/public.sh | 59 ---------- aux/workflow/repocheck.sh | 184 ------------------------------- aux/workflow/sign-tarballs.sh | 38 ------- aux/workflow/style.css | 41 ------- 39 files changed, 955 insertions(+), 1222 deletions(-) create mode 100644 aux/.gitignore delete mode 100755 aux/assert-shellcheck.sh create mode 100755 aux/checks/changelog.sh create mode 100755 aux/checks/manpages.sh create mode 100644 aux/checks/manpages/footer.en.0.in create mode 100644 aux/checks/manpages/footer.eo.0.in create mode 100644 aux/checks/manpages/footer.es.0.in create mode 100644 aux/checks/manpages/footer.fr.0.in create mode 100644 aux/checks/manpages/footer.pt.0.in create mode 100755 aux/checks/readme.sh create mode 100755 aux/checks/repo.sh create mode 100755 aux/checks/shellcheck.sh create mode 100755 aux/checks/spelling.sh create mode 100755 aux/checks/todos.sh create mode 100644 aux/dev.mk create mode 100755 aux/dist.sh create mode 100755 aux/ext2subdir.sh create mode 100644 aux/favicon.svg create mode 100644 aux/headers.html create mode 100755 aux/po4a-cfg.sh create mode 100644 aux/preamble-md.in create mode 100755 aux/sign-tarballs.sh delete mode 100755 aux/workflow/TODOs.sh delete mode 100755 aux/workflow/assert-changelog.sh delete mode 100755 aux/workflow/assert-manpages.sh delete mode 100755 aux/workflow/assert-readme.sh delete mode 100755 aux/workflow/assert-spelling.sh delete mode 100755 aux/workflow/assert-todos.sh delete mode 100755 aux/workflow/commonmark.sh delete mode 100755 aux/workflow/dist.sh delete mode 100644 aux/workflow/favicon.html delete mode 100644 aux/workflow/favicon.svg delete mode 100755 aux/workflow/l10n.sh delete mode 100644 aux/workflow/preamble.md delete mode 100755 aux/workflow/public.sh delete mode 100755 aux/workflow/repocheck.sh delete mode 100755 aux/workflow/sign-tarballs.sh delete mode 100644 aux/workflow/style.css (limited to 'aux') diff --git a/aux/.gitignore b/aux/.gitignore new file mode 100644 index 0000000..5588aca --- /dev/null +++ b/aux/.gitignore @@ -0,0 +1,3 @@ +/generated.mk +/preamble-md +/checks/manpages/*.0 diff --git a/aux/assert-shellcheck.sh b/aux/assert-shellcheck.sh deleted file mode 100755 index 40fd364..0000000 --- a/aux/assert-shellcheck.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -set -eu - -find . -name '*.sh' -print0 | - xargs -0 awk 'FNR==1 && /^#!\/bin\/sh$/ { print FILENAME }' | - xargs shellcheck diff --git a/aux/checks/changelog.sh b/aux/checks/changelog.sh new file mode 100755 index 0000000..ee10549 --- /dev/null +++ b/aux/checks/changelog.sh @@ -0,0 +1,54 @@ +#!/bin/sh +set -eu + + +while getopts 'h' flag; do + case "$flag" in + h) + usage + help + exit + ;; + *) + usage >&2 + exit 2 + ;; + esac +done +shift $((OPTIND - 1)) + +. aux/lib.sh + + +HOMEPAGE_LINK="Changelog for [$NAME](https://$TLD/$NAME/en/)." + +if ! grep -qF "$HOMEPAGE_LINK" CHANGELOG.md; then + echo "Missing link to homepage in CHANGELOG.md:" >&2 + echo "$HOMEPAGE_LINK" + exit 1 +fi + +assert() { + DATE="$1" + VVERSION="$2" + VERSION="${2#v}" + CHANGELOG_ENTRY="$(printf \ + '# [%s](https://%s/git/%s/commit/?id=%s) - %s' \ + "$VERSION" "$TLD" "$NAME" "$VVERSION" "$DATE")" + if ! grep -qF "$CHANGELOG_ENTRY" CHANGELOG.md; then + echo "Missing '$CHANGELOG_ENTRY' entry from CHANGELOG.md" >&2 + exit 1 + fi +} + +for VVERSION in $(git tag); do + DATE="$(git log -1 --format=%ad --date=short "$VVERSION")" + assert "$DATE" "$VVERSION" +done + +# FIXME +# "$@" represents a list of tags to be also included in the verification. +for VVERSION in "$@"; do + DATE="$(date '+%Y-%m-%d')" + assert "$DATE" "$VVERSION" +done diff --git a/aux/checks/manpages.sh b/aux/checks/manpages.sh new file mode 100755 index 0000000..204d960 --- /dev/null +++ b/aux/checks/manpages.sh @@ -0,0 +1,21 @@ +#!/bin/sh +set -eu + +while getopts 'h' flag; do + case "$flag" in + h) + usage + help + exit + ;; + *) + exit 2 + ;; + esac +done +shift $((OPTIND - 1)) + +. aux/lib.sh + + +# FIXME diff --git a/aux/checks/manpages/footer.en.0.in b/aux/checks/manpages/footer.en.0.in new file mode 100644 index 0000000..8db378b --- /dev/null +++ b/aux/checks/manpages/footer.en.0.in @@ -0,0 +1,30 @@ +.SH AUTHORS + +.MT eu@euandre.org +EuAndreh +.ME +and contributors. + + +.SH BUGS + +.IP \(bu +Report bugs to the +.MT ~euandreh/@MAILING_LIST@@lists.sr.ht +mailing list +.ME . +Use the subject "\f(CR[@NAME@] BUG or TASK: +\fR". +.IP \(bu +Browse bugs +.UR https://@TLD@/@NAME@/TODOs.html +online +.UE . +.IP \(bu +.UR https://@TLD@/@NAME@/en/ +Homepage +.UE . +.IP \(bu +.UR https://lists.sr.ht/~euandreh/@MAILING_LIST@?search=%5B@NAME@%5D +Comments and discussions +.UE . diff --git a/aux/checks/manpages/footer.eo.0.in b/aux/checks/manpages/footer.eo.0.in new file mode 100644 index 0000000..bb319ca --- /dev/null +++ b/aux/checks/manpages/footer.eo.0.in @@ -0,0 +1,13 @@ +.SH AUTHORS + +.MT eu@euandre.org EuAndreh .ME and contributors. + + +.SH BUGS + +.IP \(bu Report bugs to the .MT ~euandreh/@MAILING_LIST@@lists.sr.ht mailing +list .ME . Use the subject "\f(CR[@NAME@] BUG or TASK: \fR". +.IP \(bu Browse bugs .UR https://@TLD@/@NAME@/TODOs.html online .UE . .IP +\(bu .UR https://@TLD@/@NAME@/en/ Homepage .UE . .IP \(bu .UR +https://lists.sr.ht/~euandreh/@MAILING_LIST@?search=%5B@NAME@%5D Comments +and discussions .UE . diff --git a/aux/checks/manpages/footer.es.0.in b/aux/checks/manpages/footer.es.0.in new file mode 100644 index 0000000..bb319ca --- /dev/null +++ b/aux/checks/manpages/footer.es.0.in @@ -0,0 +1,13 @@ +.SH AUTHORS + +.MT eu@euandre.org EuAndreh .ME and contributors. + + +.SH BUGS + +.IP \(bu Report bugs to the .MT ~euandreh/@MAILING_LIST@@lists.sr.ht mailing +list .ME . Use the subject "\f(CR[@NAME@] BUG or TASK: \fR". +.IP \(bu Browse bugs .UR https://@TLD@/@NAME@/TODOs.html online .UE . .IP +\(bu .UR https://@TLD@/@NAME@/en/ Homepage .UE . .IP \(bu .UR +https://lists.sr.ht/~euandreh/@MAILING_LIST@?search=%5B@NAME@%5D Comments +and discussions .UE . diff --git a/aux/checks/manpages/footer.fr.0.in b/aux/checks/manpages/footer.fr.0.in new file mode 100644 index 0000000..bb319ca --- /dev/null +++ b/aux/checks/manpages/footer.fr.0.in @@ -0,0 +1,13 @@ +.SH AUTHORS + +.MT eu@euandre.org EuAndreh .ME and contributors. + + +.SH BUGS + +.IP \(bu Report bugs to the .MT ~euandreh/@MAILING_LIST@@lists.sr.ht mailing +list .ME . Use the subject "\f(CR[@NAME@] BUG or TASK: \fR". +.IP \(bu Browse bugs .UR https://@TLD@/@NAME@/TODOs.html online .UE . .IP +\(bu .UR https://@TLD@/@NAME@/en/ Homepage .UE . .IP \(bu .UR +https://lists.sr.ht/~euandreh/@MAILING_LIST@?search=%5B@NAME@%5D Comments +and discussions .UE . diff --git a/aux/checks/manpages/footer.pt.0.in b/aux/checks/manpages/footer.pt.0.in new file mode 100644 index 0000000..bb319ca --- /dev/null +++ b/aux/checks/manpages/footer.pt.0.in @@ -0,0 +1,13 @@ +.SH AUTHORS + +.MT eu@euandre.org EuAndreh .ME and contributors. + + +.SH BUGS + +.IP \(bu Report bugs to the .MT ~euandreh/@MAILING_LIST@@lists.sr.ht mailing +list .ME . Use the subject "\f(CR[@NAME@] BUG or TASK: \fR". +.IP \(bu Browse bugs .UR https://@TLD@/@NAME@/TODOs.html online .UE . .IP +\(bu .UR https://@TLD@/@NAME@/en/ Homepage .UE . .IP \(bu .UR +https://lists.sr.ht/~euandreh/@MAILING_LIST@?search=%5B@NAME@%5D Comments +and discussions .UE . diff --git a/aux/checks/readme.sh b/aux/checks/readme.sh new file mode 100755 index 0000000..0447b08 --- /dev/null +++ b/aux/checks/readme.sh @@ -0,0 +1,82 @@ +#!/bin/sh +set -eu + +while getopts 'h' flag; do + case "$flag" in + h) + usage + help + exit + ;; + *) + usage >&2 + exit 2 + ;; + esac +done +shift $((OPTIND - 1)) + +. aux/lib.sh + + +EXPECTED="$(mkstemp)" +cat <<-EOF >> "$EXPECTED" + + Send contributions to the [mailing list] via + [\`git send-email\`](https://git-send-email.io/). + + + ## Links + + - [homepage](https://$TLD/s/$NAME/en/) + - [source code](https://$TLD/git/$NAME/) + - [bug tracking](https://$TLD/s/$NAME/TODOs.html) + - [mailing list] + - [CI logs](https://$TLD/s/$NAME/ci/) + - [CHANGELOG](https://$TLD/s/$NAME/en/CHANGELOG.html) + + [mailing list]: https://lists.sr.ht/~euandreh/$MAILING_LIST?search=%5B$NAME%5D +EOF + +RELEASES_LIST="$(mkstemp)" +add_release() { + DATE="$1" + VVERSION="$2" + echo "- [$VVERSION](https://$TLD/git/$NAME/commit/?id=$VVERSION) [$NAME-$VVERSION.tar.gz](https://$TLD/git/$NAME/snapshot/$NAME-$VVERSION.tar.gz) ([sig](https://$TLD/git/$NAME/snapshot/$NAME-$VVERSION.tar.gz.asc)) - $DATE" >> "$RELEASES_LIST" +} + +for VVERSION in $(git tag); do + DATE="$(git log -1 --format=%ad --date=short "$VVERSION")" + add_release "$DATE" "$VVERSION" +done + +# "$@" represents a list of tags to be also included in the verification. +for VVERSION in "$@"; do + if ! git tag | grep -qF "$VVERSION"; then + DATE="$(date '+%Y-%m-%d')" + add_release "$DATE" "$VVERSION" + fi +done + +if [ -s "$RELEASES_LIST" ]; then + printf '\n\n## Releases\n\n' >> "$EXPECTED" + sort -r "$RELEASES_LIST" >> "$EXPECTED" +fi + +cat <<-EOF >> "$EXPECTED" + + + ## License + + The code is licensed under + [GNU Affero General Public License v3.0 or later][AGPL-3.0-or-later] + (AGPL-3.0-or-later). + + [AGPL-3.0-or-later]: https://$TLD/git/$NAME/tree/COPYING +EOF + +if ! tail -n "$(wc -l < "$EXPECTED")" README.md | diff - "$EXPECTED"; then + echo 'Wrong metadata at the end of README.md file' + echo "See expected content at: $EXPECTED" + exit 1 +fi diff --git a/aux/checks/repo.sh b/aux/checks/repo.sh new file mode 100755 index 0000000..0c00e92 --- /dev/null +++ b/aux/checks/repo.sh @@ -0,0 +1,188 @@ +#!/bin/sh +set -eu + +if true; then + exit +fi + +if [ -n "${RECURSIVE_CHECK:-}" ]; then + exit +fi +export RECURSIVE_CHECK=true + +. aux/lib.sh + +REPODIR="$PWD" + +INSTALLCHECK=false +while getopts 'x:l:f:' flag; do + case "$flag" in + x) + EXECUTABLES="$OPTARG" + INSTALLCHECK=true + ;; + l) + SYMLINKS="$OPTARG" + INSTALLCHECK=true + ;; + f) + FILES="$OPTARG" + INSTALLCHECK=true + ;; + *) + exit 2 + ;; + esac +done +shift $((OPTIND - 1)) + +assert_no_diffs() { + if [ -n "$(git status -s)" ]; then + echo 'Repository left dirty.' >&2 + git status >&2 + exit 1 + fi +} + +assert_installed_files() { + if [ -n "${EXECUTABLES:-}" ]; then + ACTUAL="$(find "$1" -type f -perm -u=x | wc -l)" + if [ "$EXECUTABLES" != "$ACTUAL" ]; then + printf 'Expected %s executables, found %s:\n' \ + "$EXECUTABLES" "$ACTUAL" >&2 + echo "find $1 -type f -perm -u=x:" >&2 + find "$1" -type f -perm -u=x >&2 + exit 1 + fi + fi + + if [ -n "${SYMLINKS:-}" ]; then + ACTUAL="$(find "$1" -type l | wc -l)" + if [ "$SYMLINKS" != "$ACTUAL" ]; then + printf 'Expected %s symlinks, found %s:\n' \ + "$SYMLINKS" "$ACTUAL" >&2 + echo "find $1 -type l:" >&2 + find "$1" -type l >&2 + exit 1 + fi + fi + + if [ -n "${FILES:-}" ]; then + ACTUAL="$(find "$1" -type f | wc -l)" + if [ "$FILES" != "$ACTUAL" ]; then + printf 'Expected %s files, found %s:\n' \ + "$FILES" "$ACTUAL" >&2 + echo "find $1 -type f:" >&2 + find "$1" -type f >&2 + exit 1 + fi + fi +} + +assert_uninstalled_files() { + if [ "$(find "$1" \( -type f -o -type l \) | wc -l)" != 0 ]; then + echo 'Left-over files after uninstall' >&2 + echo "find $1 \( -type f -o -type l \):" + find "$1" \( -type f -o -type l \) + exit 1 + fi +} + +assert_install() { + if [ "$INSTALLCHECK" != 'true' ]; then + return + fi + + make clean + + echo 'Asserting "canonical" install path' >&2 + INSTALL1="$(mkdtemp)" + make PREFIX="$INSTALL1" + make check PREFIX="$INSTALL1" + make install PREFIX="$INSTALL1" + assert_installed_files "$INSTALL1" + make uninstall PREFIX="$INSTALL1" + assert_uninstalled_files "$INSTALL1" + + make clean + + echo 'Asserting "straigh-forward" install path' >&2 + INSTALL2="$(mkdtemp)" + make install PREFIX="$INSTALL2" + assert_installed_files "$INSTALL2" + make uninstall PREFIX="$INSTALL2" + assert_uninstalled_files "$INSTALL2" + + make clean + + echo 'Asserting "idempotent" install path' >&2 + INSTALL3="$(mkdtemp)" + make install PREFIX="$INSTALL3" + make install PREFIX="$INSTALL3" + assert_installed_files "$INSTALL3" + make uninstall PREFIX="$INSTALL3" + make uninstall PREFIX="$INSTALL3" + assert_uninstalled_files "$INSTALL3" + + make clean + + echo 'Asserting "destdir" install path' >&2 + DESTDIR="$(mkdtemp)" + INSTALL4="$(mkdtemp)" + make install DESTDIR="$DESTDIR" PREFIX="$INSTALL4" + assert_installed_files "$DESTDIR/$INSTALL4" + make uninstall DESTDIR="$DESTDIR" PREFIX="$INSTALL4" + assert_uninstalled_files "$DESTDIR/$INSTALL4" +} + +assert_clean_clone() { + CLONEDIR="$(mkdtemp)" + cd "$CLONEDIR" + + git clone "$REPODIR" . + + make clean public dev-check + assert_no_diffs + make clean + assert_no_diffs + + if [ -n "$(git clean -ffdx --dry-run)" ]; then + echo '"make clean" left files:' >&2 + git clean -ffdx --dry-run >&2 + echo "Clone directory: $CLONEDIR" >&2 + exit 1 + fi + + rm -rf aux/ + make clean check || { + echo 'Cannot run "make check" without "aux/".' >&2 + echo "Clone directory: $CLONEDIR" >&2 + exit 1 + } + + assert_install + + cd - > /dev/null +} + +assert_clean_checkout() { + CHECKOUTDIR="$(mkdtemp)" + git --work-tree="$CHECKOUTDIR" checkout HEAD -- . + cd "$CHECKOUTDIR" + + FILECOUNT="$(find . -type f | wc -l)" + make clean public dev-check + make clean + if [ "$FILECOUNT" != "$(find . -type f | wc -l)" ]; then + echo 'File count mismatch after "make clean".' >&2 + echo "Checkout directory: $CHECKOUTDIR" >&2 + exit 1 + fi + + assert_install + + cd - > /dev/null +} + +assert_clean_clone +assert_clean_checkout diff --git a/aux/checks/shellcheck.sh b/aux/checks/shellcheck.sh new file mode 100755 index 0000000..40fd364 --- /dev/null +++ b/aux/checks/shellcheck.sh @@ -0,0 +1,6 @@ +#!/bin/sh +set -eu + +find . -name '*.sh' -print0 | + xargs -0 awk 'FNR==1 && /^#!\/bin\/sh$/ { print FILENAME }' | + xargs shellcheck diff --git a/aux/checks/spelling.sh b/aux/checks/spelling.sh new file mode 100755 index 0000000..4368820 --- /dev/null +++ b/aux/checks/spelling.sh @@ -0,0 +1,5 @@ +#!/bin/sh +set -eu + +echo FIXME +exit diff --git a/aux/checks/todos.sh b/aux/checks/todos.sh new file mode 100755 index 0000000..2b9a570 --- /dev/null +++ b/aux/checks/todos.sh @@ -0,0 +1,62 @@ +#!/bin/sh +set -eu + +if true; then + exit +fi + +if [ -e .git ] && git grep FIXME | grep -v '^TODOs.md' | + grep -v '^aux/workflow/assert-todos.sh'; then + echo "Found dangling FIXME markers on the project." + echo "You should write them down properly on TODOs.md." + exit 1 +fi + +awk -F'{#' ' +BEGIN { + exitstatus = 0 + h2flag = 0 + h2status = "" + prevline = "" + idx = 0 + delete ids[0] +} +h2flag == 1 { + split($0, l, " ") + timelinestatus = l[2] + if (h2status != timelinestatus) { + print "h2/timeline status mismatch for line " NR-1 + print prevline + print $0 + exitstatus = 1 + } + h2status = "" + h2flag = 0 +} + +/^## (TODO|DOING|WAITING|MEETING|INACTIVE|NEXT|CANCELLED|DONE|WONTFIX)/ { + if (match($0, / \{#.*?\}.*$/) == 0) { + print "Missing ID for line " NR ":\n" $0 + exitstatus = 1 + } + id_with_prefix = substr($2, 0, length($2) - 1) + match(id_with_prefix, /^\w+-/) + id = substr(id_with_prefix, RLENGTH + 1) + if (id in arr) { + print "Duplicate ID: " id + exitstatus = 1 + } else { + arr[id] = 1 + } + + split($0, l, " ") + h2status = l[2] + h2flag = 1 + prevline = $0 +} + + +/^# Scratch$/ { + exit exitstatus +} +' TODOs.md diff --git a/aux/dev.mk b/aux/dev.mk new file mode 100644 index 0000000..8433a49 --- /dev/null +++ b/aux/dev.mk @@ -0,0 +1,101 @@ +.POSIX: + +.SUFFIXES: +.SUFFIXES: .in .md .html + +.in: + sed \ + -e "s:@TLD@:`cat aux/tld.txt`:g" \ + -e "s:@NAME@:`basename $$PWD`:g" \ + -e 's:@MAILING_LIST@:$(MAILING_LIST):g' \ + < $< > $@ + +.in.html: + pandoc -s -r man -w html \ + -H aux/headers.html \ + --metadata lang="`echo $< | awk -F. '{ print $$(NF-2) }'`" \ + < $( $@ + +.md.html: + pandoc -s -r commonmark -w html \ + -H aux/headers.html \ + --metadata lang="`echo $( $@ + +manpages.html = $(manpages.in:.in=.html) + +md_files.html = $(md_files:.md=.html) + +public: manpages.sentinel public/makefile.svg po4a.cfg md.sentinel \ + public/index.html public/ci public/TODOs.html public/style.css \ + public/favicon.svg + touch $@ + +public/index.html: + mkdir -p $(@D) + ln -rs public/en/index.html $@ + +public/ci: + sh aux/ci/report.sh -n `basename "$$PWD"` -o $@ + +public/TODOs.html: TODOs.md aux/preamble-md + mkdir -p $(@D) + td -H | cat aux/preamble-md - | pandoc -s -r commonmark -w html \ + -H aux/headers.html \ + --metadata lang=en \ + --metadata title="`basename $$PWD` - TODOs" \ + --toc --toc-depth=2 \ + --highlight-style pygments \ + > $@ + +public/favicon.svg: aux/favicon.svg + mkdir -p $(@D) + cp aux/favicon.svg $@ + +public/style.css: + mkdir -p $(@D) + td -S > $@ + +md.sentinel: $(md_files.html) + mkdir -p public + sh aux/ext2subdir.sh -o public $? + for d in public/*/; do ln -rfs public/style.css $$d/style.css; done + touch $@ + +manpages.sentinel: $(manpages.html) + mkdir -p public + sh aux/ext2subdir.sh -o public $? + touch $@ + +public/makefile.svg: Makefile + mkdir -p $(@D) + LANG=en.UTF-8 make -Bnd dev | make2graph | dot -Tsvg >$@ + +po4a.cfg: $(en_files) po + sh aux/po4a-cfg.sh -f '$(en_files) aux/checks/manpages/footer.en.0.in' > $@ + + +test-files = \ + aux/checks/changelog.sh \ + aux/checks/manpages.sh \ + aux/checks/readme.sh \ + aux/checks/shellcheck.sh \ + aux/checks/spelling.sh \ + aux/checks/todos.sh \ + aux/checks/repo.sh \ + +$(test-files): ALWAYS manfooter.sentinel + env MAILING_LIST='$(MAILING_LIST)' sh $@ + +aux/checks/assert-manpages.sh: manfooter.sentinel + +manfooter.sentinel: + for f in aux/checks/manpages/*.in; do $(MAKE) -f aux/dev.mk "$${f%.in}"; done + touch $@ + +check: $(test-files) + +ALWAYS: diff --git a/aux/dist.sh b/aux/dist.sh new file mode 100755 index 0000000..def68e6 --- /dev/null +++ b/aux/dist.sh @@ -0,0 +1,88 @@ +#!/bin/sh +set -eu + +usage() { + cat <<-'EOF' + EOF +} + +while getopts 'd:V:n:' flag; do + case "$flag" in + d) + DATE="$OPTARG" + ;; + V) + VVERSION="v$OPTARG" + ;; + n) + NAME="$OPTARG" + ;; + *) + exit 2 + ;; + esac +done +shift $((OPTIND - 1)) + +. aux/lib.sh + +eval "$(assert_arg "${DATE:-}" '-d DATE')" +eval "$(assert_arg "${VVERSION:-}" '-V VERSION')" +eval "$(assert_arg "${NAME:-}" '-n NAME')" + + +if [ "$(git rev-parse --abbrev-ref HEAD)" != 'main' ]; then + echo 'Not on branch "main".' >&2 + exit 1 +fi + +if git show "$VVERSION" 1>/dev/null 2>/dev/null; then + echo "Version '$VVERSION' already exists." >&2 + exit 1 +fi + +if ! printf '%s\n%s\n' "$(git tag)" "$VVERSION" | sort -nct. -k1 -k2 -k3; then + echo 'New tag is not bigger than existing ones.' >&2 + exit 1 +fi + +if [ "$DATE" != "$(git log -1 --format=%ad --date=short HEAD)" ]; then + echo "Date '$DATE' is not up-to-date." >&2 + exit 1 +fi + +if [ "Release $VVERSION" != "$(git log --format=%B -1 HEAD | head -n1)" ]; then + echo "Commit message isn't 'Release $VVERSION'." >&2 + exit 1 +fi + +# FIXME +: make clean check EXTRA_VERSION="$VVERSION" + +if ! (git diff --quiet && git diff --quiet --staged); then + echo 'Dirty repository.' + exit 1 +fi + + +git tag "$VVERSION" +sh aux/workflow/sign-tarballs.sh -n "$NAME" + + +printf 'Publish version? [Y/n]: ' >&2 +read -r publish + +if [ "$publish" = 'n' ]; then + cat <&2 +Now push the tag and the signature before pushing the commit: + +git push origin refs/notes/signatures/tar.gz -o ci.skip --no-verify +git push --tags -o ci.skip --no-verify +git push + +EOF +else + git push origin refs/notes/signatures/tar.gz -o ci.skip --no-verify + git push --tags -o ci.skip --no-verify + git push +fi diff --git a/aux/ext2subdir.sh b/aux/ext2subdir.sh new file mode 100755 index 0000000..4770d1b --- /dev/null +++ b/aux/ext2subdir.sh @@ -0,0 +1,60 @@ +#!/bin/sh +set -eu + +usage() { + cat <<-'EOF' + FIXME + EOF +} + +help() { + cat <<-'EOF' + FIXME + EOF +} + + +for flag in "$@"; do + case "$flag" in + --) + break + ;; + --help) + usage + help + exit + ;; + *) + ;; + esac +done + +while getopts 'o:h' flag; do + case "$flag" in + o) + OUTDIR="$OPTARG" + ;; + h) + usage + help + exit + ;; + *) + usage >&2 + exit 2 + ;; + esac +done +shift $((OPTIND - 1)) + +. aux/lib.sh + +eval "$(assert_arg "${OUTDIR:-}" '-o OUTDIR')" + + +for f in "$@"; do + lang="$(printf '%s' "$(basename "$f")" | sed 's|^.*\.\([a-z][a-z]\)\..*$|\1|')" + f_nolang="$(printf '%s' "$(basename "$f")" | sed "s|\.$lang\.|.|")" + mkdir -p -- "$OUTDIR/$lang" + cp -- "$f" "$OUTDIR/$lang/$f_nolang" +done diff --git a/aux/favicon.svg b/aux/favicon.svg new file mode 100644 index 0000000..ce566b2 --- /dev/null +++ b/aux/favicon.svg @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/aux/headers.html b/aux/headers.html new file mode 100644 index 0000000..1686e45 --- /dev/null +++ b/aux/headers.html @@ -0,0 +1,2 @@ + + diff --git a/aux/lib.sh b/aux/lib.sh index 2276681..f168294 100644 --- a/aux/lib.sh +++ b/aux/lib.sh @@ -1,6 +1,8 @@ #!/bin/sh TLD="$(cat aux/tld.txt)" +NAME="$(basename "$PWD")" +export TLD NAME assert_arg() { if [ -z "$1" ]; then diff --git a/aux/po4a-cfg.sh b/aux/po4a-cfg.sh new file mode 100755 index 0000000..11e51aa --- /dev/null +++ b/aux/po4a-cfg.sh @@ -0,0 +1,85 @@ +#!/bin/sh +set -eu + +usage() { + cat <<-'EOF' + FIXME + EOF +} + +help() { + cat <<-'EOF' + FIXME + EOF +} + + +for flag in "$@"; do + case "$flag" in + --) + break + ;; + --help) + usage + help + exit + ;; + *) + ;; + esac +done + +while getopts 'f:L:h' flag; do + case "$flag" in + f) + FILES="$OPTARG" + ;; + h) + usage + help + exit + ;; + *) + usage >&2 + exit 2 + ;; + esac +done +shift $((OPTIND - 1)) + +. aux/lib.sh + + +files() { + printf '%s' "${FILES:-}" | tr ' ' '\n' | grep . +} + +guess_type() { + case "$1" in + *.md) + echo text + ;; + *.[1-9]*.in) + echo man + ;; + *) + echo text + ;; + esac +} + + +cat <<-'EOF' + [options] --keep 0 --master-charset UTF-8 --localized-charset UTF-8 + + [po_directory] po + +EOF + +files | while read -r file; do + TYPE="$(guess_type "$file")" + # shellcheck disable=2016 + VAR_FILE="$(printf '%s' "$file" | sed 's|\.en\.|.$lang.|')" + # shellcheck disable=2016 + printf '[type: %s] %s $lang:%s\n' "$TYPE" "$file" "$VAR_FILE" +done diff --git a/aux/preamble-md.in b/aux/preamble-md.in new file mode 100644 index 0000000..9255261 --- /dev/null +++ b/aux/preamble-md.in @@ -0,0 +1,14 @@ +# About + +TODOs for [@NAME@](https://@TLD@/@NAME@/en/). + +Register a new one at +[~euandreh/@MAILING_LIST@@lists.sr.ht](mailto:~euandreh/@MAILING_LIST@@lists.sr.ht?subject=%5B@NAME@%5D%20BUG%20or%20TASK%3A%20%3Cdescription%3E) +and see [existing discussions](https://lists.sr.ht/~euandreh/@MAILING_LIST@?search=%5B@NAME@%5D). + +*Você também pode escrever em português*. + +*Vous pouvez aussi écrire en français*. + +*Vi povas ankaŭ skribi esperante*. + diff --git a/aux/sign-tarballs.sh b/aux/sign-tarballs.sh new file mode 100755 index 0000000..3ab2bb8 --- /dev/null +++ b/aux/sign-tarballs.sh @@ -0,0 +1,38 @@ +#!/bin/sh +set -eu + +while getopts 'n:' flag; do + case "$flag" in + n) + PROJECT="$OPTARG" + ;; + *) + exit 2 + ;; + esac +done +shift $((OPTIND -1)) + +assert_arg() { + if [ -z "$1" ]; then + echo "Missing $2" >&2 + exit 2 + fi +} + +assert_arg "${PROJECT:-}" '-n PROJECT' + + +SIGNATURES="$(git notes --ref=refs/notes/signatures/tar.gz list | cut -d\ -f2)" +for tag in $(git tag); do + COMMIT="$(git rev-list -n1 "$tag")" + if echo "$SIGNATURES" | grep -qF "$COMMIT"; then + continue + fi + echo "Adding missing signature to $tag" >&2 + git notes --ref=refs/notes/signatures/tar.gz add -C "$( + git archive --format tar.gz --prefix "$PROJECT-$tag/" "$tag" | + gpg --output - --armor --detach-sign | + git hash-object -w --stdin + )" "$tag" +done diff --git a/aux/workflow/TODOs.sh b/aux/workflow/TODOs.sh deleted file mode 100755 index efc0b04..0000000 --- a/aux/workflow/TODOs.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/sh -set -eu - -TLD="$(cat aux/tld.txt)" -PROJECT_UC= -while getopts 'n:N:m:o:' flag; do - case "$flag" in - n) - PROJECT="$OPTARG" - ;; - N) - PROJECT_UC="$OPTARG" - ;; - m) - MAILING_LIST="$OPTARG" - ;; - o) - OUTDIR="$OPTARG" - ;; - *) - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - -assert_arg() { - if [ -z "$1" ]; then - echo "Missing $2" >&2 - exit 2 - fi -} - -assert_arg "${PROJECT:-}" '-n PROJECT' -assert_arg "${MAILING_LIST:-}" '-m MAILING_LIST' -assert_arg "${OUTDIR:-}" '-o OUTDIR' - -if [ -z "${PROJECT_UC:-}" ]; then - PROJECT_UC="$PROJECT" -fi - - -# shellcheck disable=1004 -IDS_REGEX='s:^## \(TODO\|DOING\|WAITING\|MEETING\|INACTIVE\|NEXT\|CANCELLED\|DONE\|WONTFIX\) \(.*\) {#\(.*\)}\(.*\)$:## \1 \2\4\ -
#\3
\ -:g' -TAGS_REGEX='s|tag:\([a-z0-9-]*\)|\1|g' - -cat aux/workflow/preamble.md TODOs.md | - sed \ - -e "s:@PROJECT_UC@:$PROJECT_UC:g" \ - -e "s:@PROJECT@:$PROJECT:g" \ - -e "s:@MAILING_LIST@:$MAILING_LIST:g" \ - -e "s:@TLD@:$TLD:g" \ - -e "$IDS_REGEX" \ - -e "$TAGS_REGEX" | - pandoc \ - --toc \ - --highlight-style pygments \ - --toc-depth=2 \ - -s \ - --metadata title="$PROJECT_UC - TODOs" \ - --metadata lang=en \ - -r commonmark \ - -w html \ - -H aux/workflow/favicon.html \ - -H aux/workflow/style.css | - sed \ - -e 's:::g' \ - > "$OUTDIR/TODOs.html" diff --git a/aux/workflow/assert-changelog.sh b/aux/workflow/assert-changelog.sh deleted file mode 100755 index 4acc81b..0000000 --- a/aux/workflow/assert-changelog.sh +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh -set -eu - -TLD="$(cat aux/tld.txt)" -PROJECT_UC= -while getopts 'n:N:' flag; do - case "$flag" in - n) - PROJECT="$OPTARG" - ;; - N) - PROJECT_UC="$OPTARG" - ;; - *) - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - -assert_arg() { - if [ -z "$1" ]; then - echo "Missing $2" >&2 - exit 2 - fi -} - -assert_arg "${PROJECT:-}" '-n PROJECT' - -if [ -z "${PROJECT_UC:-}" ]; then - PROJECT_UC="$PROJECT" -fi - -HOMEPAGE_LINK="Changelog for [$PROJECT_UC](https://$TLD/$PROJECT/en/)." - -if ! grep -qF "$HOMEPAGE_LINK" CHANGELOG.md; then - echo "Missing link to homepage in CHANGELOG.md:" >&2 - echo "$HOMEPAGE_LINK" - exit 1 -fi - -assert() { - DATE="$1" - VVERSION="$2" - VERSION="${2#v}" - CHANGELOG_ENTRY="$(printf \ - '# [%s](https://git.euandreh.xyz/%s/commit/?id=%s) - %s' \ - "$VERSION" "$PROJECT" "$VVERSION" "$DATE")" - if ! grep -qF "$CHANGELOG_ENTRY" CHANGELOG.md; then - echo "Missing '$CHANGELOG_ENTRY' entry from CHANGELOG.md" >&2 - exit 1 - fi -} - -if [ -e .git ]; then - for VVERSION in $(git tag); do - DATE="$(git log -1 --format=%cd --date=short "$VVERSION")" - assert "$DATE" "$VVERSION" - done -fi - -# "$@" represents a list of tags to be also included in the verification. -for VVERSION in "$@"; do - DATE="$(date '+%Y-%m-%d')" - assert "$DATE" "$VVERSION" -done diff --git a/aux/workflow/assert-manpages.sh b/aux/workflow/assert-manpages.sh deleted file mode 100755 index f9a6807..0000000 --- a/aux/workflow/assert-manpages.sh +++ /dev/null @@ -1,220 +0,0 @@ -#!/bin/sh -set -eu - -TLD="$(cat aux/tld.txt)" -. aux/lib.sh - -IN_PLACE=false -while getopts 'l:n:m:i' flag; do - case "$flag" in - n) - PROJECT="$OPTARG" - ;; - m) - MAILING_LIST="$OPTARG" - ;; - i) - IN_PLACE=true - ;; - l) - LANGS="$OPTARG" - ;; - *) - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - -assert_arg() { - if [ -z "$1" ]; then - echo "Missing $2" >&2 - exit 2 - fi -} - -assert_arg "${PROJECT:-}" '-n PROJECT' -assert_arg "${MAILING_LIST:-}" '-m MAILING_LIST' -assert_arg "${LANGS:-}" '-l LANGS' - - -EXPECTED_EN="$(mkstemp)" -cat <> "$EXPECTED_EN" - - -.SH AUTHORS - -.MT eu@euandre.org -EuAndreh -.ME -and contributors. - - -.SH BUGS - -.IP \(bu -Report bugs to the -.MT ~euandreh/$MAILING_LIST@lists.sr.ht -mailing list -.ME . -Use the subject "\f(CR[$PROJECT] BUG or TASK: -\fR". -.IP \(bu -Browse bugs -.UR https://$TLD/$PROJECT/TODOs.html -online -.UE . -.IP \(bu -.UR https://$TLD/$PROJECT/en/ -Homepage -.UE . -.IP \(bu -.UR https://lists.sr.ht/~euandreh/$MAILING_LIST?search=%5B$PROJECT%5D -Comments and discussions -.UE . -EOF - -EXPECTED_PT="$(mkstemp)" -cat <> "$EXPECTED_PT" - - -.SH AUTORES - -.MT eu@euandre.org -EuAndreh -.ME -e colaboradores. - - -.SH BUGS - -.IP \(bu -Relate bugs na -.MT ~euandreh/$MAILING_LIST@lists.sr.ht -lista de discussão -.ME . -Use o assunto "\f(CR[$PROJECT] BUG ou TASK: -\fR". -.IP \(bu -Veja os bugs -.UR https://$TLD/$PROJECT/TODOs.html -online -.UE . -.IP \(bu -.UR https://$TLD/$PROJECT/pt/ -Página inicial -.UE . -.IP \(bu -.UR https://lists.sr.ht/~euandreh/$MAILING_LIST?search=%5B$PROJECT%5D -Comentários e discussões -.UE . -EOF - -EXPECTED_FR="$(mkstemp)" -cat <> "$EXPECTED_FR" - - -.SH AUTEURS - -.MT eu@euandre.org -EuAndreh -.ME -et les contributeurs. - - -.SH BUGS - -.IP \(bu -Soumettre un bogue dans la -.MT ~euandreh/$MAILING_LIST@lists.sr.ht -liste -de diffusion -.ME . -Utilise le sujet "\f(CR[$PROJECT] BUG ou TASK: -\fR". -.IP \(bu -Parcourir les bogues -.UR https://$TLD/$PROJECT/TODOs.html -en -ligne -.UE . -.IP \(bu -.UR https://$TLD/$PROJECT/fr/ -Page d'accueil -.UE . -.IP \(bu -.UR https://lists.sr.ht/~euandreh/$MAILING_LIST?search=%5B$PROJECT%5D -Commentaires et discussions -.UE . -EOF - -EXPECTED_EO="$(mkstemp)" -cat <> "$EXPECTED_EO" - - -.SH AŬTOROJ - -.MT eu@euandre.org -EuAndreh -.ME -kaj la kontribuuloj. - - -.SH MISFUNKCIOJ - -.IP \(bu -Raportu misfunkcioj al la -.MT ~euandreh/$MAILING_LIST@lists.sr.ht -dissendolisto -.ME . -Uzu la subjekton "\f(CR[$PROJECT] BUG aŭ TASK: -\fR". -.IP \(bu -Foliumu misfunkcioj -.UR https://$TLD/$PROJECT/TODOs.html -rete -.UE . -.IP \(bu -.UR https://$TLD/$PROJECT/eo/ -Ĉefpaĝo -.UE . -.IP \(bu -.UR https://lists.sr.ht/~euandreh/$MAILING_LIST?search=%5B$PROJECT%5D -Komentoj kaj diskutoj -.UE . -EOF - - -for from_f in "$@"; do - for lang in $LANGS; do - case "$lang" in - en) - EXPECTED="$EXPECTED_EN" - ;; - pt) - EXPECTED="$EXPECTED_PT" - ;; - fr) - EXPECTED="$EXPECTED_FR" - ;; - eo) - EXPECTED="$EXPECTED_EO" - ;; - *) - printf 'Unsupported lang: %s\n' "$lang" >&2 - exit 2 - ;; - esac - - f="$(echo "$from_f" | sed "s/\.en\./.$lang./")" - if ! tail -n "$(wc -l < "$EXPECTED")" "$f" | - diff - "$EXPECTED"; then - echo "Missing metadata at the end of \"$f\" file" - if [ "$IN_PLACE" = true ]; then - cat "$EXPECTED" >> "$f" - else - exit 1 - fi - fi - done -done diff --git a/aux/workflow/assert-readme.sh b/aux/workflow/assert-readme.sh deleted file mode 100755 index 1e49bfb..0000000 --- a/aux/workflow/assert-readme.sh +++ /dev/null @@ -1,108 +0,0 @@ -#!/bin/sh -set -eu - -if [ ! -e .git ]; then - exit -fi - -TLD="$(cat aux/tld.txt)" -. aux/lib.sh - -while getopts 'n:m:' flag; do - case "$flag" in - n) - PROJECT="$OPTARG" - ;; - m) - MAILING_LIST="$OPTARG" - ;; - *) - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - -assert_arg() { - if [ -z "$1" ]; then - echo "Missing $2" >&2 - exit 2 - fi -} - -assert_arg "${PROJECT:-}" '-n PROJECT' -assert_arg "${MAILING_LIST:-}" '-m MAILING_LIST' - -EXPECTED="$(mkstemp)" -cat <> "$EXPECTED" - -For running the extra development-only checks, run: - -\`\`\`shell -$ make dev-check -\`\`\` - -and for generating the documentation HTML and website, run: - -\`\`\`shell -$ make public -\`\`\` - -Send contributions to the [mailing list] via -[\`git send-email\`](https://git-send-email.io/). - - -## Links - -- [homepage](https://$TLD/$PROJECT/en/) -- [source code](https://git.euandreh.xyz/$PROJECT/) -- [bug tracking](https://$TLD/$PROJECT/TODOs.html) -- [mailing list] -- [CI logs](https://$TLD/$PROJECT/ci.html) -- [CHANGELOG](https://$TLD/$PROJECT/en/CHANGELOG.html) - -[mailing list]: https://lists.sr.ht/~euandreh/$MAILING_LIST?search=%5B$PROJECT%5D -EOF - -RELEASES_LIST="$(mkstemp)" -add_release() { - DATE="$1" - VVERSION="$2" - echo "- [$VVERSION](https://git.euandreh.xyz/$PROJECT/commit/?id=$VVERSION) [$PROJECT-$VVERSION.tar.gz](https://git.euandreh.xyz/$PROJECT/snapshot/$PROJECT-$VVERSION.tar.gz) ([sig](https://git.euandreh.xyz/$PROJECT/snapshot/$PROJECT-$VVERSION.tar.gz.asc)) - $DATE" >> "$RELEASES_LIST" -} - -for VVERSION in $(git tag); do - DATE="$(git log -1 --format=%cd --date=short "$VVERSION")" - add_release "$DATE" "$VVERSION" -done - -# "$@" represents a list of tags to be also included in the verification. -for VVERSION in "$@"; do - if ! git tag | grep -qF "$VVERSION"; then - DATE="$(date '+%Y-%m-%d')" - add_release "$DATE" "$VVERSION" - fi -done - -if [ -s "$RELEASES_LIST" ]; then - printf '\n\n## Releases\n\n' >> "$EXPECTED" - sort -r "$RELEASES_LIST" >> "$EXPECTED" -fi - -cat <> "$EXPECTED" - - -## License - -The code is licensed under -[GNU Affero General Public License v3.0 or later][AGPL-3.0-or-later] -(AGPL-3.0-or-later). - -[AGPL-3.0-or-later]: https://git.euandreh.xyz/$PROJECT/tree/COPYING -EOF - -if ! tail -n "$(wc -l < "$EXPECTED")" README.md | diff - "$EXPECTED"; then - echo 'Wrong metadata at the end of README.md file' - echo "See expected content at: $EXPECTED" - exit 1 -fi diff --git a/aux/workflow/assert-spelling.sh b/aux/workflow/assert-spelling.sh deleted file mode 100755 index 853fd5e..0000000 --- a/aux/workflow/assert-spelling.sh +++ /dev/null @@ -1,78 +0,0 @@ -#!/bin/sh -set -eu - -. aux/lib.sh - -sort_dicts() { - for f in po/spelling/*.txt; do - if LANG=POSIX sort "$f" | diff - "$f"; then - echo continue - fi - if [ "$IN_PLACE" = true ]; then - OUT="$(mkstemp)" - LANG=POSIX sort "$f" | uniq > "$OUT" - mv "$OUT" "$f" - else - printf 'The %s dictionary is unsorted.' "$f" >&2 - printf " To fix it, run:\n" >&2 - printf " sh aux/workflow/assert-spelling.sh -i" >&2 - exit 1 - fi - done -} - -IN_PLACE=false -while getopts 'l:i' flag; do - case "$flag" in - l) - LANGS="$OPTARG" - ;; - i) - IN_PLACE=true - sort_dicts - exit - ;; - *) - exit 2 - ;; - esac -done -shift $((OPTIND -1)) - -assert_arg() { - if [ -z "$1" ]; then - echo "Missing $2" >&2 - exit 2 - fi -} - -assert_arg "${LANGS:-}" '-l LANGS' - -mkdir -p po/spelling -eval "touch po/spelling/{international,$(echo "$LANGS" | tr ' ' ,)}.txt" - -get_lang() { - grep lang=.. "$1" | - head -n1 | - awk ' - match($0, /lang="(..)"/) { - print substr($0, RSTART+length("lang=\""), 2) - } - ' -} - -ACC="$(mkstemp)" -for f in "$@"; do - l="$(get_lang "$f")" - CURR_DICT="$(mkstemp)" - cat po/spelling/international.txt "po/spelling/$l.txt" | - sort | uniq > "$CURR_DICT" - hunspell -u3 -H -d "$l" -p "$CURR_DICT" "$f" | tee -a "$ACC" >&2 -done - -if [ -s "$ACC" ]; then - printf '\n\tMispelled words detected by hunspell above.\n\n' >&2 - exit 1 -fi - -sort_dicts diff --git a/aux/workflow/assert-todos.sh b/aux/workflow/assert-todos.sh deleted file mode 100755 index bc4907d..0000000 --- a/aux/workflow/assert-todos.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/bin/sh -set -eu - -if [ -e .git ] && git grep FIXME | grep -v '^TODOs.md' | - grep -v '^aux/workflow/assert-todos.sh'; then - echo "Found dangling FIXME markers on the project." - echo "You should write them down properly on TODOs.md." - exit 1 -fi - -awk -F'{#' ' -BEGIN { - exitstatus = 0 - h2flag = 0 - h2status = "" - prevline = "" - idx = 0 - delete ids[0] -} -h2flag == 1 { - split($0, l, " ") - timelinestatus = l[2] - if (h2status != timelinestatus) { - print "h2/timeline status mismatch for line " NR-1 - print prevline - print $0 - exitstatus = 1 - } - h2status = "" - h2flag = 0 -} - -/^## (TODO|DOING|WAITING|MEETING|INACTIVE|NEXT|CANCELLED|DONE|WONTFIX)/ { - if (match($0, / \{#.*?\}.*$/) == 0) { - print "Missing ID for line " NR ":\n" $0 - exitstatus = 1 - } - id_with_prefix = substr($2, 0, length($2) - 1) - match(id_with_prefix, /^\w+-/) - id = substr(id_with_prefix, RLENGTH + 1) - if (id in arr) { - print "Duplicate ID: " id - exitstatus = 1 - } else { - arr[id] = 1 - } - - split($0, l, " ") - h2status = l[2] - h2flag = 1 - prevline = $0 -} - - -/^# Scratch$/ { - exit exitstatus -} -' TODOs.md diff --git a/aux/workflow/commonmark.sh b/aux/workflow/commonmark.sh deleted file mode 100755 index 6f5e59b..0000000 --- a/aux/workflow/commonmark.sh +++ /dev/null @@ -1,42 +0,0 @@ -#!/bin/sh -set -eu - -while getopts 'N:t:l:' flag; do - case "$flag" in - N) - PROJECT_UC="$OPTARG" - ;; - t) - TITLE="$OPTARG" - ;; - l) - THE_LANG="$OPTARG" - ;; - *) - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - -assert_arg() { - if [ -z "$1" ]; then - echo "Missing $2" >&2 - exit 2 - fi -} - -assert_arg "${PROJECT_UC:-}" '-N PROJECT_UC' -assert_arg "${TITLE:-}" '-t TITLE' -assert_arg "${THE_LANG:-}" '-l THE_LANG' - -pandoc \ - --toc \ - --highlight-style pygments \ - --toc-depth=2 \ - -s \ - --metadata title="$PROJECT_UC - $TITLE" \ - --metadata "lang=$THE_LANG" \ - -r commonmark \ - -w html \ - -H aux/workflow/favicon.html diff --git a/aux/workflow/dist.sh b/aux/workflow/dist.sh deleted file mode 100755 index c1c0342..0000000 --- a/aux/workflow/dist.sh +++ /dev/null @@ -1,99 +0,0 @@ -#!/bin/sh -set -eu - -PROJECT_UC= -while getopts 'd:V:n:N:m:' flag; do - case "$flag" in - d) - DATE="$OPTARG" - ;; - V) - VVERSION="v$OPTARG" - ;; - n) - PROJECT="$OPTARG" - ;; - N) - PROJECT_UC="$OPTARG" - ;; - m) - MAILING_LIST="$OPTARG" - ;; - *) - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - -assert_arg() { - if [ -z "$1" ]; then - echo "Missing $2" >&2 - exit 2 - fi -} - -assert_arg "${DATE:-}" '-d DATE' -assert_arg "${VVERSION:-}" '-V VERSION' -assert_arg "${PROJECT:-}" '-n PROJECT' -assert_arg "${MAILING_LIST:-}" '-m MAILING_LIST' - -if [ -z "${PROJECT_UC:-}" ]; then - PROJECT_UC="$PROJECT" -fi - - -if [ "$(git rev-parse --abbrev-ref HEAD)" != 'main' ]; then - echo 'Not on branch "main".' >&2 - exit 1 -fi - -if git show "$VVERSION" 1>/dev/null 2>/dev/null; then - echo "Version '$VVERSION' already exists." >&2 - exit 1 -fi - -if ! printf '%s\n%s\n' "$(git tag)" "$VVERSION" | sort -nct. -k1 -k2 -k3; then - echo 'New tag is not bigger than existing ones.' >&2 - exit 1 -fi - -if [ "$DATE" != "$(git log -1 --format=%ad --date=short HEAD)" ]; then - echo "Date '$DATE' is not up-to-date." >&2 - exit 1 -fi - -if [ "Release $VVERSION" != "$(git log --format=%B -1 HEAD | head -n1)" ]; then - echo "Commit message isn't 'Release $VVERSION'." >&2 - exit 1 -fi - -: make clean check EXTRA_VERSION="$VVERSION" - -if ! (git diff --quiet && git diff --quiet --staged); then - echo 'Dirty repository.' - exit 1 -fi - - -git tag "$VVERSION" -sh aux/workflow/sign-tarballs.sh -n "$PROJECT" - - -printf 'Publish version? [Y/n]: ' >&2 -read -r publish - -if [ "$publish" = 'n' ]; then - cat <&2 -Now push the tag and the signature before pushing the commit: - -git push origin refs/notes/signatures/tar.gz -o ci.skip --no-verify -git push --tags -o ci.skip --no-verify -git push - -EOF -else - git push origin refs/notes/signatures/tar.gz -o ci.skip --no-verify - git push --tags -o ci.skip --no-verify - git push -fi diff --git a/aux/workflow/favicon.html b/aux/workflow/favicon.html deleted file mode 100644 index 8f9327c..0000000 --- a/aux/workflow/favicon.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/aux/workflow/favicon.svg b/aux/workflow/favicon.svg deleted file mode 100644 index ce566b2..0000000 --- a/aux/workflow/favicon.svg +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/aux/workflow/l10n.sh b/aux/workflow/l10n.sh deleted file mode 100755 index 1002adc..0000000 --- a/aux/workflow/l10n.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/sh -set -eu - -LANGS= -while getopts 'l:L:' flag; do - case "$flag" in - l) - LANGS="$OPTARG" - ;; - L) - CONTRIBLANGS="$OPTARG" - ;; - *) - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - -assert_arg() { - if [ -z "$1" ]; then - echo "Missing $2" >&2 - exit 2 - fi -} - -assert_arg "${LANGS:-}" '-l LANGS' - -for from_f in "$@"; do - for lang in $LANGS ${CONTRIBLANGS:-}; do - to_f="$(echo "$from_f" | sed "s/\.en\./.$lang./")" - printf 'Generating %s...\n' "$to_f" >&2 - pofile="po/LC_MESSAGES/$from_f/$lang.po" - mkdir -p "$(dirname "$pofile")" - - case "$from_f" in - *.en.[1-9].in) - po4a-updatepo -f man -m "$from_f" -p "$pofile" - po4a-translate -f man -m "$from_f" \ - -p "$pofile" -l "$to_f" -k 0 -v >&2 - ;; - *.en.html) - po4a-updatepo -f xhtml -m "$from_f" -p "$pofile" - po4a-translate -f xhtml -m "$from_f" \ - -p "$pofile" -l "$to_f" -k 0 -v >&2 - ;; - *.en.md) - touch "$pofile" - md2po --include-codeblocks --quiet --save \ - --po-filepath "$pofile" < "$from_f" - po2md --pofiles "$pofile" --save "$to_f" \ - --quiet < "$from_f" - ;; - *) - echo "Unsupported file format: $from_f" >&2 - exit 2 - ;; - esac - done -done - -end="\033[0m" -yellowb="\033[1;33m" -for lang in $LANGS; do - # shellcheck disable=2044 - for pofile in $(find po/ -type f -name "$lang.po"); do - if ! LANG=POSIX msgfmt --statistics "$pofile" 2>&1 | - grep untranslated; then - continue - fi - # shellcheck disable=2059 - printf "\n ${yellowb}WARNING${end}!" >&2 - printf "\n Missing translations for %s\n\n" "$pofile" >&2 - done -done diff --git a/aux/workflow/preamble.md b/aux/workflow/preamble.md deleted file mode 100644 index ee32d58..0000000 --- a/aux/workflow/preamble.md +++ /dev/null @@ -1,14 +0,0 @@ -# About - -TODOs for [@PROJECT_UC@](https://@TLD@/@PROJECT@/en/). - -Register a new one at -[~euandreh/@MAILING_LIST@@lists.sr.ht](mailto:~euandreh/@MAILING_LIST@@lists.sr.ht?subject=%5B@PROJECT@%5D%20BUG%20or%20TASK%3A%20%3Cdescription%3E) -and see [existing discussions](https://lists.sr.ht/~euandreh/@MAILING_LIST@?search=%5B@PROJECT@%5D). - -*Você também pode escrever em português*. - -*Vous pouvez aussi écrire en français*. - -*Vi povas ankaŭ skribi esperante*. - diff --git a/aux/workflow/public.sh b/aux/workflow/public.sh deleted file mode 100755 index 38613de..0000000 --- a/aux/workflow/public.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/sh -set -eu - -PROJECT_UC= -while getopts 'n:N:m:o:l:' flag; do - case "$flag" in - n) - PROJECT="$OPTARG" - ;; - N) - PROJECT_UC="$OPTARG" - ;; - m) - MAILING_LIST="$OPTARG" - ;; - o) - OUTDIR="$OPTARG" - ;; - l) - LANGS="$OPTARG" - ;; - *) - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - -assert_arg() { - if [ -z "$1" ]; then - echo "Missing $2" >&2 - exit 2 - fi -} - -assert_arg "${PROJECT:-}" '-n PROJECT' -assert_arg "${MAILING_LIST:-}" '-m MAILING_LIST' -assert_arg "${OUTDIR:-}" '-o OUTDIR' -assert_arg "${LANGS:-}" '-l LANGS' -PROJECT_UC="${PROJECT_UC:-$PROJECT}" - -mkdir -p "$OUTDIR" - -sh aux/workflow/TODOs.sh \ - -N "$PROJECT_UC" -n "$PROJECT" -m "$MAILING_LIST" -o "$OUTDIR" - -for lang in $LANGS; do - mkdir -p "$OUTDIR/$lang/" - sh aux/workflow/commonmark.sh -N "$PROJECT" -t README -l "$lang" \ - < "README.$lang.md" > "$OUTDIR/$lang/index.html" - sh aux/workflow/commonmark.sh -N "$PROJECT" -t CHANGELOG -l "$lang" \ - < "CHANGELOG.$lang.md" > "$OUTDIR/$lang/CHANGELOG.html" - ln -fs ../favicon.svg "$OUTDIR/$lang" -done - -ln -fs en/index.html "$OUTDIR/index.html" -cp aux/workflow/favicon.svg "$OUTDIR" - -sh aux/ci/report.sh -n "$PROJECT" -o "$OUTDIR" diff --git a/aux/workflow/repocheck.sh b/aux/workflow/repocheck.sh deleted file mode 100755 index 688410a..0000000 --- a/aux/workflow/repocheck.sh +++ /dev/null @@ -1,184 +0,0 @@ -#!/bin/sh -set -eu - -if [ -n "${RECURSIVE_CHECK:-}" ]; then - exit -fi -export RECURSIVE_CHECK=true - -. aux/lib.sh - -REPODIR="$PWD" - -INSTALLCHECK=false -while getopts 'x:l:f:' flag; do - case "$flag" in - x) - EXECUTABLES="$OPTARG" - INSTALLCHECK=true - ;; - l) - SYMLINKS="$OPTARG" - INSTALLCHECK=true - ;; - f) - FILES="$OPTARG" - INSTALLCHECK=true - ;; - *) - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - -assert_no_diffs() { - if [ -n "$(git status -s)" ]; then - echo 'Repository left dirty.' >&2 - git status >&2 - exit 1 - fi -} - -assert_installed_files() { - if [ -n "${EXECUTABLES:-}" ]; then - ACTUAL="$(find "$1" -type f -perm -u=x | wc -l)" - if [ "$EXECUTABLES" != "$ACTUAL" ]; then - printf 'Expected %s executables, found %s:\n' \ - "$EXECUTABLES" "$ACTUAL" >&2 - echo "find $1 -type f -perm -u=x:" >&2 - find "$1" -type f -perm -u=x >&2 - exit 1 - fi - fi - - if [ -n "${SYMLINKS:-}" ]; then - ACTUAL="$(find "$1" -type l | wc -l)" - if [ "$SYMLINKS" != "$ACTUAL" ]; then - printf 'Expected %s symlinks, found %s:\n' \ - "$SYMLINKS" "$ACTUAL" >&2 - echo "find $1 -type l:" >&2 - find "$1" -type l >&2 - exit 1 - fi - fi - - if [ -n "${FILES:-}" ]; then - ACTUAL="$(find "$1" -type f | wc -l)" - if [ "$FILES" != "$ACTUAL" ]; then - printf 'Expected %s files, found %s:\n' \ - "$FILES" "$ACTUAL" >&2 - echo "find $1 -type f:" >&2 - find "$1" -type f >&2 - exit 1 - fi - fi -} - -assert_uninstalled_files() { - if [ "$(find "$1" \( -type f -o -type l \) | wc -l)" != 0 ]; then - echo 'Left-over files after uninstall' >&2 - echo "find $1 \( -type f -o -type l \):" - find "$1" \( -type f -o -type l \) - exit 1 - fi -} - -assert_install() { - if [ "$INSTALLCHECK" != 'true' ]; then - return - fi - - make clean - - echo 'Asserting "canonical" install path' >&2 - INSTALL1="$(mkdtemp)" - make PREFIX="$INSTALL1" - make check PREFIX="$INSTALL1" - make install PREFIX="$INSTALL1" - assert_installed_files "$INSTALL1" - make uninstall PREFIX="$INSTALL1" - assert_uninstalled_files "$INSTALL1" - - make clean - - echo 'Asserting "straigh-forward" install path' >&2 - INSTALL2="$(mkdtemp)" - make install PREFIX="$INSTALL2" - assert_installed_files "$INSTALL2" - make uninstall PREFIX="$INSTALL2" - assert_uninstalled_files "$INSTALL2" - - make clean - - echo 'Asserting "idempotent" install path' >&2 - INSTALL3="$(mkdtemp)" - make install PREFIX="$INSTALL3" - make install PREFIX="$INSTALL3" - assert_installed_files "$INSTALL3" - make uninstall PREFIX="$INSTALL3" - make uninstall PREFIX="$INSTALL3" - assert_uninstalled_files "$INSTALL3" - - make clean - - echo 'Asserting "destdir" install path' >&2 - DESTDIR="$(mkdtemp)" - INSTALL4="$(mkdtemp)" - make install DESTDIR="$DESTDIR" PREFIX="$INSTALL4" - assert_installed_files "$DESTDIR/$INSTALL4" - make uninstall DESTDIR="$DESTDIR" PREFIX="$INSTALL4" - assert_uninstalled_files "$DESTDIR/$INSTALL4" -} - -assert_clean_clone() { - CLONEDIR="$(mkdtemp)" - cd "$CLONEDIR" - - git clone "$REPODIR" . - - make clean public dev-check - assert_no_diffs - make clean - assert_no_diffs - - if [ -n "$(git clean -ffdx --dry-run)" ]; then - echo '"make clean" left files:' >&2 - git clean -ffdx --dry-run >&2 - echo "Clone directory: $CLONEDIR" >&2 - exit 1 - fi - - rm -rf aux/ - make clean check || { - echo 'Cannot run "make check" without "aux/".' >&2 - echo "Clone directory: $CLONEDIR" >&2 - exit 1 - } - - assert_install - - cd - > /dev/null -} - -assert_clean_checkout() { - CHECKOUTDIR="$(mkdtemp)" - git --work-tree="$CHECKOUTDIR" checkout HEAD -- . - cd "$CHECKOUTDIR" - - FILECOUNT="$(find . -type f | wc -l)" - make clean public dev-check - make clean - if [ "$FILECOUNT" != "$(find . -type f | wc -l)" ]; then - echo 'File count mismatch after "make clean".' >&2 - echo "Checkout directory: $CHECKOUTDIR" >&2 - exit 1 - fi - - assert_install - - cd - > /dev/null -} - -assert_clean_clone -assert_clean_checkout diff --git a/aux/workflow/sign-tarballs.sh b/aux/workflow/sign-tarballs.sh deleted file mode 100755 index 3ab2bb8..0000000 --- a/aux/workflow/sign-tarballs.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh -set -eu - -while getopts 'n:' flag; do - case "$flag" in - n) - PROJECT="$OPTARG" - ;; - *) - exit 2 - ;; - esac -done -shift $((OPTIND -1)) - -assert_arg() { - if [ -z "$1" ]; then - echo "Missing $2" >&2 - exit 2 - fi -} - -assert_arg "${PROJECT:-}" '-n PROJECT' - - -SIGNATURES="$(git notes --ref=refs/notes/signatures/tar.gz list | cut -d\ -f2)" -for tag in $(git tag); do - COMMIT="$(git rev-list -n1 "$tag")" - if echo "$SIGNATURES" | grep -qF "$COMMIT"; then - continue - fi - echo "Adding missing signature to $tag" >&2 - git notes --ref=refs/notes/signatures/tar.gz add -C "$( - git archive --format tar.gz --prefix "$PROJECT-$tag/" "$tag" | - gpg --output - --armor --detach-sign | - git hash-object -w --stdin - )" "$tag" -done diff --git a/aux/workflow/style.css b/aux/workflow/style.css deleted file mode 100644 index d72991e..0000000 --- a/aux/workflow/style.css +++ /dev/null @@ -1,41 +0,0 @@ - -- cgit v1.2.3