Browse Source

split up build script

svn path=/trunk/; revision=31254
tags/stw2018
paul 4 years ago
parent
commit
6da028e90f
15 changed files with 857 additions and 777 deletions
  1. 112
    0
      build/build_main.sh
  2. 31
    0
      build/buildrun.sh
  3. 51
    0
      build/filenames.sh
  4. 29
    0
      build/fundraising.sh
  5. 57
    0
      build/help.sh
  6. 46
    0
      build/languages.sh
  7. 178
    0
      build/makerules.sh
  8. 35
    0
      build/misc.sh
  9. 34
    0
      build/processor.sh
  10. 73
    0
      build/scaffold.sh
  11. 89
    0
      build/sources.sh
  12. 58
    0
      build/stirrups.sh
  13. 29
    0
      build/translations.sh
  14. 35
    0
      build/xmlfiles.sh
  15. 0
    777
      build/xmltree.sh

+ 112
- 0
build/build_main.sh View File

@@ -0,0 +1,112 @@
#!/bin/sh

basedir="$(dirname $0)/.."

[ -z "$inc_filenames" ] && . "$basedir/build/filenames.sh"
[ -z "$inc_buildrun" ] && . "$basedir/build/buildrun.sh"
[ -z "$inc_help" ] && . "$basedir/build/help.sh"
[ -z "$inc_languages" ] && . "$basedir/build/languages.sh"
[ -z "$inc_makerules" ] && . "$basedir/build/makerules.sh"
[ -z "$inc_misc" ] && . "$basedir/build/misc.sh"
[ -z "$inc_processor" ] && . "$basedir/build/processor.sh"
[ -z "$inc_scaffold" ] && . "$basedir/build/scaffold.sh"
[ -z "$inc_sources" ] && . "$basedir/build/sources.sh"

while [ -n "$*" ]; do
case "$1" in
-s|--statusdir|--status-dir)
[ -n "$*" ] && shift 1 && statusdir="$1"
;;
--domain)
[ -n "$*" ] && shift 1 && domain="$1"
;;
--source)
[ -n "$*" ] && shift 1 && basedir="$1"
;;
-d|--dest|--destination)
[ -n "$*" ] && shift 1 && target="$1"
;;
-h|--help)
command="help"
;;
build_into)
command="$1$command"
[ -n "$*" ] && shift 1 && target="$1"
;;
build_xmlstream)
command="$1$command"
[ -n "$*" ] && shift 1 && workfile="$1"
[ -n "$*" ] && shift 1 && olang="$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"
[ -n "$*" ] && shift 1 && workfile="$1"
[ -n "$*" ] && shift 1 && processor="$1"
[ -n "$*" ] && shift 1 && olang="$1"
;;
sourceglobs)
command="$1$command"
[ -n "$*" ] && shift 1 && sourcesfile="$1"
;;
cast_globfile)
command="$1$command"
[ -n "$*" ] && shift 1 && sourceglobfile="$1"
[ -n "$*" ] && shift 1 && lang="$1"
[ -n "$*" ] && shift 1 && globfile="$1"
;;
*)
print_error "Unknown option $1"
exit 1
;;
esac
[ -n "$*" ] && shift 1
done

if [ -n "$statusdir" ]; then
mkdir -p "$statusdir"
if [ ! -w "$statusdir" -o ! -d "$statusdir" ]; then
print_error "Unable to set up status directory in \"$statusdir\",
either select a status directory that exists and is writable,
or run the build script without output to a status directory"
exit 1
fi
fi

case "$command" in
build_into)
[ -z "$target" ] && print_error "Missing destination directory" && exit 1
build_into
;;
process_file)
[ -z "$workfile" ] && print_error "Need at least input file" && exit 1
process_file "$workfile" "$processor" "$olang"
;;
build_xmlstream)
[ -z "$workfile" ] && print_error "Missing xhtml file name" && exit 1
build_xmlstream "$(get_shortname "$workfile")" "$(get_language "$workfile")" "$olang"
;;
tree_maker)
[ -z "$tree" ] && tree="$basedir"
[ -z "$target" ] && print_error "Missing target location" && exit 1
tree_maker "$tree" "$target"
;;
sourceglobs)
[ -z "$sourcesfile" ] && print_error "Missing .sources file" && exit 1
sourceglobs "$sourcesfile"
;;
cast_globfile)
[ -z "$sourceglobfile" -o -z "$lang" -o -z "$globfile" ] && print_error "Need source globfile language and globfile" && exit 1
cast_globfile "$sourceglobfile" "$lang" "$globfile"
;;
*help*)
print_help
;;
*)
print_error "Urecognised command or no command given"
;;
esac

+ 31
- 0
build/buildrun.sh View File

@@ -0,0 +1,31 @@
#!/bin/sh

inc_buildrun=true
[ -z "$inc_makerules" ] && . "$basedir/build/makerules.sh"
[ -z "$inc_misc" ] && . "$basedir/build/misc.sh"
[ -z "$inc_stirrups" ] && . "$basedir/build/stirrups.sh"

build_into(){
ncpu="$(cat /proc/cpuinfo |grep ^processor |wc -l)"

[ -w "$statusdir" -a -d "$statusdir" ] && \
manifest="$(tempfile -d "$statusdir" -p mnfst)" \
|| manifest="$(tempfile -p w3bld)"

make -C "$basedir" \
| logstatus premake

dir_maker "$basedir" "$target"
tree_maker "$basedir" "$target" \
| logstatus Makefile \
| build_manifest "$manifest" \
| make -j $ncpu -f - \
| logstatus buildlog

remove_orphans "$target" <"$manifest" \
| logstatus removed

[ -w "$statusdir" -a -d "$statusdir" ] && \
mv "$manifest" "$statusdir/manifest" \
|| rm "$manifest"
}

+ 51
- 0
build/filenames.sh View File

@@ -0,0 +1,51 @@
#!/bin/sh

inc_filenames=true
[ -z "$inc_languages" ] && . "$basedir/build/languages.sh"

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 formated for inclusion
# in xml stream
shortname="$1"

langfilter=$(
echo "$shortname".[a-z][a-z].xhtml \
| sed -r 's;[^ ]+.([a-z]{2}).xhtml;\1;g;s; ;|;g'
)
languages |egrep "^($langfilter) " \
| sed -r 's:^([a-z]{2}) (.+)$:<tr id="\1">\2</tr>:g'
}

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

#echo "$(echo "$1" | sed -r 's:\.[a-z]{2}.xhtml$::')";
echo "${1%.??.xhtml}"
}

