diff --git a/builder.py b/builder.py index a9a00be..1bc9c2e 100644 --- a/builder.py +++ b/builder.py @@ -71,8 +71,13 @@ class BuildJob: def __init__(self, t, sf, lock, shouldbuildfunc, donefunc): self.t = t # original target name, not relative to vars.BASE self.sf = sf - self.tmpname1 = '%s.redo1.tmp' % t - self.tmpname2 = '%s.redo2.tmp' % t + tmpbase = t + while not os.path.isdir(os.path.dirname(tmpbase) or '.'): + ofs = tmpbase.rfind('/') + assert(ofs >= 0) + tmpbase = tmpbase[:ofs] + '__' + tmpbase[ofs+1:] + self.tmpname1 = '%s.redo1.tmp' % tmpbase + self.tmpname2 = '%s.redo2.tmp' % tmpbase self.lock = lock self.shouldbuildfunc = shouldbuildfunc self.donefunc = donefunc @@ -141,7 +146,8 @@ class BuildJob: dofile, basename, # target name (no extension) ext, # extension (if any), including leading dot - os.path.join(basedir, os.path.basename(self.tmpname2)) # temp output file name + # temp output file name + state.relpath(os.path.abspath(self.tmpname2), dodir), ] if vars.VERBOSE: argv[1] += 'v' if vars.XTRACE: argv[1] += 'x' diff --git a/clean.do b/clean.do index 16df2c3..fa794a7 100644 --- a/clean.do +++ b/clean.do @@ -1,7 +1,7 @@ rm -rf t/.redo redo-sh if [ -e .do_built ]; then while read x; do - rm -f "$x" + [ -d "$x" ] || rm -f "$x" done <.do_built fi [ -z "$DO_BUILT" ] && rm -rf .do_built .do_built.dir diff --git a/minimal/do b/minimal/do index fa209e5..f08e002 100755 --- a/minimal/do +++ b/minimal/do @@ -24,6 +24,13 @@ _dirsplit() dir=${1%$base} } +dirname() +( + _dirsplit "$1" + dir=${dir%/} + echo "${dir:-.}" +) + _dirsplit "$0" export REDO=$(cd "${dir:-.}" && echo "$PWD/$base") @@ -73,6 +80,7 @@ _find_dofile() [ -e "$dofile" ] && break [ "$PWD" = "/" ] && break target=${PWD##*/}/$target + tmp=${PWD##*/}/$tmp prefix=${PWD##*/}/$prefix cd .. done @@ -89,17 +97,17 @@ _run_dofile() read line1 <"$PWD/$dofile" cmd=${line1#"#!/"} if [ "$cmd" != "$line1" ]; then - /$cmd "$PWD/$dofile" "$@" >"$target.tmp2" + /$cmd "$PWD/$dofile" "$@" >"$tmp.tmp2" else - :; . "$PWD/$dofile" >"$target.tmp2" + :; . "$PWD/$dofile" >"$tmp.tmp2" fi } _do() { - local dir=$1 target=$2 - if [ ! -e "$target" ] || [ -d "$target/." -a ! -e "$target.did" ]; then + local dir=$1 target=$2 tmp=$3 + 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" @@ -111,30 +119,47 @@ _do() echo "do: $target: no .do file" >&2 return 1 fi - [ ! -e "$DO_BUILT" ] || : >>"$target.did" - ( _run_dofile "$base" "$ext" "$target.tmp" ) + [ ! -e "$DO_BUILT" ] || [ ! -d "$(dirname "$target")" ] || + : >>"$target.did" + ( _run_dofile "$base" "$ext" "$tmp.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" + rm -f "$tmp.tmp" "$tmp.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" + mv "$tmp.tmp" "$target" 2>/dev/null || + ! test -s "$tmp.tmp2" || + mv "$tmp.tmp2" "$target" 2>/dev/null + rm -f "$tmp.tmp2" else echo "do $DO_DEPTH$target exists." >&2 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() { for i in "$@"; do _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 }