apenwarr-redo/minimal/do
Avery Pennarun a75555e7a8 minimal/do: don't completely abort if a sub-redo fails.
Just allow that sub-redo to return an error code.  Also, parent redos should
return error code 1, not the same code as the child.  That makes it easier
to figure out which file generated the "special" error code.
2010-12-11 20:37:27 -08:00

91 lines
1.6 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="$(dirname "$0")/$(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 "$DO_BUILT" | uniq | tee "$DO_BUILT.new" |
while read f; do rm -f "$f"; done
mv "$DO_BUILT.new" "$DO_BUILT"
fi
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 "
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
}
alias redo-ifchange="redo"
alias redo-ifcreate=":"
set -e
if [ -n "$*" ]; then
redo "$@"
else
redo all
fi