It actually decreases readability of the .do files - by not making it explicit when you're going into a subdir. Plus it adds ambiguity: what if there's a dirname.do *and* a dirname/all? We could resolve the ambiguity if we wanted, but that adds more code, while taking out this special case makes *less* code and improves readability. I think it's the right way to go.
90 lines
1.6 KiB
Bash
Executable file
90 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" "got exit code $RV" >&2
|
|
exit $RV
|
|
fi
|
|
else
|
|
echo "do $DO_DEPTH$TARGET exists." >&2
|
|
fi
|
|
}
|
|
|
|
|
|
redo()
|
|
{
|
|
for i in "$@"; do
|
|
_dirsplit "$i"
|
|
( cd "$dir" && _do "$dir" "$base" ) || exit $?
|
|
done
|
|
}
|
|
|
|
|
|
alias redo-ifchange="redo"
|
|
alias redo-ifcreate=":"
|
|
set -e
|
|
|
|
if [ -n "$*" ]; then
|
|
redo "$@"
|
|
else
|
|
redo all
|
|
fi
|