get_processor(){
# find the xslt script which is responsible for processing
# a given xhtml file.
# expects the shortname of the file as input (i.e. the
# the file path without language and file endings)
shortname="$1"
if [ -f "${shortname}.xsl" ]; then
echo "${shortname}.xsl"
else
location="$(dirname "$shortname")"
until [ -f "$location/default.xsl" -o "$location" = . -o "$location" = / ]; do
location="$(dirname "$location")"
done
echo "$location/default.xsl"
fi
}

+ 29
- 0
build/fundraising.sh View File

@@ -0,0 +1,29 @@
#!/bin/sh

inc_fundraising=true
[ -z "$inc_filenames" ] && . "$basedir/build/filenames.sh"
[ -z "$inc_languages" ] && . "$basedir/build/languages.sh"

cache_fundraising(){
cache_fundraising="$(for lang in $(get_languages); do
if [ -f "$basedir/fundraising-${lang}.xml" ]; then
echo -n " ${lang}:<$basedir/fundraising-${lang}.xml> "
elif [ -f "$basedir/fundraising-en.xml" ]; then
echo -n " ${lang}:<$basedir/fundraising-en.xml> "
fi
done)"
}

get_fundraisingfile(){
# get the fundraising file for a given language
# TODO: integrate with regular texts function
lang="$1"

if [ -n "$cache_fundraising" ]; then
echo "$cache_fundraising" |sed -r 's;^.* '"$lang"':<([^>]+)> .*$;\1;p'
elif [ -f "$basedir/fundraising-${lang}.xml" ]; then
echo "$basedir/fundraising-${lang}.xml"
elif [ -f "$basedir/fundraising-en.xml" ]; then
echo "$basedir/fundraising-en.xml"
fi
}

+ 57
- 0
build/help.sh View File

@@ -0,0 +1,57 @@
#!/bin/sh

inc_help=true

print_help(){
cat <<-EOHELP

Usage:
------------------------------------------------------------------------------
$0 [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.

$0 [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.

$0 [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 choosen automatically.
$0 [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 paramter
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.
Pathes 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.
EOHELP
}

+ 46
- 0
build/languages.sh View File

@@ -0,0 +1,46 @@
#!/bin/sh

# lazy-ass include guard
inc_languages=true
[ -z "$inc_filenames" ] && . "$basedir/build/filenames.sh"

languages(){
cat <<EOL
ar &#1575;&#1604;&#1593;&#1585;&#1576;&#1610;&#1617;&#1577;
bg Български
bs Bosanski
ca Català
cs Česky
da Dansk
de Deutsch
el Ελληνικά
en English
es Español
et Eesti
fi Suomi
fr Français
hr Hrvatski
hu Magyar
it Italiano
ku Kurdî
mk Mакедонски
nb Norsk (bokmål)
nl Nederlands
nn Norsk (nynorsk)
pl Polski
pt Português
ro Română
ru Русский
sk Slovenčina
sl Slovenščina
sq Shqip
sr Српски
sv Svenska
tr Türkçe
uk Українська
EOL
}

get_languages(){
languages |cut -d\ -f1
}

+ 178
- 0
build/makerules.sh View File

@@ -0,0 +1,178 @@
#!/bin/sh

inc_makerules=true
[ -z "$inc_translations" ] && . "$basedir/build/translations.sh"
[ -z "$inc_filenames" ] && . "$basedir/build/filenames.sh"
[ -z "$inc_fundraising" ] && . "$basedir/build/fundraising.sh"
[ -z "$inc_languages" ] && . "$basedir/build/languages.sh"
[ -z "$inc_sources" ] && . "$basedir/build/sources.sh"

mes(){
# make escape... escape a filename for make syntax
# possibly not complete
while [ -n "$*" ]; do
echo "$1"
shift 1
done \
| sed -r 's;([ #]);\\\1;g' \
| tr '\n' ' '
}

glob_maker(){
sourcesfile="$1"

filedir=$(dirname "$sourcesfile")
shortbase="$(basename "$sourcesfile" |sed -r 's;\.sources$;;')"
sourceglobfile="${filedir}/._._${shortbase}.sourceglobs"

cat <<MakeEND
$(mes "$sourceglobfile"): $(mes $(all_sources "$sourcesfile"))
$0 --source "$basedir" sourceglobs "$sourcesfile" >"$sourceglobfile"
MakeEND

for lang in $(get_languages); do
globfile="${filedir}/._._${shortbase}.${lang}.sourceglobs"
cat <<MakeEND
$(mes "$globfile"): $(mes "$sourceglobfile")
$0 --source "$basedir" cast_globfile "$sourceglobfile" "$lang" "$globfile"
MakeEND
done
}

xhtml_maker(){
# generate make rules for building html files out of xhtml
# account for included xml files and xsl rules

shortname="$1"
outpath="$2"

textsen="$(get_textsfile "en")"
menufile="$basedir/tools/menu-global.xml"
filedir="$(dirname "$shortname")"
shortbase="$(basename "$shortname")"
processor="$(get_processor "$shortname")"

[ -f "$shortname".rss.xsl ] && bool_rss=true || bool_rss=false
[ -f "$shortname".ics.xsl ] && bool_ics=true || bool_ics=false

olang="$(echo "${shortname}".[a-z][a-z].xhtml "${shortname}".[e]n.xhtml |sed -rn 's;^.*\.([a-z]{2})\.xhtml.*$;\1;p')"

if [ "${shortbase}" = "$(basename "$filedir")" ] && \
[ ! -f "${filedir}/index.${olang}.xhtml" ]; then
bool_indexname=true
else
bool_indexname=false
fi

[ -f "${shortname}.sources" ] && bool_sourceinc=true || bool_sourceinc=false

# For speed considerations: avoid all disk I/O in this loop
for lang in $(get_languages); do
infile="${shortname}.${lang}.xhtml"
[ -f "$infile" ] && depfile="$infile" || depfile="${shortname}.${olang}.xhtml"

outbase="${shortbase}.${lang}.html"
outfile="${outpath}/${outbase}"
outlink="${outpath}/${shortbase}.html.$lang"
rssfile="${outpath}/${shortbase}.${lang}.rss"
icsfile="${outpath}/${shortbase}.${lang}.ics"

textsfile="$(get_textsfile "$lang")"
fundraisingfile="$(get_fundraisingfile "$lang")"
$bool_sourceinc && sourceglobs="${filedir}/._._${shortbase}.${lang}.sourceglobs" || unset sourceglobs

cat <<MakeEND
all: $(mes "$outfile" "$outlink")
$(mes "$outfile"): $(mes "$depfile" "$processor" "$textsen" "$textsfile" "$fundraisingfile" "$menufile" "$sourceglobs")
$0 --source "$basedir" process_file "${infile}" "$processor" "$olang" >"$outfile"
$(mes "$outlink"):
ln -sf "${outbase}" "${outlink}"
MakeEND
$bool_rss && cat<<MakeEND
all: $(mes "$rssfile")
$(mes "$rssfile"): $(mes "$depfile" "${shortname}.rss.xsl" "$textsen" "$textsfile" "$fundraisingfile" "$menufile" "$sourceglobs")
$0 --source "$basedir" process_file "${infile}" "${shortname}.rss.xsl" "$olang" >"$rssfile"
MakeEND
$bool_ics && cat<<MakeEND
all: $(mes "$icsfile")
$(mes "$icsfile"): $(mes "$depfile" "${shortname}.ics.xsl" "$textsen" "$textsfile" "$fundraisingfile" "$menufile" "$sourceglobs")
$0 --source "$basedir" process_file "${infile}" "${shortname}.ics.xsl" "$olang" >"$icsfile"
MakeEND
$bool_indexname && cat <<MakeEND
all: $(mes "$outpath/index.${lang}.html" "$outpath/index.html.$lang")
$(mes "$outpath/index.${lang}.html"):
ln -sf "$outbase" "$outpath/index.${lang}.html"
$(mes "$outpath/index.html.$lang"):
ln -sf "$outbase" "$outpath/index.html.$lang"
MakeEND
done
}

copy_maker(){
# generate make rule for copying a plain file

infile="$1"
outpath="$2"
outfile="$outpath/$(basename "$infile")"
cat <<MakeEND
all: $(mes "$outfile")
$(mes "$outfile"): $(mes "$infile")
cp "$infile" "$outfile"
MakeEND
}

xslt_dependencies(){
file="$1"

cat "$file" \
| tr '\n' ' ' \
| sed -r 's;(<xsl:(include|import)[^>]*>);\n\1\n;g' \
| sed -nr '/<xsl:(include|import)[^>]*>/s;^.*href="([^"]*)".*$;\1;gp'
}

xslt_maker(){
# find external references in a xsl file and generate
# Make dependencies accordingly

file="$1"
dir="$(dirname "$file")"

deps="$(xslt_dependencies "$file" |while read dep; do mes "$dir/$dep"; done)"
cat <<MakeEND
$(mes "$file"): $deps
touch "$file"
MakeEND
}

tree_maker(){
# walk through file tree and issue Make rules according to file type
input="$(echo "$1" |sed -r 's:/$::')"
output="$(echo "$2" |sed -r 's:/$::')"

cache_textsfile
cache_fundraising

echo ".PHONY: all"
find "$input" -type f \
| sed -r "/(^|\/)\.svn($|\/)|^\.\.$/d;s;^$input/*;;" \
| while read filepath; do
inpfile="${input}/$filepath"
case "$filepath" in
Makefile) true;;
*.xml) true;;
*.sourceglobs) true;;
*.sources) glob_maker "$inpfile";;
*.xsl) xslt_maker "$inpfile";;
*.xhtml) copy_maker "$inpfile" "$output/source/$(dirname "$filepath")";;
*) copy_maker "$inpfile" "$output/$(dirname "$filepath")";;
esac
done

