feat/build-improvements-2 (#4553)
All checks were successful
continuous-integration/drone/push Build is passing

Another attempt at #4516

Adds a small fix for tag map generation

#4516 introduces build failures, but testing indicates that those failures would have been resolved by a full rebuild.

Hence this pr.

Co-authored-by: Darragh Elliott <me@delliott.xyz>
Reviewed-on: #4553
Co-authored-by: delliott <delliott@fsfe.org>
Co-committed-by: delliott <delliott@fsfe.org>
This commit is contained in:
delliott 2024-10-29 14:56:41 +00:00 committed by tobiasd
parent fa6c9a7d7c
commit bb45fc85ba
19 changed files with 523 additions and 515 deletions

View File

@ -12,6 +12,7 @@
# This will be overwritten in the command line running this Makefile.
build_env = development
languages = none
# -----------------------------------------------------------------------------
# Build search index
@ -68,7 +69,7 @@ SUBDIRS := $(shell find . -regex "./[a-z\.]+\.[a-z]+/.*/Makefile" | xargs dirnam
all: $(SUBDIRS)
$(SUBDIRS): .FORCE
echo "* Preparing subdirectory $@"
$(MAKE) --silent --directory=$@
$(MAKE) --silent --directory=$@ languages="$(languages)"
# -----------------------------------------------------------------------------
# Create XML symlinks
@ -82,9 +83,7 @@ $(SUBDIRS): .FORCE
# otherwise. This symlinks make sure that phase 2 can easily use the right file
# for each language, also as a prerequisite in the Makefile.
LANGUAGES := $(shell ls -xw0 global/languages)
TEXTS_LINKS := $(foreach lang,$(LANGUAGES),global/data/texts/.texts.$(lang).xml)
TEXTS_LINKS := $(foreach lang,$(languages),global/data/texts/.texts.$(lang).xml)
all: $(TEXTS_LINKS)
global/data/texts/.texts.%.xml: .FORCE
@ -94,7 +93,7 @@ global/data/texts/.texts.%.xml: .FORCE
ln -sf texts.en.xml $@; \
fi
TOPBANNER_LINKS := $(foreach lang,$(LANGUAGES),global/data/topbanner/.topbanner.$(lang).xml)
TOPBANNER_LINKS := $(foreach lang,$(languages),global/data/topbanner/.topbanner.$(lang).xml)
all: $(TOPBANNER_LINKS)
global/data/topbanner/.topbanner.%.xml: .FORCE
@ -134,7 +133,7 @@ default_xsl:
.PHONY: localmenus
all: localmenus
localmenus: $(SUBDIRS)
tools/update_localmenus.sh
tools/update_localmenus.sh "$(languages)"
# -----------------------------------------------------------------------------
# Update XML filelists
@ -155,4 +154,4 @@ localmenus: $(SUBDIRS)
.PHONY: xmllists
all: xmllists
xmllists: $(SUBDIRS)
tools/update_xmllists.sh
tools/update_xmllists.sh "$(languages)"

View File

@ -72,7 +72,7 @@ You can see the current status of translation progress of fsfe.org at [status.fs
## Build
There are two ways to build and develop the directory locally. Initial builds of the webpages may take ~40 minutes, but subsequent builds should be much faster.
There are two ways to build and develop the directory locally. Initial builds of the webpages may take ~40 minutes, but subsequent builds should be much faster. Using the `--languages` flag to avoid building all supported languages can make this much faster. See ./build/README.md for more information.
Alterations to build scripts or the files used site-wide will result in near full rebuilds.

View File

@ -2,26 +2,47 @@
set -euo pipefail
usage() {
echo "Usage: $0 -f|--full -s|--serve" 1>&2
exit 1
cat <<-EOF
# build.sh Usage
## General
This script is a wrapper script over ./build/build_main.sh that provides nicer option names, and the options to serve the files.
For documentation on the build script itself see ./build/README.md
## Flags
### -f | --full
Perform a full rebuild of the webpages.
### -s | --serve
Serve the build webpages over localhost.
### --
Everything after this is passed directly to build_main.
See ./build/README.md for valid options.
EOF
exit 1
}
command="build_run"
serve=""
extra_args=""
while [ "$#" -gt 0 ]; do
case "$1" in
--full | -f)
command="build_into" && shift 1
;;
--serve | -s)
serve="true" && shift 1
;;
*)
usage
;;
esac
case "$1" in
--full | -f)
command="build_into" && shift 1
;;
--serve | -s)
serve="true" && shift 1
;;
--)
shift 1
while [ "$#" -gt 0 ]; do
extra_args+="$1 "
shift 1
done
;;
*)
usage
;;
esac
done
mkdir -p ./output
./build/build_main.sh "$command" ./output/final --statusdir ./output/final/status.fsfe.org/fsfe.org/data
./build/build_main.sh "$command" ./output/final --statusdir ./output/final/status.fsfe.org/fsfe.org/data $extra_args
if [[ "$serve" ]]; then
python3 ./serve-websites.py
python3 ./serve-websites.py
fi

View File

@ -1,58 +0,0 @@
Usage:
------------------------------------------------------------------------------
build_main.sh [options] build_into "destination_dir"
Perform the page build. Write output to destination_dir. The source
directory is determined from the build scripts own location.
build_main.sh [options] build_xmlstream "file.xhtml"
Compile an xml stream from the specified file, additional sources will be
determined and included automatically. The stream is suitable for being
passed into xsltproc.
build_main.sh [options] process_file "file.xhtml" [processor.xsl]
Generate output from an xhtml file as if it would be processed during the
build. Output is written to STDOUT and can be redirected as desired.
If a xslt file is not given, it will be chosen automatically.
build_main.sh [options] tree_maker [input_dir] "destination_dir"
Generate a set of make rules to build the website contained in input_dir.
destination_dir should be the www root of a web server.
If input_dir is omitted, it will be the source directory determined from
the build scripts location.
Note: if destination_dir is set via previous options, and only one parameter
is given, then this parameter will be interpreted as input_dir
OPTIONS
-------
--source "source_dir"
Force a specific source directory. If not explicitly given source_dir is
determined from the build scripts own location.
Paths given in .sources files are interpreted as relative to source_dir
making this option useful when building a webpage outside of the build
scripts "regular" tree.
--destination "destination_dir"
The directory into which the website will be built. This option can be used
in conjunction with the tree_maker and build_into commands. It will override
the destination_dir option given after those commands and is therefore
redundant. The option exists to provide backward compatibility to the 2002
build script.
--statusdir "status_dir"
A directory to which messages are written. If no status_dir is provided
information will be written to stdout. The directory will also be used
to store some temporary files, which would otherwise be set up in the
system wide temp directory.
--build-env "selection"
Indicate the current build environment. "selection" can be one of:
* "fsfe.org": building https://fsfe.org on the production server
* "test.fsfe.org": building https://test.fsfe.org on the production server
* "development" (default): local development build
In a local development build, code to dynamically compile the less files into
CSS will be included in the HTML output, while in the other environments, the
precompiles fsfe.min.css (or valentine.min.css) will be referenced from the
generated web pages.

