apenwarr-redo/minimal/do
Avery Pennarun 80fedc84fe minimal/do: make redo-ifchange (etc) into subprograms in a temp dir.
Using aliases for them was cute, but it didn't work with things like:

	find -name '*.c' | xargs redo-ifchange

since xargs doesn't know about aliases.
2010-12-11 21:47:55 -08:00

99 lines
1.9 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
#
export REDO="$(cd "$(dirname "$0")" && echo "$PWD/$(basename "$0")")"
if [ -z "$DO_BUILT" ]; then
export DO_BUILT="$PWD/.do_built"
if [ -e "$DO_BUILT" ]; then
echo "Removing previously built files..." >&2
sort -u "$DO_BUILT" | tee "$DO_BUILT.new" |
while read f; do rm -f "$f"; done
mv "$DO_BUILT.new" "$DO_BUILT"
fi
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
for d in redo-ifcreate redo-stamp redo-always; do
ln -s /bin/true "$DO_PATH/$d";
done
fi
_dirsplit()
{
OLDIFS="$IFS"
IFS=/
set -- $1
IFS="$OLDIFS"
dir=""
while [ $# -gt 1 ]; do
dir="$dir$1/"
shift
done
base="$1"
}
_do()
{
DIR="$1"
TARGET="$2"
if [ ! -e "$TARGET" ]; then
printf '\033[32mdo %s\033[1m%s\033[m\n' \
"$DO_DEPTH" "$DIR$TARGET" >&2
echo "$PWD/$TARGET" >>"$DO_BUILT"
dof=".$TARGET"
DOFILE="$TARGET.do"
BASE="$TARGET"
EXT=""
while [ ! -e "$DOFILE" ]; do
dof2=$(echo "$dof" | sed 's/\.[^\.]*//')
[ "$dof" = "$dof2" ] && break
dof="$dof2"
DOFILE="default$dof.do"
BASE="$(basename "$TARGET" "$dof")"
EXT="$dof"
done
set "$BASE" "$EXT" "$TARGET.tmp"
RV=
(
export DO_DEPTH="$DO_DEPTH "
export REDO_TARGET="$PWD/$TARGET"
set -e
. "$PWD/$DOFILE" >"$TARGET.tmp"
) || RV="$?"
[ -z "$RV" ] && mv "$TARGET.tmp" "$TARGET" 2>/dev/null
: >>"$TARGET"
if [ -n "$RV" ]; then
printf "do: %s%s\n" "$DO_DEPTH" \
"$DIR$TARGET: got exit code $RV" >&2
return $RV
fi
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
if [ -n "$*" ]; then
redo "$@"
else
redo all
fi