commit b9143afb333ff62611a6ebe20661a64fb29bde1b
parent b9c6fc8b784a32c12597b12bcca4aff11518ce66
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 22 Aug 2025 17:09:46 +0200
Add support for hooks by section
These are shell scripts stored in the hook subdirectory of the sections,
executed in lexicographical order so that they are prioritized relative
to each other. Each hook outputs the names of the files it creates as
website resources in order to inform the compilation system that they
must be deployed with the site.
The build system generates Makefile targets to automate the execution of
hooks and the management of their data.
Currently, only one hook is written for solstice. It extracts the
content of the archive needed to generate its web pages.
Diffstat:
7 files changed, 144 insertions(+), 12 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -10,3 +10,5 @@
.lint
tags
man
+*.hook
+.hooks
diff --git a/Makefile b/Makefile
@@ -22,16 +22,21 @@ LINT=$(HTML:.html=.lint) $(SH:.sh=.shlint)
default: build
-build clean distclean lint install:
- @$(MAKE) -fMakefile $@__ \
+build clean distclean lint install: .hooks
+ @$(MAKE) -f.hooks -fMakefile $@__ \
HTML="$$($(SHELL) ./list.sh html | tr '\n' ' ')" \
SIG="$$( $(SHELL) ./list.sh sig | tr '\n' ' ')" \
SH="$$( $(SHELL) ./list.sh shell | tr '\n' ' ')"
+.hooks: hooks.sh
+ $(SHELL) hooks.sh > $@
+
build__: $(HTML) $(SIG)
clean__:
+ rm -f .hooks
rm -f $(HTML)
+ rm -f $(SH:.sh=.md)
distclean__: clean__
rm -f $(SIG)
diff --git a/hooks.sh b/hooks.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+# Copyright (C) 2017-2025 |Méso|Star> (contact@meso-star.com)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+set -e
+
+# Print on standard output the Makefile targets used to automate hook
+# management
+
+sh ./list.sh hook | while read -r i; do
+ # Divide the path into two parts:
+ # - the top-level directory, i.e. the section
+ # - the shell script to be executed from the section directory
+ section="${i%%/*}"
+ hook="${i##"${section}"/}"
+
+ # The hook is the first one in the current section: it has the highest
+ # priority and therefore has no prerequisites.
+ if [ "${section}" != "${prev_section}" ]; then
+ dep=""
+ fi
+
+ # Define a name for the hook used as a prefix for Makefile targets in
+ # order to automate its execution and the management of the file it
+ # generates. To ensure that this name is unique, and thus avoid
+ # conflicts between different hooks, it is constructed from the names
+ # of the section and file corresponding to the hook.
+ file="$(basename "${hook}")"
+ prefix="${section}-${file%%.*}"
+
+ # Set the file in which the names of the files generated by the hook
+ # are stored as resources for the website, i.e., the files that must
+ # be deployed with the website.
+ tgt="${i%%.*}.hook"
+
+ # Define the Makefile target that automate the hook executation. Its
+ # pre-requisites are the hook script and the output of the # previous
+ # hook in the section, i.e. with an higher priority. So that
+ # execution priority is ensured.
+ #
+ # Finally, make this target a prerequisite for building the website
+ # in order to enforce its execution during the build call.
+ printf '%s: %s %s\n' "${tgt}" "${i}" "${dep}"
+ printf " @( cd -- %s && \$(SHELL) %s ) > \$@\n" \
+ "${section}" "${hook}"
+ printf 'build__: %s\n' "${tgt}" #
+
+ # Set the target for cleaning files generated by executing the hook.
+ # Run it on "distclean" and not on "clean", as their generation can be
+ # costly while effectively being files generated to "distribute" the
+ # website.
+ printf '%s-clean:\n' "${prefix}"
+ printf ' if [ -f %s ]; then cat %s | xargs rm -f; fi\n' \
+ "${tgt}" "${tgt}"
+ printf ' rm -f %s\n' "${tgt}"
+ printf 'distclean__: %s-clean\n' "${prefix}"
+
+ # Set the target that installs website resources generated by the hook
+ printf '%s-install: %s\n' "${prefix}" "${tgt}"
+ printf " @rsync --mkpath -avzrR --files-from=%s ./ \$(PREFIX)\n" \
+ "${tgt}"
+ printf 'install__: %s-install\n' "${prefix}"
+
+ # Ensure that the target of the hook is a prerequisite for the next
+ # hook in the section, so that the execution order follows their
+ # priority as defined by their file name.
+ dep="${tgt}"
+ prev_section="${section}"
+done
diff --git a/list.sh b/list.sh
@@ -20,7 +20,7 @@
set -e
if [ "$#" -lt 1 ]; then
- >&2 printf 'usage: %s <html|shell|sig>\n' "${0##*/}"
+ >&2 printf 'usage: %s <html|hook|shell|sig>\n' "${0##*/}"
exit 1
fi
@@ -44,6 +44,20 @@ html()
| sort"
}
+# List of hooks, i.e. shell scripts to be run by section
+hook()
+{
+ _find_args="$(\
+ printf '%s\n' "${sections}" \
+ | sed -e 's/^/-path "/;s/$/\/hooks\/*" -o/' \
+ | tr '\n' ' ' \
+ | sed 's/ -o $//')"
+
+ eval "find ${search_dirs} \
+ \( \( ${_find_args} \) -type f -name \"*.sh\" \) \
+ | sort"
+}
+
# List of signatures to be performed, i.e. the signature of each
# archive stored in the "downloads" subdirectory of each section
sig()
@@ -78,6 +92,10 @@ shell()
| sort"
}
+# List the relevent section subdirectories which are:
+# - downloads
+# - images
+# - thumbs
subdir()
{
downloads="-path \1/downloads"
@@ -96,11 +114,7 @@ subdir()
# Script
########################################################################
# List of sections to be dealt with
-sections="$(\
- strip_dummy < menu.tsv \
- | cut -d' ' -f2 \
- | sed -e 's/[[:space:]]/\ /g')"
-
+sections="$(sections)"
search_dirs="$(printf '%s\n' "${sections}" | tr '\n' ' ')"
"$@"
diff --git a/meso-web.sh b/meso-web.sh
@@ -25,3 +25,14 @@ strip_dummy() # stdin
| sed '/^[[:space:]]\{0,\}$/d' \
| sed -e 's/^[[:space:]]\{1,\}//g' -e 's/[[:space:]]\{1,\}$//g'
}
+
+# List the sections of the menu
+sections()
+{
+ # - Remove irrelevant data from the menu file
+ # - Get the section field
+ # - Protect spaces in the section name
+ strip_dummy < menu.tsv \
+ | cut -d' ' -f2 \
+ | sed -e 's/[[:space:]]/\\ /g'
+}
diff --git a/solstice/hooks/00-extract-archive.sh b/solstice/hooks/00-extract-archive.sh
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# Copyright (C) 2017-2025 |Méso|Star> (contact@meso-star.com)
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+set -e
+
+. "./config.in"
+
+tar -xz -f "${arch}" "${directory}/share/man" "${readme}"
diff --git a/solstice/solstice-downloads.sh b/solstice/solstice-downloads.sh
@@ -117,10 +117,6 @@ print_downloads()
########################################################################
# Generate page content using Markdown formatting
########################################################################
-if ! [ -e "${readme}" ]; then
- tar -xz -f "${arch}" "${readme}"
-fi
-
# Title
echo '# Downloads'