42
build/README.md Normal file
View File

@ -0,0 +1,42 @@
# Main Commands
Note that targets takes a comma separated list of valid rsync targets, and hence supports ssh targets. If targeting more than one directory one must use the --stage-dir flag documented below.
## build_main.sh [options] build_run "targets"
Perform the page build. Write output to targets. The source directory is determined from the build scripts own location.
## build_main.sh [options] git_build_into "targets"
Update repo to latest version of upstream branch and then perform a standard build. Write output to targets. The source directory is determined from the build scripts own location.
## build_main.sh [options] build_into "targets"
Perform a full rebuild of the webpages, removing all cached files. Write output to targets. The source directory is determined from the build scripts own location.
# Internal Commands
It is unlikely that you will need to directly call these commands, but they are documented here never the less.
## build_main.sh [options] build_xmlstream "file.xhtml"
Compile an xml stream from the specified file, additional sources will be determined and included automatically. The stream is suitable for being passed into xsltproc.
## build_main.sh [options] process_file "file.xhtml" [processor.xsl]
Generate output from an xhtml file as if it would be processed during the
build. Output is written to STDOUT and can be redirected as desired.
If a xslt file is not given, it will be chosen automatically.
## build_main.sh [options] tree_maker [input_dir] "targets"
Generate a set of make rules to build the website contained in input_dir. targets should be the www root of a web server. If input_dir is omitted, it will be the source directory determined from the build scripts location. Note: if targets is set via previous options, and only one parameter is given, then this parameter will be interpreted as input_dir
# OPTIONS
## --source "source_dir"
Force a specific source directory. If not explicitly given source_dir is determined from the build scripts own location. Paths given in .sources files are interpreted as relative to source_dir making this option useful when building a webpage outside of the build scripts "regular" tree.
## --status-dir "status_dir"
A directory to which messages are written. If no status_dir is provided information will be written to stdout. The directory will also be used to store some temporary files, which would otherwise be set up in the system wide temp directory.
## --stage-dir "stage_dir"
Directory used for staging the website builds. The websites are first build into this directory, then copied to each targets.
## --build-env "selection"
Indicate the current build environment. "selection" can be one of: * "fsfe.org": building https://fsfe.org on the production server * "test.fsfe.org": building https://test.fsfe.org on the production server * "development" (default): local development build In a local development build, code to dynamically compile the less files into CSS will be included in the HTML output, while in the other environments, the precompiles fsfe.min.css (or valentine.min.css) will be referenced from the generated web pages.
## --languages "languages"
Takes a comma separated list of language shot codes to build the website in. For example, to build the site in English and French only one would use `--languages en,fr`. One of the built languages must be English.
## --help
Show this README.

View File