find "$input" -type f -and -name '*.[a-z][a-z].xhtml' \
| sed -r "/(^|\/)\.svn($|\/)|^\.\.$/d;s;^$input/*(.+)\.[a-z]{2}\.xhtml$;\1;" \
| sort -u \
| while read shortpath; do
xhtml_maker "${input}/$shortpath" "$output/$(dirname "$shortpath")"
done
}


+ 35
- 0
build/misc.sh View File

@@ -0,0 +1,35 @@
#!/bin/sh

inc_misc=true

debug(){
dbg_file=/dev/stderr

if [ "$#" -ge 1 ]; then
echo "$*" >"$dbg_file"
else
tee -a "$dbg_file"
fi
}

match(){
echo -E "$1" |egrep -q "$2"
}

logstatus(){
# pipeline atom to write data streams into a log file
# log file will be created inside statusdir
# if statusdir is not enabled, we won't log to a file
file="$1"

if [ -w "$statusdir" ]; then
tee "$statusdir/$file"
else
cat
fi
}

print_error(){
echo "Error: $*" |logstatus lasterror >/dev/stderr
echo "Run '$0 --help' to see usage instructions" >/dev/stderr
}

+ 34
- 0
build/processor.sh View File

@@ -0,0 +1,34 @@
#!/bin/sh

inc_processor=true
[ -z "$inc_filenames" ] && . "$basedir/build/filenames.sh"
[ -z "$inc_scaffold" ] && . "$basedir/build/scaffold.sh"

process_file(){
infile="$1"
processor="$2"
olang="$3"

domain="www.fsfe.org"

shortname=$(get_shortname "$infile")
lang=$(get_language "$infile")
[ -z "$processor" ] && processor="$(get_processor "$shortname")"

build_xmlstream "$shortname" "$lang" "$olang" \
| xsltproc "$processor" - \
| sed -r '
s;< *(a|link)( [^>]*)? href="https?://'"$domain"'/([^"]*)";<\1\2 href="/\3";g
s;< *(a|link)( [^>]*)? href='\''https?://'"$domain"'/([^'\'']*)'\'';<\1\2 href='\''/\3'\'';g

s;< *(a|link)( [^>]*)? href="(https?://[^"]*)";<\1\2 href="#== norewrite ==\3";g
s;< *(a|link)( [^>]*)? href="([^#"])([^"]*/)?([^\./"]*\.)(html|rss|ics)(#[^"]*)?";<\1\2 href="\3\4\5'"$lang"'.\6\7";g
s;< *(a|link)( [^>]*)? href="([^#"]*/)(#[^"]*)?";<\1\2 href="\3index.'"$lang"'.html\4";g
s;< *(a|link)( [^>]*)? href="#== norewrite ==(https?://[^"]*)";<\1\2 href="\3";g

