Since we use ". filename.do" to run the .do files instead of just "filename.do", shell local variables end up being inherited by the subprogram. Change all the local variables to be all lowercase, to avoid conflicting with any typical environment variables someone might use. The particular variable that triggered this was PREFIX (reported by "ulrik" on the mailing list) and that fixes this, at least. Arguably we shouldn't be using ".", but using it avoids unnecessary forks, which is kind of nice.
150 lines
3.1 KiB
Bash
Executable file
150 lines
3.1 KiB
Bash
Executable file
#!/bin/sh
|
|
#
|
|
# A minimal alternative to djb redo that doesn't support incremental builds.
|
|
# For the full version, visit http://github.com/apenwarr/redo
|
|
#
|
|
# The author disclaims copyright to this source file and hereby places it in
|
|
# the public domain. (2010 12 14)
|
|
#
|
|
|
|
# By default, no output coloring.
|
|
green=""
|
|
bold=""
|
|
plain=""
|
|
|
|
if [ -n "$TERM" -a "$TERM" != "dumb" ] && tty <&2 >/dev/null 2>&1; then
|
|
green="$(printf '\033[32m')"
|
|
bold="$(printf '\033[1m')"
|
|
plain="$(printf '\033[m')"
|
|
fi
|
|
|
|
_dirsplit()
|
|
{
|
|
base=${1##*/}
|
|
dir=${1%$base}
|
|
}
|
|
|
|
_dirsplit "$0"
|
|
export REDO=$(cd "${dir:-.}" && echo "$PWD/$base")
|
|
|
|
DO_TOP=
|
|
if [ -z "$DO_BUILT" ]; then
|
|
DO_TOP=1
|
|
[ -n "$*" ] || set all # only toplevel redo has a default target
|
|
export DO_BUILT=$PWD/.do_built
|
|
: >>"$DO_BUILT"
|
|
echo "Removing previously built files..." >&2
|
|
sort -u "$DO_BUILT" | tee "$DO_BUILT.new" |
|
|
while read f; do printf "%s\0%s.did\0" "$f" "$f"; done |
|
|
xargs -0 rm -f 2>/dev/null
|
|
mv "$DO_BUILT.new" "$DO_BUILT"
|
|
DO_PATH=$DO_BUILT.dir
|
|
export PATH=$DO_PATH:$PATH
|
|
rm -rf "$DO_PATH"
|
|
mkdir "$DO_PATH"
|
|
for d in redo redo-ifchange; do
|
|
ln -s "$REDO" "$DO_PATH/$d";
|
|
done
|
|
[ -e /bin/true ] && TRUE=/bin/true || TRUE=/usr/bin/true
|
|
for d in redo-ifcreate redo-stamp redo-always; do
|
|
ln -s $TRUE "$DO_PATH/$d";
|
|
done
|
|
fi
|
|
|
|
|
|
_find_dofile_pwd()
|
|
{
|
|
dofile=default.$1.do
|
|
while :; do
|
|
dofile=default.${dofile#default.*.}
|
|
[ -e "$dofile" -o "$dofile" = default.do ] && break
|
|
done
|
|
ext=${dofile#default}
|
|
ext=${ext%.do}
|
|
base=${1%$ext}
|
|
}
|
|
|
|
|
|
_find_dofile()
|
|
{
|
|
local prefix=
|
|
while :; do
|
|
_find_dofile_pwd "$1"
|
|
[ -e "$dofile" ] && break
|
|
[ "$PWD" = "/" ] && break
|
|
target=${PWD##*/}/$target
|
|
prefix=${PWD##*/}/$prefix
|
|
cd ..
|
|
done
|
|
base=$prefix$base
|
|
}
|
|
|
|
|
|
_run_dofile()
|
|
{
|
|
export DO_DEPTH="$DO_DEPTH "
|
|
export REDO_TARGET=$PWD/$target
|
|
local line1
|
|
set -e
|
|
read line1 <"$PWD/$dofile"
|
|
cmd=${line1#"#!/"}
|
|
if [ "$cmd" != "$line1" ]; then
|
|
/$cmd "$PWD/$dofile" "$@" >"$target.tmp2"
|
|
else
|
|
:; . "$PWD/$dofile" >"$target.tmp2"
|
|
fi
|
|
}
|
|
|
|
|
|
_do()
|
|
{
|
|
local dir=$1 target=$2
|
|
if [ ! -e "$target" ] || [ -d "$target/." -a ! -e "$target.did" ]; then
|
|
printf '%sdo %s%s%s%s\n' \
|
|
"$green" "$DO_DEPTH" "$bold" "$dir$target" "$plain" >&2
|
|
echo "$PWD/$target" >>"$DO_BUILT"
|
|
dofile=$target.do
|
|
base=$target
|
|
ext=
|
|
[ -e "$target.do" ] || _find_dofile "$target"
|
|
if [ ! -e "$dofile" ]; then
|
|
echo "do: $target: no .do file" >&2
|
|
return 1
|
|
fi
|
|
[ ! -e "$DO_BUILD" ] || : >>"$target.did"
|
|
( _run_dofile "$base" "$ext" "$target.tmp" )
|
|
rv=$?
|
|
if [ $rv != 0 ]; then
|
|
printf "do: %s%s\n" "$DO_DEPTH" \
|
|
"$dir$target: got exit code $rv" >&2
|
|
rm -f "$target.tmp" "$target.tmp2"
|
|
return $rv
|
|
fi
|
|
mv "$target.tmp" "$target" 2>/dev/null ||
|
|
! test -s "$target.tmp2" ||
|
|
mv "$target.tmp2" "$target" 2>/dev/null
|
|
rm -f "$target.tmp2"
|
|
else
|
|
echo "do $DO_DEPTH$target exists." >&2
|
|
fi
|
|
}
|
|
|
|
|
|
redo()
|
|
{
|
|
for i in "$@"; do
|
|
_dirsplit "$i"
|
|
( cd "$dir" && _do "$dir" "$base" ) || return 1
|
|
done
|
|
}
|
|
|
|
|
|
set -e
|
|
redo "$@"
|
|
|
|
if [ -n "$DO_TOP" ]; then
|
|
echo "Removing stamp files..." >&2
|
|
[ ! -e "$DO_BUILT" ] ||
|
|
while read f; do printf "%s.did\0" "$f"; done <"$DO_BUILT" |
|
|
xargs -0 rm -f 2>/dev/null
|
|
fi
|