./do: use the latest minimal/do from the redo project.

This commit is contained in:
Avery Pennarun 2011-05-03 14:19:45 -07:00
parent c13be0b817
commit 57e744dadd

115
do
View File

@ -8,14 +8,14 @@
# #
# By default, no output coloring. # By default, no output coloring.
GREEN="" green=""
BOLD="" bold=""
PLAIN="" plain=""
if [ -n "$TERM" -a "$TERM" != "dumb" ] && tty <&2 >/dev/null 2>&1; then if [ -n "$TERM" -a "$TERM" != "dumb" ] && tty <&2 >/dev/null 2>&1; then
GREEN="$(printf '\033[32m')" green="$(printf '\033[32m')"
BOLD="$(printf '\033[1m')" bold="$(printf '\033[1m')"
PLAIN="$(printf '\033[m')" plain="$(printf '\033[m')"
fi fi
_dirsplit() _dirsplit()
@ -24,6 +24,13 @@ _dirsplit()
dir=${1%$base} dir=${1%$base}
} }
dirname()
(
_dirsplit "$1"
dir=${dir%/}
echo "${dir:-.}"
)
_dirsplit "$0" _dirsplit "$0"
export REDO=$(cd "${dir:-.}" && echo "$PWD/$base") export REDO=$(cd "${dir:-.}" && echo "$PWD/$base")
@ -54,87 +61,105 @@ fi
_find_dofile_pwd() _find_dofile_pwd()
{ {
DOFILE=default.$1.do dofile=default.$1.do
while :; do while :; do
DOFILE=default.${DOFILE#default.*.} dofile=default.${dofile#default.*.}
[ -e "$DOFILE" -o "$DOFILE" = default.do ] && break [ -e "$dofile" -o "$dofile" = default.do ] && break
done done
EXT=${DOFILE#default} ext=${dofile#default}
EXT=${EXT%.do} ext=${ext%.do}
BASE=${1%$EXT} base=${1%$ext}
} }
_find_dofile() _find_dofile()
{ {
PREFIX= local prefix=
while :; do while :; do
_find_dofile_pwd "$1" _find_dofile_pwd "$1"
[ -e "$DOFILE" ] && break [ -e "$dofile" ] && break
[ "$PWD" = "/" ] && break [ "$PWD" = "/" ] && break
TARGET=${PWD##*/}/$TARGET target=${PWD##*/}/$target
PREFIX=${PWD##*/}/$PREFIX tmp=${PWD##*/}/$tmp
prefix=${PWD##*/}/$prefix
cd .. cd ..
done done
BASE=$PREFIX$BASE base=$prefix$base
} }
_run_dofile() _run_dofile()
{ {
export DO_DEPTH="$DO_DEPTH " export DO_DEPTH="$DO_DEPTH "
export REDO_TARGET=$PWD/$TARGET export REDO_TARGET=$PWD/$target
local line1
set -e set -e
read line1 <"$PWD/$DOFILE" read line1 <"$PWD/$dofile"
cmd=${line1#"#!/"} cmd=${line1#"#!/"}
if [ "$cmd" != "$line1" ]; then if [ "$cmd" != "$line1" ]; then
/$cmd "$PWD/$DOFILE" "$@" >"$TARGET.tmp2" /$cmd "$PWD/$dofile" "$@" >"$tmp.tmp2"
else else
. "$PWD/$DOFILE" >"$TARGET.tmp2" :; . "$PWD/$dofile" >"$tmp.tmp2"
fi fi
} }
_do() _do()
{ {
DIR=$1 local dir=$1 target=$2 tmp=$3
TARGET=$2 if [ ! -e "$target" ] || [ -d "$target" -a ! -e "$target.did" ]; then
if [ ! -e "$TARGET" ] || [ -e "$TARGET/." -a ! -e "$TARGET.did" ]; then
printf '%sdo %s%s%s%s\n' \ printf '%sdo %s%s%s%s\n' \
"$GREEN" "$DO_DEPTH" "$BOLD" "$DIR$TARGET" "$PLAIN" >&2 "$green" "$DO_DEPTH" "$bold" "$dir$target" "$plain" >&2
echo "$PWD/$TARGET" >>"$DO_BUILT" echo "$PWD/$target" >>"$DO_BUILT"
DOFILE=$TARGET.do dofile=$target.do
BASE=$TARGET base=$target
EXT= ext=
[ -e "$TARGET.do" ] || _find_dofile "$TARGET" [ -e "$target.do" ] || _find_dofile "$target"
if [ ! -e "$DOFILE" ]; then if [ ! -e "$dofile" ]; then
echo "do: $TARGET: no .do file" >&2 echo "do: $target: no .do file" >&2
return 1 return 1
fi fi
[ ! -e "$DO_BUILD" ] || : >>"$TARGET.did" [ ! -e "$DO_BUILT" ] || [ ! -d "$(dirname "$target")" ] ||
( _run_dofile "$BASE" "$EXT" "$TARGET.tmp" ) : >>"$target.did"
RV=$? ( _run_dofile "$base" "$ext" "$tmp.tmp" )
if [ $RV != 0 ]; then rv=$?
if [ $rv != 0 ]; then
printf "do: %s%s\n" "$DO_DEPTH" \ printf "do: %s%s\n" "$DO_DEPTH" \
"$DIR$TARGET: got exit code $RV" >&2 "$dir$target: got exit code $rv" >&2
rm -f "$TARGET.tmp" "$TARGET.tmp2" rm -f "$tmp.tmp" "$tmp.tmp2"
return $RV return $rv
fi fi
mv "$TARGET.tmp" "$TARGET" 2>/dev/null || mv "$tmp.tmp" "$target" 2>/dev/null ||
! test -s "$TARGET.tmp2" || ! test -s "$tmp.tmp2" ||
mv "$TARGET.tmp2" "$TARGET" 2>/dev/null mv "$tmp.tmp2" "$target" 2>/dev/null
rm -f "$TARGET.tmp2" rm -f "$tmp.tmp2"
else else
echo "do $DO_DEPTH$TARGET exists." >&2 echo "do $DO_DEPTH$target exists." >&2
fi fi
} }
# Make corrections for directories that don't actually exist yet.
_dir_shovel()
{
local dir base
xdir=$1 xbase=$2 xbasetmp=$2
while [ ! -d "$xdir" -a -n "$xdir" ]; do
_dirsplit "${xdir%/}"
xbasetmp=${base}__$xbase
xdir=$dir xbase=$base/$xbase
echo "xbasetmp='$xbasetmp'" >&2
done
}
redo() redo()
{ {
for i in "$@"; do for i in "$@"; do
_dirsplit "$i" _dirsplit "$i"
( cd "$dir" && _do "$dir" "$base" ) || return 1 _dir_shovel "$dir" "$base"
dir=$xdir base=$xbase basetmp=$xbasetmp
( cd "$dir" && _do "$dir" "$base" "$basetmp" ) || return 1
done done
} }