s;< *(a|link)( [^>]*)? href='\''(https?://[^'\'']*)'\'';<\1\2 href='\''#== norewrite ==\3'\'';g
s;< *(a|link)( [^>]*)? href='\''([^#'\''])([^'\'']*/)?([^\./'\'']*\.)(html|rss|ics)(#[^'\'']*)?'\'';<\1\2 href='\''\3\4\5'"$lang"'.\6\7'\'';g
s;< *(a|link)( [^>]*)? href='\''([^#'\'']*/)(#[^'\'']*)?'\'';<\1\2 href='\''\3index.'"$lang"'.html\4'\'';g
s;< *(a|link)( [^>]*)? href='\''#== norewrite ==(https?://[^'\'']*)'\'';<\1\2 href='\''\3'\'';g
'
}

+ 73
- 0
build/scaffold.sh View File

@@ -0,0 +1,73 @@
#!/bin/sh

inc_scaffold=true
[ -z "$inc_xmlfiles" ] && . "$basedir/build/xmlfiles.sh"
[ -z "$inc_translations" ] && . "$basedir/build/translations.sh"
[ -z "$inc_filenames" ] && . "$basedir/build/filenames.sh"
[ -z "$inc_fundraising" ] && . "$basedir/build/fundraising.sh"
[ -z "$inc_sources" ] && . "$basedir/build/sources.sh"

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="$3"

dirname="$(dirname "$shortname")"
metaname="$(echo "$shortname" |sed -r 's;.*/\.\.(/.+)$;\1;')"
texts_xml=$(get_textsfile $lang)
fundraising_xml=$(get_fundraisingfile $lang)
date="$(date +%Y-%m-%d)"
time="$(date +%H:%M:%S)"
outdated=no

[ -z "$olang" ] && olang="en"
if [ -f "${shortname}.${lang}.xhtml" ]; then
act_lang="$lang"
[ "${shortname}.${olang}.xhtml" -nt "${shortname}.${lang}.xhtml" ] && outdated=yes
else
act_lang="$olang"
fi

infile="${shortname}.${act_lang}.xhtml"

cat <<-EOF
<buildinfo
date="$date"
original="$olang"
filename="$metaname"
dirname="$dirname"
language="$lang"
outdated="$outdated"
>
<trlist>
$(list_langs "$shortname")
</trlist>
<menuset>$(include_xml "$basedir/tools/menu-global.xml")</menuset>
<textsetbackup>$(include_xml "$basedir/tools/texts-en.xml")</textsetbackup>
<textset>$(include_xml "$texts_xml")</textset>
<fundraising>$(include_xml "$fundraising_xml")</fundraising>
<document
language="$act_lang"
$(get_attributes "$infile")
>
<timestamp>
\$Date:$date $time \$
\$Author: automatic \$
</timestamp>
<set>
$(auto_sources "${shortname}.sources" "$lang")
</set>
$(include_xml "$infile")
</document>
</buildinfo>
EOF
}


+ 89
- 0
build/sources.sh View File

@@ -0,0 +1,89 @@
#!/bin/sh

inc_sources=true
[ -z "$inc_xmlfiles" ] && . "$basedir/build/xmlfiles.sh"

sourceglobs(){
# read a .sources file and glob up referenced
# source files for processing in list_sources
sourcesfile="$1"

if [ -f "$sourcesfile" ]; then
sed -rn 's;:global$;*.[a-z][a-z].xml;gp' "$sourcesfile" \
| while read glob; do
echo "$basedir/"$glob
done \
| sed -rn 's:\.[a-z]{2}\.xml( |$):\n:gp' \
| sort -u
fi
}

all_sources(){
# read a .sources file and glob up all referenced
# source files
sourcesfile="$1"

if [ -f "$sourcesfile" ]; then
sed -rn 's;:global$;*.[a-z][a-z].xml;gp' "$sourcesfile" \
| while read glob; do
echo "$basedir/"$glob
done |grep -vF "[a-z][a-z].xml"
fi
}

list_sources(){
# read a .sources file and generate a list
# of all referenced xml files with preference
# for a given language
sourcesfile="$1"
lang="$2"

# Optional 3rd parameter: preglobbed list of source files
# can lead to speed gain in some cases
[ "$#" -ge 3 ] && \
sourceglobs="$3" \
|| sourceglobs="$(sourceglobs "$sourcesfile")"

for base in $sourceglobs; do
echo "${base}".[a-z][a-z].xml "${base}".en.[x]ml "${base}.${lang}".[x]ml
done |sed -rn 's;^.*\.([a-z]{2})\.xml.*$;\1;p'
}

auto_sources(){
# import elements from source files, add file name
# attribute to first element included from each file
sourcesfile="$1"
lang="$2"

globfile="$(echo "$sourcesfile" |sed -r 's;(^|.*/)([^/]+).sources$;\1._._\2.'"$lang"'.sourceglobs;')"

if [ -e "$globfile" ];then
cat "$globfile"
else
list_sources "$sourcesfile" "$lang"
fi | while read source; do
echo -n "$source\t"
include_xml "$source"
echo
done \
| sed -r 's:^([^\t]+)\t[^<]*(< *[^ >]+)([^>]*>):\2 filename="\1" \3:'
}

cast_globfile(){
sourceglobfile="$1"
lang="$2"
globfile="$3"

sources="$(list_sources "###" "$lang" "$(cat "$sourceglobfile")")"

[ -f "$globfile" ] && \
[ "$sources" = "$(cat "$globfile")" ] \
|| echo "$sources" >"$globfile"

if [ "$sourceglobfile" -nt "$globfile" ]; then
echo "$sources" |while read incfile; do
[ "$incfile" -nt "$globfile" ] && touch "$globfile" || true
done
fi
}


+ 58
- 0
build/stirrups.sh View File

@@ -0,0 +1,58 @@
#!/bin/sh

inc_stirrups=true
[ -z "$inc_misc" ] && . "$basedir/build/misc.sh"

dir_maker(){
# set up directory tree for output
# optimise by only issuing mkdir commands
# for leaf directories

input="$(echo "$1" |sed -r 's:/$::')"
output="$(echo "$2" |sed -r 's:/$::')"

curpath="$output"
find "$input" -depth -type d \
| sed -r "/(^|\/)\.svn($|\/)|^\.\.$/d;s;^$input/*;;" \
| while read filepath; do
oldpath="$curpath"
curpath="$output/$filepath/"
srcdir="$output/source/$filepath/"
match "$oldpath" "^$curpath" || mkdir -p "$curpath" "$srcdir"
done
}

build_manifest(){
# pass Makefile throug on pipe and generate
# list of all make tagets

outfile="$1"
while line="$(line)"; do
echo "$line"
echo "$line" \
| sed -nr 's;/\./;/;g;s;\\ ; ;g;s;([^:]+) :.*;\1;p' \
>> "$outfile"
done
}

remove_orphans(){
# read list of files which should be in a directory tree
# and remove everything else

tree="$1"

# idea behind the algorithm:
# `find` will list every existing file once
# the manifest of all make targets will list all wanted files once
# concatenate all lines from manifest and `find`
# every file which is listed twice is wanted and exists,
# we use 'uniq -u' to drop those from the list
# remaining single files exist only in the tree and are to be removed

(find "$tree" -type f -or -type l; cat) \
| sort \
| uniq -u \
| while read file; do
match "$file" "^$tree" && rm -v "$file"
done
}

+ 29
- 0
build/translations.sh View File

@@ -0,0 +1,29 @@
#!/bin/sh

inc_translations=true
[ -z "$inc_filenames" ] && . "$basedir/build/filenames.sh"
[ -z "$inc_languages" ] && . "$basedir/build/languages.sh"

cache_textsfile(){
cache_textsfile="$(for lang in $(get_languages); do
if [ -f "$basedir/tools/texts-${lang}.xml" ]; then
echo -n " ${lang}:<$basedir/tools/texts-${lang}.xml> "
else
echo -n " ${lang}:<$basedir/tools/texts-en.xml> "
fi
done)"
}

get_textsfile(){
# get the texts file for a given language
# fall back to english if necessary
lang="$1"

if [ -n "$cache_textsfile" ]; then
echo "$cache_textsfile" |sed -r 's;^.* '"$lang"':<([^>]+)> .*$;\1;p'
elif [ -f "$basedir/tools/texts-${1}.xml" ]; then
echo "$basedir/tools/texts-${1}.xml"
else
echo "$basedir/tools/texts-en.xml"
fi
}

+ 35
- 0
build/xmlfiles.sh View File

@@ -0,0 +1,35 @@
#!/bin/sh

inc_xmlfiles=true

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
file="$1"

if [ -f "$file" ]; then
# guess encoding from xml header
# we will convert everything to utf-8 prior to processing
enc="$(sed -nr 's:^.*<\?.*encoding="([^"]+)".*$:\1:p' "$file")"
[ -z "$enc" ] && enc="UTF-8"

iconv -f "$enc" -t "UTF-8" "$file" \
| tr '\n\t\r' ' ' \
| sed -r 's:<(\?[xX][mM][lL]|!DOCTYPE) [^>]+>::g
s:<[^!][^>]*>::;
s:</[^>]*>([^<]*((<[^>]+/>|<!([^>]|<[^>]*>)*>|<\?[^>]+>)[^<]*)*)?$:\1:;'
fi
}

get_attributes(){
# get attributes of top level element in a given
# XHTML file
file="$1"

cat "$file" \
| tr '\n\t\r' ' ' \
| sed -rn 's;^.*< *([xX]|[xX]?[hH][tT])[mM][lL] +([^>]*)>.*$;\2;p'
}


+ 0
- 777
build/xmltree.sh View File

@@ -1,777 +0,0 @@
#!/bin/sh


print_help(){
cat <<-EOHELP

Usage:
------------------------------------------------------------------------------
$0 [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.

$0 [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.

$0 [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 choosen automatically.
$0 [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 paramter
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.
Pathes 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.
EOHELP
}

debug(){
dbg_file=/dev/stderr

if [ "$#" -ge 1 ]; then
echo "$*" >"$dbg_file"
else
tee -a "$dbg_file"
fi
}

match(){
echo -E "$1" |egrep -q "$2"
}

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
file="$1"

if [ -f "$file" ]; then
# guess encoding from xml header
# we will convert everything to utf-8 prior to processing
enc="$(sed -nr 's:^.*<\?.*encoding="([^"]+)".*$:\1:p' "$file")"
[ -z "$enc" ] && enc="UTF-8"

iconv -f "$enc" -t "UTF-8" "$file" \
| tr '\n\t\r' ' ' \
| sed -r 's:<(\?[xX][mM][lL]|!DOCTYPE) [^>]+>::g
s:<[^!][^>]*>::;
s:</[^>]*>([^<]*((<[^>]+/>|<!([^>]|<[^>]*>)*>|<\?[^>]+>)[^<]*)*)?$:\1:;'
fi
}

get_attributes(){
# get attributes of top level element in a given
# XHTML file
file="$1"

cat "$file" \
| tr '\n\t\r' ' ' \
| sed -rn 's;^.*< *([xX]|[xX]?[hH][tT])[mM][lL] +([^>]*)>.*$;\2;p'
}

sourceglobs(){
# read a .sources file and glob up referenced
# source files for processing in list_sources
sourcesfile="$1"

if [ -f "$sourcesfile" ]; then
sed -rn 's;:global$;*.[a-z][a-z].xml;gp' "$sourcesfile" \
| while read glob; do
echo "$basedir/"$glob
done \
| sed -rn 's:\.[a-z]{2}\.xml( |$):\n:gp' \
| sort -u
fi
}

all_sources(){
# read a .sources file and glob up all referenced
# source files
sourcesfile="$1"

if [ -f "$sourcesfile" ]; then
sed -rn 's;:global$;*.[a-z][a-z].xml;gp' "$sourcesfile" \
| while read glob; do
echo "$basedir/"$glob
done |grep -vF "[a-z][a-z].xml"
fi
}

list_sources(){
# read a .sources file and generate a list
# of all referenced xml files with preference
# for a given language
sourcesfile="$1"
lang="$2"

# Optional 3rd parameter: preglobbed list of source files
# can lead to speed gain in some cases
[ "$#" -ge 3 ] && \
sourceglobs="$3" \
|| sourceglobs="$(sourceglobs "$sourcesfile")"

for base in $sourceglobs; do
echo "${base}".[a-z][a-z].xml "${base}".en.[x]ml "${base}.${lang}".[x]ml
done |sed -rn 's;^.*\.([a-z]{2})\.xml.*$;\1;p'
}

auto_sources(){
# import elements from source files, add file name
# attribute to first element included from each file
sourcesfile="$1"
lang="$2"

globfile="$(echo "$sourcesfile" |sed -r 's;(^|.*/)([^/]+).sources$;\1._._\2.'"$lang"'.sourceglobs;')"

if [ -e "$globfile" ];then
cat "$globfile"
else
list_sources "$sourcesfile" "$lang"
fi | while read source; do
echo -n "$source\t"
include_xml "$source"
echo
done \
| sed -r 's:^([^\t]+)\t[^<]*(< *[^ >]+)([^>]*>):\2 filename="\1" \3:'
}

languages(){
cat <<EOL
ar &#1575;&#1604;&#1593;&#1585;&#1576;&#1610;&#1617;&#1577;
bg Български
bs Bosanski
ca Català
cs Česky
da Dansk
de Deutsch
el Ελληνικά
en English
es Español
et Eesti
fi Suomi
fr Français
hr Hrvatski
hu Magyar
it Italiano
ku Kurdî
mk Mакедонски
nb Norsk (bokmål)
nl Nederlands
nn Norsk (nynorsk)
pl Polski
pt Português
ro Română
ru Русский
sk Slovenčina
sl Slovenščina
sq Shqip
sr Српски
sv Svenska
tr Türkçe
uk Українська
EOL
}

get_languages(){
languages |cut -d\ -f1
}

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 formated for inclusion
# in xml stream
shortname="$1"

langfilter=$(
echo "$shortname".[a-z][a-z].xhtml \
| sed -r 's;[^ ]+.([a-z]{2}).xhtml;\1;g;s; ;|;g'
)
languages |egrep "^($langfilter) " \
| sed -r 's:^([a-z]{2}) (.+)$:<tr id="\1">\2</tr>:g'
}

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

#echo "$(echo "$1" | sed -r 's:\.[a-z]{2}.xhtml$::')";
echo "${1%.??.xhtml}"
}

cache_textsfile(){
cache_textsfile="$(for lang in $(get_languages); do
if [ -f "$basedir/tools/texts-${lang}.xml" ]; then
echo -n " ${lang}:<$basedir/tools/texts-${lang}.xml> "
else
echo -n " ${lang}:<$basedir/tools/texts-en.xml> "
fi
done)"
}
get_textsfile(){
# get the texts file for a given language
# fall back to english if necessary
lang="$1"

if [ -n "$cache_textsfile" ]; then
echo "$cache_textsfile" |sed -r 's;^.* '"$lang"':<([^>]+)> .*$;\1;p'
elif [ -f "$basedir/tools/texts-${1}.xml" ]; then
echo "$basedir/tools/texts-${1}.xml"
else
echo "$basedir/tools/texts-en.xml"
fi
}

cache_fundraising(){
cache_fundraising="$(for lang in $(get_languages); do
if [ -f "$basedir/fundraising-${lang}.xml" ]; then
echo -n " ${lang}:<$basedir/fundraising-${lang}.xml> "
elif [ -f "$basedir/fundraising-en.xml" ]; then
echo -n " ${lang}:<$basedir/fundraising-en.xml> "
fi
done)"
}
get_fundraisingfile(){
# get the fundraising file for a given language
# TODO: integrate with regular texts function
lang="$1"

if [ -n "$cache_fundraising" ]; then
echo "$cache_fundraising" |sed -r 's;^.* '"$lang"':<([^>]+)> .*$;\1;p'
elif [ -f "$basedir/fundraising-${lang}.xml" ]; then
echo "$basedir/fundraising-${lang}.xml"
elif [ -f "$basedir/fundraising-en.xml" ]; then
echo "$basedir/fundraising-en.xml"
fi
}

get_processor(){
# find the xslt script which is responsible for processing
# a given xhtml file.
# expects the shortname of the file as input (i.e. the
# the file path without language and file endings)

shortname="$1"

if [ -f "${shortname}.xsl" ]; then
echo "${shortname}.xsl"
else
location="$(dirname "$shortname")"
until [ -f "$location/default.xsl" -o "$location" = . -o "$location" = / ]; do
location="$(dirname "$location")"
done
echo "$location/default.xsl"
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"
olang="$3"

dirname="$(dirname "$shortname")"
metaname="$(echo "$shortname" |sed -r 's;.*/\.\.(/.+)$;\1;')"
texts_xml=$(get_textsfile $lang)
fundraising_xml=$(get_fundraisingfile $lang)
date="$(date +%Y-%m-%d)"
time="$(date +%H:%M:%S)"
outdated=no

[ -z "$olang" ] && olang="en"
if [ -f "${shortname}.${lang}.xhtml" ]; then
act_lang="$lang"
[ "${shortname}.${olang}.xhtml" -nt "${shortname}.${lang}.xhtml" ] && outdated=yes
else
act_lang="$olang"
fi

infile="${shortname}.${act_lang}.xhtml"

cat <<-EOF
<buildinfo
date="$date"
original="$olang"
filename="$metaname"
dirname="$dirname"
language="$lang"
outdated="$outdated"
>
<trlist>
$(list_langs "$shortname")
</trlist>
<menuset>$(include_xml "$basedir/tools/menu-global.xml")</menuset>
<textsetbackup>$(include_xml "$basedir/tools/texts-en.xml")</textsetbackup>
<textset>$(include_xml "$texts_xml")</textset>
<fundraising>$(include_xml "$fundraising_xml")</fundraising>
<document
language="$act_lang"
$(get_attributes "$infile")
>
<timestamp>
\$Date:$date $time \$
\$Author: automatic \$
</timestamp>
<set>
$(auto_sources "${shortname}.sources" "$lang")
</set>
$(include_xml "$infile")
</document>
</buildinfo>
EOF
}

mes(){
# make escape... escape a filename for make syntax
# possibly not complete
while [ -n "$*" ]; do
echo "$1"
shift 1
done \
| sed -r 's;([ #]);\\\1;g' \
| tr '\n' ' '
}

process_file(){
infile="$1"
processor="$2"
olang="$3"

shortname=$(get_shortname "$infile")
lang=$(get_language "$infile")
[ -z "$processor" ] && processor="$(get_processor "$shortname")"

build_xmlstream "$shortname" "$lang" "$olang" \
| xsltproc "$processor" - \
| sed -r '
s;< *(a|link)( [^>]*)? href="https?://'"$domain"'/([^"]*)";<\1\2 href="/\3";g
s;< *(a|link)( [^>]*)? href='\''https?://'"$domain"'/([^'\'']*)'\'';<\1\2 href='\''/\3'\'';g

s;< *(a|link)( [^>]*)? href="(https?://[^"]*)";<\1\2 href="#== norewrite ==\3";g
s;< *(a|link)( [^>]*)? href="([^#"])([^"]*/)?([^\./"]*\.)(html|rss|ics)(#[^"]*)?";<\1\2 href="\3\4\5'"$lang"'.\6\7";g
s;< *(a|link)( [^>]*)? href="([^#"]*/)(#[^"]*)?";<\1\2 href="\3index.'"$lang"'.html\4";g
s;< *(a|link)( [^>]*)? href="#== norewrite ==(https?://[^"]*)";<\1\2 href="\3";g