@ -3,87 +3,92 @@
[ -z "$inc_misc" ] && . "$basedir/build/misc.sh"
if [ -z "$inc_arguments" ]; then
inc_arguments=true
basedir="$(realpath "${0%/*}/..")"
inc_arguments=true
basedir="$(realpath "${0%/*}/..")"
while [ "$#" -gt 0 ]; do
case "$1" in
-s|--statusdir|--status-dir)
[ "$#" -gt 0 ] && shift 1 && statusdir="$1"
;;
--domain)
[ "$#" -gt 0 ] && shift 1 && domain="$1"
;;
--source)
[ "$#" -gt 0 ] && shift 1 && basedir="$1"
;;
--stage|--stagedir)
[ "$#" -gt 0 ] && shift 1 && stagedir="$1"
;;
-d|--dest|--destination)
[ "$#" -gt 0 ] && shift 1 && target="$1"
;;
--build-env)
[ "$#" -gt 0 ] && shift 1 && build_env="$1"
;;
-h|--help)
command="help"
;;
build_into)
command="$1$command"
[ "$#" -gt 0 ] && shift 1 && target="$1"
;;
git_build_into)
command="$1$command"
[ "$#" -gt 0 ] && shift 1 && target="$1"
;;
build_run)
command="$1$command"
[ "$#" -gt 0 ] && shift 1 && target="$1"
;;
build_xmlstream)
command="$1$command"
[ "$#" -gt 0 ] && shift 1 && workfile="$1"
;;
tree_maker)
command="$1$command"
[ -n "$target" -o -n "$3" ] && shift 1 && tree="$1"
shift 1; [ -n "$1" ] && target="$1"
;;
process_file)
command="$1$command"
[ "$#" -gt 0 ] && shift 1 && workfile="$1"
[ "$#" -gt 0 ] && shift 1 && processor="$1"
;;
*)
print_error "Unknown option: $1"
exit 1
;;
esac
[ "$#" -gt 0 ] && shift 1
done
tree="${tree:-$basedir}"
stagedir="${stagedir:-$target}"
readonly tree="${tree:+$(realpath "$tree")}"
readonly stagedir="${stagedir:+$(realpath "$stagedir")}"
readonly basedir="${basedir:+$(realpath "$basedir")}"
readonly domain="${domain:-www.fsfe.org}"
readonly command
if [ "$stagedir" != "$target" ] && printf %s "$target" | egrep -q '^.+@.+:(.+)?$'; then
readonly target
else
readonly target="${target:+$(realpath "$target")}"
fi
while [ "$#" -gt 0 ]; do
case "$1" in
-s | --statusdir | --status-dir)
[ "$#" -gt 0 ] && shift 1 && statusdir="$1"
;;
--source)
[ "$#" -gt 0 ] && shift 1 && basedir="$1"
;;
--stage | --stagedir | --stage-dir)
[ "$#" -gt 0 ] && shift 1 && stagedir="$1"
;;
--build-env)
[ "$#" -gt 0 ] && shift 1 && build_env="$1"
;;
--languages)
[ "$#" -gt 0 ] && shift 1 && languages="$1"
;;
-h | --help)
command="help"
;;
build_into)
command="$1$command"
[ "$#" -gt 0 ] && shift 1 && target="$1"
;;
git_build_into)
command="$1$command"
[ "$#" -gt 0 ] && shift 1 && target="$1"
;;
build_run)
command="$1$command"
[ "$#" -gt 0 ] && shift 1 && target="$1"
;;
build_xmlstream)
command="$1$command"
[ "$#" -gt 0 ] && shift 1 && workfile="$1"
;;
tree_maker)
command="$1$command"
[ -n "$target" -o -n "$3" ] && shift 1 && tree="$1"
shift 1
[ -n "$1" ] && target="$1"
;;
process_file)
command="$1$command"
[ "$#" -gt 0 ] && shift 1 && workfile="$1"
[ "$#" -gt 0 ] && shift 1 && processor="$1"
;;
*)
print_error "Unknown option: $1"
exit 1
;;
esac
[ "$#" -gt 0 ] && shift 1
done
tree="${tree:-$basedir}"
stagedir="${stagedir:-$target}"
readonly tree="${tree:+$(realpath "$tree")}"
readonly stagedir="${stagedir:+$(realpath "$stagedir")}"
readonly basedir="${basedir:+$(realpath "$basedir")}"
readonly build_env="${build_env:-development}"
readonly command
if [ "$languages" ]; then
readonly languages="$(echo "$languages" | tr ',' ' ')"
else
readonly languages="$(ls -xw0 "${basedir}/global/languages")"
fi
if [ "$stagedir" != "$target" ] && printf %s "$target" | egrep -q '^.+@.+:(.+)?$'; then
readonly target
else
readonly target="${target:+$(realpath "$target")}"
fi
case "$command" in
build_into) [ -z "$target" ] && die "Missing destination directory" ;;
git_build_into) [ -z "$target" ] && die "Missing destination directory" ;;
build_run) [ -z "$target" ] && die "Missing destination directory" ;;
process_file) [ -z "$workfile" ] && die "Need at least input file" ;;
build_xmlstream) [ -z "$workfile" ] && die "Missing xhtml file name" ;;
tree_maker) [ -z "$target" ] && die "Missing target location" ;;
*help*) cat "$basedir/build/HELP"; exit 0 ;;
*) die "Urecognised command or no command given" ;;
esac
case "$command" in
build_into) [ -z "$target" ] && die "Missing destination directory" ;;
git_build_into) [ -z "$target" ] && die "Missing destination directory" ;;
build_run) [ -z "$target" ] && die "Missing destination directory" ;;
process_file) [ -z "$workfile" ] && die "Need at least input file" ;;
build_xmlstream) [ -z "$workfile" ] && die "Missing xhtml file name" ;;
tree_maker) [ -z "$target" ] && die "Missing target location" ;;
*help*)
cat "$basedir/build/README.md"
exit 0
;;
*) die "Urecognised command or no command given" ;;
esac
fi

View File

@ -2,31 +2,31 @@
# Dependency check function
check_dependencies() {
depends="$@"
deperrors=''
for depend in $depends; do
if ! which "$depend" >/dev/null 2>&1; then
deperrors="$depend $deperrors"
fi
done
if [ -n "$deperrors" ]; then
printf '\033[1;31m'
cat <<-EOF
The build script depends on some other programs to function.
Not all of those programs could be located on your system.
Please use your package manager to install the following programs:
depends="$@"
deperrors=''
for depend in $depends; do
if ! which "$depend" >/dev/null 2>&1; then
deperrors="$depend $deperrors"
fi
done
if [ -n "$deperrors" ]; then
printf '\033[1;31m'
cat <<-EOF
The build script depends on some other programs to function.
Not all of those programs could be located on your system.
Please use your package manager to install the following programs:
EOF
printf '\n\033[0;31m%s\n' "$deperrors"
exit 1
fi 1>&2
printf '\n\033[0;31m%s\n' "$deperrors"
exit 1
fi 1>&2
}
# Check dependencies for all kinds of build envs (e.g. development, fsfe.org)
check_dependencies realpath rsync xsltproc xmllint sed find egrep grep wc make tee date iconv wget shuf python3
if ! make --version | grep -q "GNU Make 4"; then
echo "The build script requires GNU Make 4.x"
exit 1
echo "The build script requires GNU Make 4.x"
exit 1
fi
basedir="${0%/*}/.."
@ -37,46 +37,46 @@ readonly start_time="$(date +%s)"
# Check special dependencies for (test.)fsfe.org build server
if [ "$build_env" == "fsfe.org" ] || [ "$build_env" == "test.fsfe.org" ]; then
check_dependencies lessc
check_dependencies lessc
fi
statusdir="${statusdir/#\~/$HOME}"
if [ -n "$statusdir" ]; then
mkdir -p "$statusdir"
[ ! -w "$statusdir" -o ! -d "$statusdir" ] && \
die "Unable to set up status directory in \"$statusdir\",\n" \
"either select a status directory that exists and is writable,\n" \
"or run the build script without output to a status directory"
mkdir -p "$statusdir"
[ ! -w "$statusdir" -o ! -d "$statusdir" ] &&
die "Unable to set up status directory in \"$statusdir\",\n" \
"either select a status directory that exists and is writable,\n" \
"or run the build script without output to a status directory"
fi
readonly statusdir="${statusdir:+$(realpath "$statusdir")}"
readonly statusdir="${statusdir:+$(realpath "$statusdir")}"
buildpids=$(
ps -eo command \
| egrep "[s]h ${0} .*" \
| wc -l
ps -eo command |
egrep "[s]h ${0} .*" |
wc -l
)
if [ $command = "build_into" -o $command = "git_build_into" ] && [ "$buildpids" -gt 2 ]; then
debug "build script is already running"
exit 1
debug "build script is already running"
exit 1
fi
[ -z "$inc_filenames" ] && . "$basedir/build/filenames.sh"
[ -z "$inc_buildrun" ] && . "$basedir/build/buildrun.sh"
[ -z "$inc_buildrun" ] && . "$basedir/build/buildrun.sh"
[ -z "$inc_makerules" ] && . "$basedir/build/makerules.sh"
[ -z "$inc_processor" ] && . "$basedir/build/processor.sh"
[ -z "$inc_scaffold" ] && . "$basedir/build/scaffold.sh"
[ -z "$inc_scaffold" ] && . "$basedir/build/scaffold.sh"
case "$command" in
git_build_into) if [ -f "${statusdir}/full_build" ]; then
debug "discovered flag file, performing full build"
rm "${statusdir}/full_build"
build_into
else
git_build_into
fi ;;
build_into) build_into ;;
build_run) buildrun ;;
process_file) process_file "$workfile" "$processor" ;;
build_xmlstream) build_xmlstream "$(get_shortname "$workfile")" "$(get_language "$workfile")" ;;
tree_maker) tree_maker "$tree" "$target" ;;
git_build_into) if [ -f "${statusdir}/full_build" ]; then
debug "discovered flag file, performing full build"
rm "${statusdir}/full_build"
build_into
else
git_build_into
fi ;;
build_into) build_into ;;
build_run) buildrun ;;
process_file) process_file "$workfile" "$processor" ;;
build_xmlstream) build_xmlstream "$(get_shortname "$workfile")" "$(get_language "$workfile")" ;;
tree_maker) tree_maker "$tree" "$target" ;;
esac

View File

@ -5,131 +5,136 @@ inc_buildrun=true
[ -z "$inc_logging" ] && . "$basedir/build/logging.sh"
[ -z "$inc_misc" ] && . "$basedir/build/misc.sh"
match(){
printf %s "$1" | egrep -q "$2"
match() {
printf %s "$1" | egrep -q "$2"
}
dir_maker(){
# set up directory tree for output
# optimise by only issuing mkdir commands
# for leaf directories
input="${1%/}"
output="${2%/}"
dir_maker() {
# set up directory tree for output
# optimise by only issuing mkdir commands
# for leaf directories
input="${1%/}"
output="${2%/}"
curpath="$output"
find "$input" -depth -type d \
-regex "$input/[a-z\.]+\.[a-z]+\(/.*\)?" \
-printf '%P\n' \
| while read -r filepath; do
oldpath="$curpath"
curpath="$output/$filepath/"
match "$oldpath" "^$curpath" || mkdir -p "$curpath"
done
curpath="$output"
find "$input" -depth -type d \
-regex "$input/[a-z\.]+\.[a-z]+\(/.*\)?" \
-printf '%P\n' |
while read -r filepath; do
oldpath="$curpath"
curpath="$output/$filepath/"
match "$oldpath" "^$curpath" || mkdir -p "$curpath"
done
}
# The actual build
buildrun(){
set -o pipefail
buildrun() {
set -o pipefail
printf %s "$start_time" > "$(logname start_time)"
printf %s "$start_time" >"$(logname start_time)"
ncpu="$(grep -c ^processor /proc/cpuinfo)"
ncpu="$(grep -c ^processor /proc/cpuinfo)"
[ -f "$(logname lasterror)" ] && rm "$(logname lasterror)"
[ -f "$(logname debug)" ] && rm "$(logname debug)"
[ -f "$(logname lasterror)" ] && rm "$(logname lasterror)"
[ -f "$(logname debug)" ] && rm "$(logname debug)"
{
echo "Starting phase 1" \
&& make --silent --directory="$basedir" build_env="${build_env:-development}" 2>&1 \
&& echo "Finishing phase 1" \
|| die "Error during phase 1"
} | t_logstatus phase_1 || exit 1
{
echo "Starting phase 1" &&
make --silent --directory="$basedir" build_env="${build_env}" languages="$languages" 2>&1 &&
echo "Finishing phase 1" ||
die "Error during phase 1"
} | t_logstatus phase_1 || exit 1
dir_maker "$basedir" "$stagedir" || exit 1
dir_maker "$basedir" "$stagedir" || exit 1
forcelog Makefile
forcelog Makefile
{
tree_maker "$basedir" "$stagedir" 2>&1 \
|| die "Error during phase 2 Makefile generation"
} > "$(logname Makefile)" || exit 1
{
tree_maker "$basedir" "$stagedir" 2>&1 ||
die "Error during phase 2 Makefile generation"
} >"$(logname Makefile)" || exit 1
{
echo "Starting phase 2" \
&& make --silent --jobs=$ncpu --file="$(logname Makefile)" 2>&1 \
&& echo "Finishing phase 2" \
|| die "Error during phase 2"
} | t_logstatus phase_2 || exit 1
{
echo "Starting phase 2" &&
make --silent --jobs=$ncpu --file="$(logname Makefile)" 2>&1 &&
echo "Finishing phase 2" ||
die "Error during phase 2"
} | t_logstatus phase_2 || exit 1
if [ "$stagedir" != "$target" ]; then
# rsync issues a "copying unsafe symlink" message for each of the "unsafe"
# symlinks which we copy while rsyncing. These messages are issued even if
# the files have not changed and clutter up the output, so we filter them
# out.
{
for destination in ${target//,/ }; do
echo "Syncing files to $(echo "$destination" | grep -Po "(?<=@)[^:]+")"
rsync -av --copy-unsafe-links --del --exclude "status.fsfe.org/*fsfe.org/data" "$stagedir/" "$destination/" | grep -v "copying unsafe symlink"
done
} | t_logstatus stagesync
fi
if [ "$stagedir" != "$target" ]; then
# rsync issues a "copying unsafe symlink" message for each of the "unsafe"
# symlinks which we copy while rsyncing. These messages are issued even if
# the files have not changed and clutter up the output, so we filter them
# out.
{
for destination in ${target//,/ }; do
echo "Syncing files to $(echo "$destination" | grep -Po "(?<=@)[^:]+")"
rsync -av --copy-unsafe-links --del --exclude "status.fsfe.org/*fsfe.org/data" "$stagedir/" "$destination/" | grep -v "copying unsafe symlink"
done
} | t_logstatus stagesync
fi
date +%s > "$(logname end_time)"
date +%s >"$(logname end_time)"
if [ -n "$statusdir" ]; then
( cd "$statusdir"/..; ./index.cgi | tail -n+3 > "$statusdir"/status_$(date +%s).html )
fi
if [ -n "$statusdir" ]; then
(
cd "$statusdir"/..
./index.cgi | tail -n+3 >"$statusdir"/status_$(date +%s).html
)
fi
}
# Update git (try 3x) and then do an actual build
git_build_into(){
forcelog GITchanges; GITchanges="$(logname GITchanges)"
forcelog GITerrors; GITerrors="$(logname GITerrors)"
git_build_into() {
forcelog GITchanges
GITchanges="$(logname GITchanges)"
forcelog GITerrors
GITerrors="$(logname GITerrors)"
gitterm=1
i=0
while [[ ( $gitterm -ne 0 ) && ( $i -lt 3) ]]; do
((i++))
gitterm=1
i=0
while [[ ($gitterm -ne 0) && ($i -lt 3) ]]; do
((i++))
git -C "$basedir" pull >"$GITchanges" 2>"$GITerrors"
gitterm="$?"
git -C "$basedir" pull >"$GITchanges" 2>"$GITerrors"
gitterm="$?"
if [ $gitterm -ne 0 ]; then
debug "Git pull unsuccessful. Trying again in a few seconds."
sleep $(shuf -i 10-30 -n1)
fi
done
if [ $gitterm -ne 0 ]; then
debug "Git pull unsuccessful. Trying again in a few seconds."
sleep $(shuf -i 10-30 -n1)
fi
done
if [ "$gitterm" -ne 0 ]; then
debug "Three git pulls failed, hard resetting and repulling"
git -C "$basedir" reset --hard HEAD~50 >"$GITchanges" 2>"$GITerrors"
git -C "$basedir" pull >>"$GITchanges" 2>>"$GITerrors"
gitterm="$?"
fi
if [ "$gitterm" -ne 0 ]; then
debug "Three git pulls failed, hard resetting and repulling"
git -C "$basedir" reset --hard HEAD~50 >"$GITchanges" 2>"$GITerrors"
git -C "$basedir" pull >>"$GITchanges" 2>>"$GITerrors"
gitterm="$?"
fi
if [ "$gitterm" -ne 0 ]; then
die "GIT reported the following problem:\n$(cat "$GITerrors")"
fi
if [ "$gitterm" -ne 0 ]; then
die "GIT reported the following problem:\n$(cat "$GITerrors")"
fi
if egrep '^Already up[ -]to[ -]date' "$GITchanges"; then
debug "No changes to GIT:\n$(cat "$GITchanges")"
# Exit status should only be 0 if there was a successful build.
# So set it to 1 here.
exit 1
fi
if egrep '^Already up[ -]to[ -]date' "$GITchanges"; then
debug "No changes to GIT:\n$(cat "$GITchanges")"
# Exit status should only be 0 if there was a successful build.
# So set it to 1 here.
exit 1
fi
logstatus GITlatest < "$GITchanges"
buildrun
logstatus GITlatest <"$GITchanges"
buildrun
}
# Clean up everything and then do an actual (full) build
build_into(){
build_into() {
# Clean up source directory.
git -C "${basedir}" clean -dxf --exclude=status.fsfe.org/translations/data
# Clean up source directory.
git -C "${basedir}" clean -dxf --exclude=status.fsfe.org/translations/data
# Remove old stage directory.
rm -rf "${stagedir}"
# Remove old stage directory.
rm -rf "${stagedir}"
buildrun
buildrun
}

View File

@ -2,15 +2,15 @@
inc_filenames=true
get_language(){
# extract language indicator from a given file name
echo "$(echo "$1" |sed -r 's:^.*\.([a-z]{2})\.[^\.]+$:\1:')";
get_language() {
# extract language indicator from a given file name
echo "$(echo "$1" | sed -r 's:^.*\.([a-z]{2})\.[^\.]+$:\1:')"
}
get_shortname(){
# get shortened version of a given file name
# required for internal processing
get_shortname() {
# get shortened version of a given file name
# required for internal processing
#echo "$(echo "$1" | sed -r 's:\.[a-z]{2}.xhtml$::')";
echo "${1%.??.xhtml}"
#echo "$(echo "$1" | sed -r 's:\.[a-z]{2}.xhtml$::')";
echo "${1%.??.xhtml}"
}

View File

@ -2,42 +2,42 @@
inc_logging=true
logname(){
name="$1"
logname() {
name="$1"
if [ -w "$statusdir" ] && touch "$statusdir/$name"; then
echo "$statusdir/$name"
elif echo "$forcedlog" |egrep -q "^${name}=.+"; then
echo "$forcedlog" \
| sed -rn "s;^${name}=;;p"
else
echo /dev/null
fi
if [ -w "$statusdir" ] && touch "$statusdir/$name"; then
echo "$statusdir/$name"
elif echo "$forcedlog" | egrep -q "^${name}=.+"; then
echo "$forcedlog" |
sed -rn "s;^${name}=;;p"
else
echo /dev/null
fi
}
forcelog(){
name="$1"
forcelog() {
name="$1"
[ "$(logname "$name")" = "/dev/null" ] \
&& forcedlog="$forcedlog\n${name}=$(mktemp -t w3bldXXXXXXXXX --suffix $$)"
[ "$(logname "$name")" = "/dev/null" ] &&
forcedlog="$forcedlog\n${name}=$(mktemp -t w3bldXXXXXXXXX --suffix $$)"
}
[ -z "$USER" ] && USER="$(whoami)"
trap "trap - 0 2 3 6 9 15; find \"${TMPDIR:-/tmp}/\" -maxdepth 1 -user \"$USER\" -name \"w3bld*$$\" -delete" 0 2 3 6 9 15
logstatus(){
# pipeline atom to write data streams into a log file
tee "$(logname "$1")"
logstatus() {
# pipeline atom to write data streams into a log file
tee "$(logname "$1")"
}
t_logstatus(){
# pipeline atom to write data streams into a log file
while read line; do
printf "[$(date +%T)] %s\n" "$line"
done |logstatus "$@"
t_logstatus() {
# pipeline atom to write data streams into a log file
while read line; do
printf "[$(date +%T)] %s\n" "$line"
done | logstatus "$@"
}
logappend(){
# pipeline atom to write data streams into a log file
tee -a "$(logname "$1")"
logappend() {
# pipeline atom to write data streams into a log file
tee -a "$(logname "$1")"
}

View File

@ -2,13 +2,12 @@
inc_makerules=true
tree_maker(){
# walk through file tree and issue Make rules according to file type
input="$(realpath "$1")"
output="$(realpath "$2")"
languages="$(ls -xw0 "${basedir}/global/languages")"
tree_maker() {
# walk through file tree and issue Make rules according to file type
input="$(realpath "$1")"
output="$(realpath "$2")"
cat <<EOF
cat <<EOF
# -----------------------------------------------------------------------------
# Makefile for FSFE website build, phase 2
# -----------------------------------------------------------------------------
@ -17,7 +16,7 @@ tree_maker(){
.DELETE_ON_ERROR:
.SECONDEXPANSION:
PROCESSOR = "$basedir/build/process_file.sh"
PROCFLAGS = --build-env "${build_env:-development}" --source "$basedir" --domain "$domain"
PROCFLAGS = --build-env "${build_env}" --source "$basedir"
INPUTDIR = $input
OUTPUTDIR = $output
STATUSDIR = $statusdir
@ -55,15 +54,15 @@ XSL_DEP = \$(firstword \$(wildcard \$(INPUTDIR)/\$*.xsl) \$(INPUTDIR)/\$(dir \$*
all: \$(HTML_DST_FILES)
EOF
for lang in ${languages}; do
cat<<EOF
for lang in ${languages}; do
cat <<EOF
\$(filter %.${lang}.html,\$(HTML_DST_FILES)): \$(OUTPUTDIR)/%.${lang}.html: \$(INPUTDIR)/%.*.xhtml \$\$(XMLLIST_DEP) \$\$(XSL_DEP) \$(INPUTDIR)/global/data/texts/.texts.${lang}.xml \$(INPUTDIR)/global/data/texts/texts.en.xml \$(INPUTDIR)/global/data/topbanner/.topbanner.${lang}.xml
echo "* Building \$*.${lang}.html"
\${PROCESSOR} \${PROCFLAGS} process_file "\$(INPUTDIR)/\$*.${lang}.xhtml" > "\$@"
EOF
done
done
cat <<EOF
cat <<EOF
# -----------------------------------------------------------------------------
# Create index.* symlinks
@ -90,15 +89,15 @@ INDEX_DST_LINKS := \$(foreach base,\$(INDEX_DST_DIRS),\$(foreach lang,\$(LANGUAG
all: \$(INDEX_DST_LINKS)
EOF
for lang in ${languages}; do
cat<<EOF
for lang in ${languages}; do
cat <<EOF
\$(filter %/index.${lang}.html,\$(INDEX_DST_LINKS)): \$(OUTPUTDIR)/%/index.${lang}.html:
echo "* Creating symlink \$*/index.${lang}.html"
ln -sf "\$(notdir \$*).${lang}.html" "\$@"
EOF
done
done
cat <<EOF
cat <<EOF
# -----------------------------------------------------------------------------
# Create symlinks from file.<lang>.html to file.html.<lang>
@ -110,15 +109,15 @@ HTML_DST_LINKS := \$(foreach base,\$(HTML_DST_BASES) \$(addsuffix index,\$(INDEX
all: \$(HTML_DST_LINKS)
EOF
for lang in ${languages}; do
cat<<EOF
for lang in ${languages}; do
cat <<EOF
\$(OUTPUTDIR)/%.html.${lang}:
echo "* Creating symlink \$*.html.${lang}"
ln -sf "\$(notdir \$*).${lang}.html" "\$@"
EOF
done
done
cat <<EOF
cat <<EOF
# -----------------------------------------------------------------------------
# Build .rss files from .xhtml sources
@ -142,15 +141,15 @@ RSS_DST_FILES := \$(foreach base,\$(RSS_DST_BASES),\$(foreach lang,\$(LANGUAGES)
all: \$(RSS_DST_FILES)
EOF
for lang in ${languages}; do
cat<<EOF
for lang in ${languages}; do
cat <<EOF
\$(OUTPUTDIR)/%.${lang}.rss: \$(INPUTDIR)/%.*.xhtml \$\$(XMLLIST_DEP) \$(INPUTDIR)/%.rss.xsl \$(INPUTDIR)/global/data/texts/.texts.${lang}.xml \$(INPUTDIR)/global/data/texts/texts.en.xml
echo "* Building \$*.${lang}.rss"
\${PROCESSOR} \${PROCFLAGS} process_file "\$(INPUTDIR)/\$*.${lang}.xhtml" "\$(INPUTDIR)/\$*.rss.xsl" > "\$@"
EOF
done
done
cat <<EOF
cat <<EOF
# -----------------------------------------------------------------------------
# Build .ics files from .xhtml sources
@ -174,15 +173,15 @@ ICS_DST_FILES := \$(foreach base,\$(ICS_DST_BASES),\$(foreach lang,\$(LANGUAGES)
all: \$(ICS_DST_FILES)
EOF
for lang in ${languages}; do
cat<<EOF
for lang in ${languages}; do
cat <<EOF
\$(OUTPUTDIR)/%.${lang}.ics: \$(INPUTDIR)/%.*.xhtml \$\$(XMLLIST_DEP) \$(INPUTDIR)/%.ics.xsl \$(INPUTDIR)/global/data/texts/.texts.${lang}.xml \$(INPUTDIR)/global/data/texts/texts.en.xml
echo "* Building \$*.${lang}.ics"
\${PROCESSOR} \${PROCFLAGS} process_file "\$(INPUTDIR)/\$*.${lang}.xhtml" "\$(INPUTDIR)/\$*.ics.xsl" > "\$@"
EOF
done
done
cat <<EOF
cat <<EOF
# -----------------------------------------------------------------------------
# Copy images, docments etc

View File

@ -3,21 +3,21 @@
inc_misc=true
[ -z "$inc_logging" ] && . "$basedir/build/logging.sh"
debug(){
if [ "$#" -ge 1 ]; then
echo "$(date '+%F %T'): $@" |logappend debug >&2
else
logappend debug >&2
fi
debug() {
if [ "$#" -ge 1 ]; then
echo "$(date '+%F %T'): $@" | logappend debug >&2
else
logappend debug >&2
fi
}
print_error(){
echo "Error - $@" |logappend lasterror >&2
echo "Run '$0 --help' to see usage instructions" >&2
print_error() {
echo "Error - $@" | logappend lasterror >&2
echo "Run '$0 --help' to see usage instructions" >&2
}
die(){
echo "$(date '+%F %T'): Fatal - $@" |logappend lasterror >&2
date +%s |logstatus end_time
exit 1
die() {
echo "$(date '+%F %T'): Fatal - $@" | logappend lasterror >&2
date +%s | logstatus end_time
exit 1
}

View File

@ -6,6 +6,6 @@ basedir="${0%/*}/.."
. "$basedir/build/arguments.sh"
case "$command" in
process_file) process_file "$workfile" "$processor" ;;
*) die "Unrecognised command or no command given" ;;
process_file) process_file "$workfile" "$processor" ;;
*) die "Unrecognised command or no command given" ;;
esac

View File

@ -2,48 +2,46 @@
inc_processor=true
[ -z "$inc_filenames" ] && . "$basedir/build/filenames.sh"
[ -z "$inc_scaffold" ] && . "$basedir/build/scaffold.sh"
[ -z "$inc_scaffold" ] && . "$basedir/build/scaffold.sh"
process_file(){
infile="$1"
processor="$2"
process_file() {
infile="$1"
processor="$2"
shortname=$(get_shortname "$infile")
lang=$(get_language "$infile")
shortname=$(get_shortname "$infile")
lang=$(get_language "$infile")
if [ -z "${processor}" ]; then
if [ -f "${shortname}.xsl" ]; then
processor="${shortname}.xsl"
else
# Actually use the symlink target, so the relative includes are searched
# in the correct directory.
processor="$(realpath "${shortname%/*}/.default.xsl")"
fi
fi
if [ -z "${processor}" ]; then
if [ -f "${shortname}.xsl" ]; then
processor="${shortname}.xsl"
else
# Actually use the symlink target, so the relative includes are searched
# in the correct directory.
processor="$(realpath "${shortname%/*}/.default.xsl")"
fi
fi
# Make sure that the following pipe exits with a nonzero exit code if *any*
# of the commands fails.
set -o pipefail
# Make sure that the following pipe exits with a nonzero exit code if *any*
# of the commands fails.
set -o pipefail
# The sed command of death below does the following:
# 1. Remove https://fsfe.org (or https://test.fsfe.org) from the start of all
# links
# 2. Change links from /foo/bar.html into /foo/bar.xx.html
# 3. Change links from foo/bar.html into foo/bar.xx.html
# 4. Same for .rss and .ics links
# 5. Change links from /foo/bar/ into /foo/bar/index.xx.html
# 6. Change links from foo/bar/ into foo/bar/index.xx.html
# ... where xx is the language code.
# Everything is duplicated to allow for the href attribute to be enclosed in
# single or double quotes.
# I am strongly convinced that there must be a less obfuscated way of doing
# this. --Reinhard
# The sed command of death below does the following:
# 1. Remove https://fsfe.org (or https://test.fsfe.org) from the start of all
# links
# 2. Change links from /foo/bar.html into /foo/bar.xx.html
# 3. Change links from foo/bar.html into foo/bar.xx.html
# 4. Same for .rss and .ics links
# 5. Change links from /foo/bar/ into /foo/bar/index.xx.html
# 6. Change links from foo/bar/ into foo/bar/index.xx.html
# ... where xx is the language code.
# Everything is duplicated to allow for the href attribute to be enclosed in
# single or double quotes.
# I am strongly convinced that there must be a less obfuscated way of doing
# this. --Reinhard
build_xmlstream "$shortname" "$lang" \
| xsltproc --stringparam "build-env" "${build_env:-development}" "$processor" - \
| sed -r ':X; N; $!bX;
s;<[\r\n\t ]*(a|link)([\r\n\t ][^>]*)?[\r\n\t ]href="(https?:)?//'"$domain"'/([^"]*)";<\1\2 href="/\4";gI
s;<[\r\n\t ]*(a|link)([\r\n\t ][^>]*)?[\r\n\t ]href='\''(https?:)?//'"$domain"'/([^'\'']*)'\'';<\1\2 href='\''/\4'\'';gI
build_xmlstream "$shortname" "$lang" |
xsltproc --stringparam "build-env" "${build_env}" "$processor" - |
sed -r ':X; N; $!bX;
s;<[\r\n\t ]*(a|link)([\r\n\t ][^>]*)?[\r\n\t ]href="((https?:)?//[^"]*)";<\1\2 href="#== norewrite ==\3";gI
s;<[\r\n\t ]*(a|link)([\r\n\t ][^>]*)?[\r\n\t ]href="([^#"])([^"]*/)?([^\./"]*\.)(html|rss|ics)(#[^"]*)?";<\1\2 href="\3\4\5'"$lang"'.\6\7";gI

View File

@ -2,124 +2,124 @@
inc_scaffold=true
get_version(){
version=$(xsltproc $basedir/build/xslt/get_version.xsl $1)
echo ${version:-0}
get_version() {
version=$(xsltproc $basedir/build/xslt/get_version.xsl $1)
echo ${version:-0}
}
include_xml(){
# include second level elements of a given XML file
# this emulates the behaviour of the original
# build script which wasn't able to load top
# level elements from any file
if [ -f "$1" ]; then
# Remove <version> because the filename attribute would otherwise be added
# to this element instead of the actual content element.
sed 's;<version>.*</version>;;' "$1" | \
sed -r ':X; $bY; N; bX; :Y;
include_xml() {
# include second level elements of a given XML file
# this emulates the behaviour of the original
# build script which wasn't able to load top
# level elements from any file
if [ -f "$1" ]; then
# Remove <version> because the filename attribute would otherwise be added
# to this element instead of the actual content element.
sed 's;<version>.*</version>;;' "$1" |
sed -r ':X; $bY; N; bX; :Y;
s:<(\?[xX][mM][lL]|!DOCTYPE)[[:space:]]+[^>]+>::g
s:<[^!][^>]*>::;
s:</[^>]*>([^<]*((<[^>]+/>|<!([^>]|<[^>]*>)*>|<\?[^>]+>)[^<]*)*)?$:\1:;'
fi
fi
}
get_attributes(){
# get attributes of top level element in a given
# XHTML file
sed -rn ':X; N; $!bX;
get_attributes() {
# get attributes of top level element in a given
# XHTML file
sed -rn ':X; N; $!bX;
s;^.*<[\n\t\r ]*([xX]|[xX]?[hH][tT])[mM][lL][\n\t\r ]+([^>]*)>.*$;\2;p' "$1"
}
list_langs(){
# list all languages a file exists in by globbing up
# the shortname (i.e. file path with file ending omitted)
# output is readily formatted for inclusion
# in xml stream
for file in "${1}".[a-z][a-z].xhtml; do
language="${file: -8:2}"
text="$(echo -n $(cat "${basedir}/global/languages/${language}"))"
echo "<tr id=\"${language}\">${text}</tr>"
done
list_langs() {
# list all languages a file exists in by globbing up
# the shortname (i.e. file path with file ending omitted)
# output is readily formatted for inclusion
# in xml stream
for file in "${1}".[a-z][a-z].xhtml; do
language="${file: -8:2}"
text="$(echo -n $(cat "${basedir}/global/languages/${language}"))"
echo "<tr id=\"${language}\">${text}</tr>"
done
}
auto_sources(){
# import elements from source files, add file name
# attribute to first element included from each file
shortname="$1"
lang="$2"
auto_sources() {
# import elements from source files, add file name
# attribute to first element included from each file
shortname="$1"
lang="$2"
list_file="$(dirname ${shortname})/.$(basename ${shortname}).xmllist"
list_file="$(dirname ${shortname})/.$(basename ${shortname}).xmllist"
if [ -f "${list_file}" ]; then
cat "${list_file}" | while read path; do
base="$(basename ${path})"
if [ -f "${basedir}/${path}.${lang}.xml" ]; then
printf '\n### filename="%s" ###\n%s' "${base#.}" "$(include_xml "${basedir}/${path}.${lang}.xml")"
elif [ -f "${basedir}/${path}.en.xml" ]; then
printf '\n### filename="%s" ###\n%s' "${base#.}" "$(include_xml "${basedir}/${path}.en.xml")"
fi
done \
| sed -r ':X; N; $!bX;
if [ -f "${list_file}" ]; then
cat "${list_file}" | while read path; do
base="$(basename ${path})"
if [ -f "${basedir}/${path}.${lang}.xml" ]; then
printf '\n### filename="%s" ###\n%s' "${base#.}" "$(include_xml "${basedir}/${path}.${lang}.xml")"
elif [ -f "${basedir}/${path}.en.xml" ]; then
printf '\n### filename="%s" ###\n%s' "${base#.}" "$(include_xml "${basedir}/${path}.en.xml")"
fi
done |
sed -r ':X; N; $!bX;
s;\n### (filename="[^\n"]+") ###\n[^<]*(<![^>]+>[^<]*)*(<([^/>]+/)*([^/>]+))(/?>);\2\3 \1\6;g;'
fi
fi
}
build_xmlstream(){
# assemble the xml stream for feeding into xsltproc
# the expected shortname and language flag indicate
# a single xhtml page to be built
shortname="$1"
lang="$2"
build_xmlstream() {
# assemble the xml stream for feeding into xsltproc
# the expected shortname and language flag indicate
# a single xhtml page to be built
shortname="$1"
lang="$2"
olang="$(echo "${shortname}".[a-z][a-z].xhtml "${shortname}".[e]n.xhtml |sed -rn 's;^.*\.([a-z]{2})\.xhtml.*$;\1;p')"
dirname="${shortname%/*}/"
topbanner_xml="$basedir/global/data/topbanner/.topbanner.${lang}.xml"
texts_xml="$basedir/global/data/texts/.texts.${lang}.xml"
date="$(date +%Y-%m-%d)"
time="$(date +%H:%M:%S)"
if [ -f "${shortname}.${lang}.xhtml" ]; then
act_lang="$lang"
translation_state="up-to-date"
[ $(get_version "${shortname}.${olang}.xhtml") -gt $(get_version "${shortname}.${lang}.xhtml") ] && translation_state="outdated"
[ $(( $(get_version "${shortname}.${olang}.xhtml") - 3 )) -gt $(get_version "${shortname}.${lang}.xhtml") ] && act_lang="$olang" && translation_state="very-outdated"
else
act_lang="$olang"
translation_state="untranslated"
fi
olang="$(echo "${shortname}".[a-z][a-z].xhtml "${shortname}".[e]n.xhtml | sed -rn 's;^.*\.([a-z]{2})\.xhtml.*$;\1;p')"
dirname="${shortname%/*}/"
topbanner_xml="$basedir/global/data/topbanner/.topbanner.${lang}.xml"
texts_xml="$basedir/global/data/texts/.texts.${lang}.xml"
date="$(date +%Y-%m-%d)"
time="$(date +%H:%M:%S)"
infile="${shortname}.${act_lang}.xhtml"
if [ -f "${shortname}.${lang}.xhtml" ]; then
act_lang="$lang"
translation_state="up-to-date"
[ $(get_version "${shortname}.${olang}.xhtml") -gt $(get_version "${shortname}.${lang}.xhtml") ] && translation_state="outdated"
[ $(($(get_version "${shortname}.${olang}.xhtml") - 3)) -gt $(get_version "${shortname}.${lang}.xhtml") ] && act_lang="$olang" && translation_state="very-outdated"
else
act_lang="$olang"
translation_state="untranslated"
fi
cat <<-EOF
<buildinfo
date="$date"
original="$olang"
filename="/${shortname#"$basedir"/}"
fileurl="/${shortname#"$basedir"/*/}"
dirname="/${dirname#"$basedir"/}"
language="$lang"
translation_state="$translation_state"
>
infile="${shortname}.${act_lang}.xhtml"
<trlist>
$(list_langs "$shortname")
</trlist>
cat <<-EOF
<buildinfo
date="$date"
original="$olang"
filename="/${shortname#"$basedir"/}"
fileurl="/${shortname#"$basedir"/*/}"
dirname="/${dirname#"$basedir"/}"
language="$lang"
translation_state="$translation_state"
>
<topbanner>$(include_xml "$topbanner_xml")</topbanner>
<textsetbackup>$(include_xml "$basedir/global/data/texts/texts.en.xml")</textsetbackup>
<textset>$(include_xml "$texts_xml")</textset>
<document
language="$act_lang"
$(get_attributes "$infile")
>
<set>
$(auto_sources "${shortname}" "$lang")
</set>
<trlist>
$(list_langs "$shortname")
</trlist>
$(include_xml "$infile")
</document>
<topbanner>$(include_xml "$topbanner_xml")</topbanner>
<textsetbackup>$(include_xml "$basedir/global/data/texts/texts.en.xml")</textsetbackup>
<textset>$(include_xml "$texts_xml")</textset>
</buildinfo>
<document
language="$act_lang"
$(get_attributes "$infile")
>
<set>
$(auto_sources "${shortname}" "$lang")
</set>
$(include_xml "$infile")
</document>
</buildinfo>
EOF
}

View File

@ -19,7 +19,7 @@ ARCH_YEARS := $(filter-out $(lastword $(ARCH_YEARS)),$(ARCH_YEARS))
ARCH_YEARS := $(filter-out $(lastword $(ARCH_YEARS)),$(ARCH_YEARS))
# Languages in which the template exists
ARCH_LANGS := $(suffix $(basename $(wildcard archive-template.??.xhtml)))
ARCH_LANGS := $(filter $(foreach lang,$(languages),.$(lang)),$(suffix $(basename $(wildcard archive-template.??.xhtml))))
# .xhtml files to generate
ARCH_XHTML := $(foreach year,$(ARCH_YEARS),$(foreach lang,$(ARCH_LANGS),$(year)/index$(lang).xhtml))

View File

@ -19,7 +19,7 @@ ARCH_YEARS := $(filter-out $(lastword $(ARCH_YEARS)),$(ARCH_YEARS))
ARCH_YEARS := $(filter-out $(lastword $(ARCH_YEARS)),$(ARCH_YEARS))
# Languages in which the template exists
ARCH_LANGS := $(suffix $(basename $(wildcard archive-template.??.xhtml)))
ARCH_LANGS := $(filter $(foreach lang,$(languages),.$(lang)),$(suffix $(basename $(wildcard archive-template.??.xhtml))))
# .xhtml files to generate
ARCH_XHTML := $(foreach year,$(ARCH_YEARS),$(foreach lang,$(ARCH_LANGS),$(year)/index$(lang).xhtml))
@ -62,7 +62,7 @@ all: $(GENERATED_XML_SOURCES)
# -----------------------------------------------------------------------------
# All existing .xhtml files
XHTML := $(shell ls */*.??.xhtml | xargs grep -l '<html newsdate')
XHTML := $(filter $(foreach lang,$(languages),%.$(lang).xhtml),$(shell ls */*.??.xhtml | xargs grep -l '<html newsdate'))
# List of .xml files to generate
XML := $(patsubst %.xhtml,%.xml,$(subst /,/.,$(XHTML)))

View File

@ -40,11 +40,7 @@ for dir in ${!files_by_dir[@]}; do
if [ "${file}" -nt "${dir}/.localmenu.en.xml" ]; then
# Find out which languages to generate.
languages=$(
ls ${files_by_dir[${dir}]} \
| sed 's/.*\.\(..\)\.xhtml/\1/' \
| sort --uniq
)
languages="$1"
# Compile the list of base filenames of the source files.
basefiles=$(

View File

@ -29,6 +29,7 @@ set -e