From 0fc2e4670888495b720512bb5b072265f6352578 Mon Sep 17 00:00:00 2001 From: Avery Pennarun Date: Wed, 17 Oct 2018 02:57:33 -0400 Subject: [PATCH] minimal/do: add support for -x -v -d -c options. -x, -v, and -d are the same as redo. -c means "continuable", which disables the feature that deletes (and forgets) all targets at the start of each run. This is a little risky, since minimal/do still doesn't understand dependencies, but it allows you to run minimal/do several times in succession, so that minimal/do -c a minimal/do -c b is the same as minimal/do a b --- README.md | 2 +- minimal/do | 60 +++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index b54c80b..c250d92 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ If you've ever thought about rewriting GNU make from scratch, the idea of doing it in 250 lines of shell script probably didn't occur to you. redo is so simple that it's actually possible. For testing, I actually wrote an even more minimal version, which always rebuilds everything instead of -checking dependencies, in 150 lines of shell (about 3 kbytes). +checking dependencies, in 210 lines of shell (about 4 kbytes). The design is simply that good. diff --git a/minimal/do b/minimal/do index b64734e..88f333a 100755 --- a/minimal/do +++ b/minimal/do @@ -36,30 +36,56 @@ export REDO=$(cd "${dir:-.}" && echo "$PWD/$base") if [ "$base" = "redo-ifchange" ]; then ifchange=1; else ifchange=; fi DO_TOP= +if [ -z "$DO_BUILT" ]; then + export _do_opt_debug= + export _do_opt_exec= + export _do_opt_verbose= + export _do_opt_continuable= +fi +while getopts dxvc _opt; do + case $_opt in + d) _do_opt_debug=1 ;; + x) _do_opt_exec=x ;; + v) _do_opt_verbose=v ;; + c) _do_opt_continuable=1 ;; + *) printf "\nusage: $0 [-d] [-x] [-v] [-c] \n" >&2 + exit 99 + ;; + esac +done +shift "$((OPTIND - 1))" +_debug() { + [ -z "$_do_opt_debug" ] || echo "$@" >&2 +} + if [ -z "$DO_BUILT" ]; then DO_TOP=1 - [ -n "$*" ] || set all # only toplevel redo has a default target + [ "$#" -gt 0 ] || set all # only toplevel redo has a default target export DO_BUILT=$PWD/.do_built : >>"$DO_BUILT" - echo "Removing previously built files..." >&2 - sort -u "$DO_BUILT" | tee "$DO_BUILT.new" | - while read f; do printf "%s\0%s.did\0" "$f" "$f"; done | - xargs -0 rm -f 2>/dev/null + sort -u "$DO_BUILT" >"$DO_BUILT.new" + if [ -z "$_do_opt_continuable" ]; then + echo "Removing previously built files..." >&2 + while read f; do printf "%s\0%s.did\0" "$f" "$f"; done <"$DO_BUILT.new" | + xargs -0 rm -f 2>/dev/null + fi mv "$DO_BUILT.new" "$DO_BUILT" 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"; + ln -s "$REDO" "$DO_PATH/$d" done [ -e /bin/true ] && TRUE=/bin/true || TRUE=/usr/bin/true for d in redo-ifcreate redo-stamp redo-always; do - ln -s $TRUE "$DO_PATH/$d"; + ln -s $TRUE "$DO_PATH/$d" done fi + + _find_dofile_pwd() { dofile=default.$1.do @@ -98,8 +124,10 @@ _run_dofile() read line1 <"$PWD/$dofile" || true cmd=${line1#"#!/"} if [ "$cmd" != "$line1" ]; then + set -$_do_opt_verbose$_do_opt_exec /$cmd "$PWD/$dofile" "$@" >"$tmp.tmp2" else + set -$_do_opt_verbose$_do_opt_exec :; . "$PWD/$dofile" >"$tmp.tmp2" fi } @@ -108,7 +136,9 @@ _run_dofile() _do() { local dir="$1" target="$2" tmp="$3" - if [ -z "$ifchange" ] || ( [ ! -e "$target" -o -d "$target" ] && [ ! -e "$target.did" ] ); then + if [ -z "$ifchange" ] || + ( [ ! -e "$target" -o -d "$target" ] && + [ ! -e "$target.did" ] ); then printf '%sdo %s%s%s%s\n' \ "$green" "$DO_DEPTH" "$bold" "$dir$target" "$plain" >&2 echo "$PWD/$target" >>"$DO_BUILT" @@ -135,7 +165,7 @@ _do() mv "$tmp.tmp2" "$target" 2>/dev/null rm -f "$tmp.tmp2" else - echo "do $DO_DEPTH$target exists." >&2 + _debug "do $DO_DEPTH$target exists." >&2 fi } @@ -149,7 +179,7 @@ _dir_shovel() _dirsplit "${xdir%/}" xbasetmp=${base}__$xbase xdir=$dir xbase=$base/$xbase - echo "xbasetmp='$xbasetmp'" >&2 + _debug "xbasetmp='$xbasetmp'" >&2 done } @@ -171,8 +201,10 @@ _redo "$@" [ "$?" = 0 ] || exit 1 if [ -n "$DO_TOP" ]; then - echo "Removing stamp files..." >&2 - [ ! -e "$DO_BUILT" ] || - while read f; do printf "%s.did\0" "$f"; done <"$DO_BUILT" | - xargs -0 rm -f 2>/dev/null + if [ -z "$_do_opt_continuable" ]; then + echo "Removing stamp files..." >&2 + [ ! -e "$DO_BUILT" ] || + while read f; do printf "%s.did\0" "$f"; done <"$DO_BUILT" | + xargs -0 rm -f 2>/dev/null + fi fi