s;< *(a|link)( [^>]*)? href='\''(https?://[^'\'']*)'\'';<\1\2 href='\''#== norewrite ==\3'\'';g
s;< *(a|link)( [^>]*)? href='\''([^#'\''])([^'\'']*/)?([^\./'\'']*\.)(html|rss|ics)(#[^'\'']*)?'\'';<\1\2 href='\''\3\4\5'"$lang"'.\6\7'\'';g
s;< *(a|link)( [^>]*)? href='\''([^#'\'']*/)(#[^'\'']*)?'\'';<\1\2 href='\''\3index.'"$lang"'.html\4'\'';g
s;< *(a|link)( [^>]*)? href='\''#== norewrite ==(https?://[^'\'']*)'\'';<\1\2 href='\''\3'\'';g
'
}

cast_globfile(){
sourceglobfile="$1"
lang="$2"
globfile="$3"

sources="$(list_sources "###" "$lang" "$(cat "$sourceglobfile")")"

[ -f "$globfile" ] && \
[ "$sources" = "$(cat "$globfile")" ] \
|| echo "$sources" >"$globfile"

if [ "$sourceglobfile" -nt "$globfile" ]; then
echo "$sources" |while read incfile; do
[ "$incfile" -nt "$globfile" ] && touch "$globfile" || true
done
fi
}

glob_maker(){
sourcesfile="$1"

filedir=$(dirname "$sourcesfile")
shortbase="$(basename "$sourcesfile" |sed -r 's;\.sources$;;')"
sourceglobfile="${filedir}/._._${shortbase}.sourceglobs"

cat <<MakeEND
$(mes "$sourceglobfile"): $(mes $(all_sources "$sourcesfile"))
$0 --source "$basedir" sourceglobs "$sourcesfile" >"$sourceglobfile"
MakeEND

for lang in $(get_languages); do
globfile="${filedir}/._._${shortbase}.${lang}.sourceglobs"
cat <<MakeEND
$(mes "$globfile"): $(mes "$sourceglobfile")
$0 --source "$basedir" cast_globfile "$sourceglobfile" "$lang" "$globfile"
MakeEND
done
}

xhtml_maker(){
# generate make rules for building html files out of xhtml
# account for included xml files and xsl rules

shortname="$1"
outpath="$2"

textsen="$(get_textsfile "en")"
menufile="$basedir/tools/menu-global.xml"
filedir="$(dirname "$shortname")"
shortbase="$(basename "$shortname")"
processor="$(get_processor "$shortname")"

[ -f "$shortname".rss.xsl ] && bool_rss=true || bool_rss=false
[ -f "$shortname".ics.xsl ] && bool_ics=true || bool_ics=false

olang="$(echo "${shortname}".[a-z][a-z].xhtml "${shortname}".[e]n.xhtml |sed -rn 's;^.*\.([a-z]{2})\.xhtml.*$;\1;p')"

if [ "${shortbase}" = "$(basename "$filedir")" ] && \
[ ! -f "${filedir}/index.${olang}.xhtml" ]; then
bool_indexname=true
else
bool_indexname=false
fi

[ -f "${shortname}.sources" ] && bool_sourceinc=true || bool_sourceinc=false

# For speed considerations: avoid all disk I/O in this loop
for lang in $(get_languages); do
infile="${shortname}.${lang}.xhtml"
[ -f "$infile" ] && depfile="$infile" || depfile="${shortname}.${olang}.xhtml"

outbase="${shortbase}.${lang}.html"
outfile="${outpath}/${outbase}"
outlink="${outpath}/${shortbase}.html.$lang"
rssfile="${outpath}/${shortbase}.${lang}.rss"
icsfile="${outpath}/${shortbase}.${lang}.ics"

textsfile="$(get_textsfile "$lang")"
fundraisingfile="$(get_fundraisingfile "$lang")"
$bool_sourceinc && sourceglobs="${filedir}/._._${shortbase}.${lang}.sourceglobs" || unset sourceglobs

cat <<MakeEND
all: $(mes "$outfile" "$outlink")
$(mes "$outfile"): $(mes "$depfile" "$processor" "$textsen" "$textsfile" "$fundraisingfile" "$menufile" "$sourceglobs")
$0 --source "$basedir" process_file "${infile}" "$processor" "$olang" >"$outfile"
$(mes "$outlink"):
ln -sf "${outbase}" "${outlink}"
MakeEND
$bool_rss && cat<<MakeEND
all: $(mes "$rssfile")
$(mes "$rssfile"): $(mes "$depfile" "${shortname}.rss.xsl" "$textsen" "$textsfile" "$fundraisingfile" "$menufile" "$sourceglobs")
$0 --source "$basedir" process_file "${infile}" "${shortname}.rss.xsl" "$olang" >"$rssfile"
MakeEND
$bool_ics && cat<<MakeEND
all: $(mes "$icsfile")
$(mes "$icsfile"): $(mes "$depfile" "${shortname}.ics.xsl" "$textsen" "$textsfile" "$fundraisingfile" "$menufile" "$sourceglobs")
$0 --source "$basedir" process_file "${infile}" "${shortname}.ics.xsl" "$olang" >"$icsfile"
MakeEND
$bool_indexname && cat <<MakeEND
all: $(mes "$outpath/index.${lang}.html" "$outpath/index.html.$lang")
$(mes "$outpath/index.${lang}.html"):
ln -sf "$outbase" "$outpath/index.${lang}.html"
$(mes "$outpath/index.html.$lang"):
ln -sf "$outbase" "$outpath/index.html.$lang"
MakeEND
done
}

copy_maker(){
# generate make rule for copying a plain file

infile="$1"
outpath="$2"
outfile="$outpath/$(basename "$infile")"
cat <<MakeEND
all: $(mes "$outfile")
$(mes "$outfile"): $(mes "$infile")
cp "$infile" "$outfile"
MakeEND
}

xslt_dependencies(){
file="$1"

cat "$file" \
| tr '\n' ' ' \
| sed -r 's;(<xsl:(include|import)[^>]*>);\n\1\n;g' \
| sed -nr '/<xsl:(include|import)[^>]*>/s;^.*href="([^"]*)".*$;\1;gp'
}

xslt_maker(){
# find external references in a xsl file and generate
# Make dependencies accordingly

file="$1"
dir="$(dirname "$file")"

deps="$(xslt_dependencies "$file" |while read dep; do mes "$dir/$dep"; done)"
cat <<MakeEND
$(mes "$file"): $deps
touch "$file"
MakeEND
}

dir_maker(){
# set up directory tree for output
# optimise by only issuing mkdir commands
# for leaf directories

input="$(echo "$1" |sed -r 's:/$::')"
output="$(echo "$2" |sed -r 's:/$::')"

curpath="$output"
find "$input" -depth -type d \
| sed -r "/(^|\/)\.svn($|\/)|^\.\.$/d;s;^$input/*;;" \
| while read filepath; do
oldpath="$curpath"
curpath="$output/$filepath/"
srcdir="$output/source/$filepath/"
match "$oldpath" "^$curpath" || mkdir -p "$curpath" "$srcdir"
done
}

tree_maker(){
# walk through file tree and issue Make rules according to file type
input="$(echo "$1" |sed -r 's:/$::')"
output="$(echo "$2" |sed -r 's:/$::')"

cache_textsfile
cache_fundraising

echo ".PHONY: all"
find "$input" -type f \
| sed -r "/(^|\/)\.svn($|\/)|^\.\.$/d;s;^$input/*;;" \
| while read filepath; do
inpfile="${input}/$filepath"
case "$filepath" in
Makefile) true;;
*.xml) true;;
*.sourceglobs) true;;
*.sources) glob_maker "$inpfile";;
*.xsl) xslt_maker "$inpfile";;
*.xhtml) copy_maker "$inpfile" "$output/source/$(dirname "$filepath")";;
*) copy_maker "$inpfile" "$output/$(dirname "$filepath")";;
esac
done

find "$input" -type f -and -name '*.[a-z][a-z].xhtml' \
| sed -r "/(^|\/)\.svn($|\/)|^\.\.$/d;s;^$input/*(.+)\.[a-z]{2}\.xhtml$;\1;" \
| sort -u \
| while read shortpath; do
xhtml_maker "${input}/$shortpath" "$output/$(dirname "$shortpath")"
done
}

logstatus(){
# pipeline atom to write data streams into a log file
# log file will be created inside statusdir
# if statusdir is not enabled, we won't log to a file
file="$1"

if [ -w "$statusdir" ]; then
tee "$statusdir/$file"
else
cat
fi
}

print_error(){
echo "Error: $*" |logstatus lasterror >/dev/stderr
echo "Run '$0 --help' to see usage instructions" >/dev/stderr
}

build_manifest(){
# pass Makefile throug on pipe and generate
# list of all make tagets

outfile="$1"
while line="$(line)"; do
echo "$line"
echo "$line" \
| sed -nr 's;/\./;/;g;s;\\ ; ;g;s;([^:]+) :.*;\1;p' \
>> "$outfile"
done
}

remove_orphans(){
# read list of files which should be in a directory tree
# and remove everything else

tree="$1"

# idea behind the algorithm:
# `find` will list every existing file once
# the manifest of all make targets will list all wanted files once
# concatenate all lines from manifest and `find`
# every file which is listed twice is wanted and exists,
# we use 'uniq -u' to drop those from the list
# remaining single files exist only in the tree and are to be removed

(find "$tree" -type f -or -type l; cat) \
| sort \
| uniq -u \
| while read file; do
match "$file" "^$tree" && rm -v "$file"
done
}

build_into(){
ncpu="$(cat /proc/cpuinfo |grep ^processor |wc -l)"

[ -w "$statusdir" -a -d "$statusdir" ] && \
manifest="$(tempfile -d "$statusdir" -p mnfst)" \
|| manifest="$(tempfile -p w3bld)"

make -C "$basedir" \
| logstatus premake

dir_maker "$basedir" "$target"
tree_maker "$basedir" "$target" \
| logstatus Makefile \
| build_manifest "$manifest" \
| make -j $ncpu -f - \
| logstatus buildlog

remove_orphans "$target" <"$manifest" \
| logstatus removed

[ -w "$statusdir" -a -d "$statusdir" ] && \
mv "$manifest" "$statusdir/manifest" \
||rm "$manifest"
}

basedir="$(dirname $0)/.."
domain="www.fsfe.org"

while [ -n "$*" ]; do
case "$1" in
-s|--statusdir|--status-dir)
[ -n "$*" ] && shift 1 && statusdir="$1"
;;
--domain)
[ -n "$*" ] && shift 1 && domain="$1"
;;
--source)
[ -n "$*" ] && shift 1 && basedir="$1"
;;
-d|--dest|--destination)
[ -n "$*" ] && shift 1 && target="$1"
;;
-h|--help)
command="help"
;;
build_into)
command="$1$command"
[ -n "$*" ] && shift 1 && target="$1"
;;
build_xmlstream)
command="$1$command"
[ -n "$*" ] && shift 1 && workfile="$1"
[ -n "$*" ] && shift 1 && olang="$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"
[ -n "$*" ] && shift 1 && workfile="$1"
[ -n "$*" ] && shift 1 && processor="$1"
[ -n "$*" ] && shift 1 && olang="$1"
;;
sourceglobs)
command="$1$command"
[ -n "$*" ] && shift 1 && sourcesfile="$1"
;;
cast_globfile)
command="$1$command"
[ -n "$*" ] && shift 1 && sourceglobfile="$1"
[ -n "$*" ] && shift 1 && lang="$1"
[ -n "$*" ] && shift 1 && globfile="$1"
;;
*)
print_error "Unknown option $1"
exit 1
;;
esac
[ -n "$*" ] && shift 1
done

if [ -n "$statusdir" ]; then
mkdir -p "$statusdir"
if [ ! -w "$statusdir" -o ! -d "$statusdir" ]; then
print_error "Unable to set up status directory in \"$statusdir\",
either select a status directory that exists and is writable,
or run the build script without output to a status directory"
exit 1
fi
fi

case "$command" in
build_into)
[ -z "$target" ] && print_error "Missing destination directory" && exit 1
build_into
;;
process_file)
[ -z "$workfile" ] && print_error "Need at least input file" && exit 1
process_file "$workfile" "$processor" "$olang"
;;
build_xmlstream)
[ -z "$workfile" ] && print_error "Missing xhtml file name" && exit 1
build_xmlstream "$(get_shortname "$workfile")" "$(get_language "$workfile")" "$olang"
;;
tree_maker)
[ -z "$tree" ] && tree="$basedir"
[ -z "$target" ] && print_error "Missing target location" && exit 1
tree_maker "$tree" "$target"
;;
sourceglobs)
[ -z "$sourcesfile" ] && print_error "Missing .sources file" && exit 1
sourceglobs "$sourcesfile"
;;
cast_globfile)
[ -z "$sourceglobfile" -o -z "$lang" -o -z "$globfile" ] && print_error "Need source globfile language and globfile" && exit 1
cast_globfile "$sourceglobfile" "$lang" "$globfile"
;;
*help*)
print_help
;;
*)
print_error "Urecognised command or no command given"
;;
esac

Loading…
Cancel
Save