redo-whichdo: updated output format.

The new format is just a list of .do files we tried, with a newline
after each one.  If we successfully found a .do file, we exit 0, else
we exit 1.

As discussed on the redo-list mailing list, it's easier to parse
without the extra cruft.  This makes users figure out $1 and $2
themselves, but that's not very hard, and maybe for the best.
This commit is contained in:
Avery Pennarun 2018-10-30 23:21:37 -04:00
commit f835becde4
2 changed files with 54 additions and 63 deletions

View file

@ -20,25 +20,14 @@ directory tree until a match is found.
To help debugging your scripts when redo is using an unexpected .do file, or To help debugging your scripts when redo is using an unexpected .do file, or
to write advanced scripts that "proxy" from one .do file to another, you to write advanced scripts that "proxy" from one .do file to another, you
can use `redo-whichdo` to see the exact search path that `redo` uses, can use `redo-whichdo` to see the exact search path that `redo` uses.
and the arguments it would use to run the .do file once found.
The output format contains lines in exactly the following order, which is The output format lists potential .do files, one per line, in order of
intended to be easy to parse in `sh`(1) scripts: preference, separated by newline characters, and stopping once a
matching .do file has been found. If the return code is zero,
the last line is a .do file that actually exists; otherwise the entire
search path has been exhausted (and printed).
- Zero or more lines starting with "-", indicating .do files that were
checked, but did not exist. If one of these files is created, the .do
script for your target would change. You might
want to call `redo-ifcreate`(1) for each of these files.
- Exactly one line starting with "+", indicating the .do file that was the
closest match.
- Exactly one line starting with "1", indicating the first argument to the
matching .do file.
- Exactly one line starting with "2", indicating the second argument to the
matching .do file.
# EXAMPLE # EXAMPLE
@ -46,49 +35,56 @@ Here's a typical search path for a source file (`x/y/a.b.o`). Because the
filename contains two dots (.), at each level of the hierarchy, `redo` needs filename contains two dots (.), at each level of the hierarchy, `redo` needs
to search `default.b.o.do`, `default.o.do`, and `default.do`. to search `default.b.o.do`, `default.o.do`, and `default.do`.
$ redo-whichdo x/y/a.b.o $ redo-whichdo x/y/a.b.o; echo $?
- x/y/a.b.o.do x/y/a.b.o.do
- x/y/default.b.o.do x/y/default.b.o.do
- x/y/default.o.do x/y/default.o.do
- x/y/default.do x/y/default.do
- x/default.b.o.do x/default.b.o.do
- x/default.o.do x/default.o.do
- x/default.do x/default.do
- default.b.o.do default.b.o.do
+ default.o.do default.o.do
1 x/y/a.b.o 0
2 x/y/a.b
You might use `redo-whichdo` to delegate from one .do script to another, You might use `redo-whichdo` to delegate from one .do script to another,
using code like this: using code like the following. This gets a little tricky because not only
are you finding a new .do file, but you have `cd` to the .do file
directory and adjust `$1` and `$2` appropriately.
out=$3 ofile=$PWD/$3
redo-whichdo "$SRCDIR/$1" | { x1=$1
x1= x2= dofile= cd "$SRCDIR"
redo-whichdo "$x1" | {
ifcreate= ifcreate=
while read a b; do while read dopath; do
case $a in if [ ! -e "$dopath" ]; then
-) ifcreate="$ifcreate $dopath"
ifcreate="$ifcreate $b" else
;; redo-ifcreate $ifcreate
+) redo-ifchange "$dopath"
redo-ifcreate $ifcreate &&
redo-ifchange "$b" || exit dofile=${dopath##*/}
dopath="$b" dodir=${dopath%$dofile}
dodir=$(dirname "$dopath")
dofile=$(basename "$dopath") # Create updated $1 and $2 for the new .do file
;; x1_rel=${x1#$dodir}
1) ext=${dofile##*default}
x1="$b" if [ "$ext" != "$dofile" ]; then
;; ext=${ext%.do}
2) else
x2="$b" ext=''
out="$PWD/$3" fi
cd "$dodir" && . "./$dofile" "$x1" "$x2" "$out" x2_rel=${x1#$dodir}
x2_rel=${x2_rel%$ext}
cd "$dodir"
set -- "$x1_rel" "$x2_rel" "$ofile"
. "./$dofile"
exit exit
;; fi
esac
done done
exit 3 exit 3
} }

View file

@ -12,18 +12,13 @@ if len(sys.argv[1:]) != 1:
sys.exit(1) sys.exit(1)
want = sys.argv[1] want = sys.argv[1]
for dodir,dofile,basedir,basename,ext in builder.possible_do_files(os.path.abspath(want)): abswant = os.path.abspath(want)
for dodir,dofile,basedir,basename,ext in builder.possible_do_files(abswant):
dopath = os.path.join('/', dodir, dofile) dopath = os.path.join('/', dodir, dofile)
relpath = os.path.relpath(dopath, '.') relpath = os.path.relpath(dopath, '.')
exists = os.path.exists(dopath) exists = os.path.exists(dopath)
assert('\n' not in relpath) assert('\n' not in relpath)
print relpath
if exists: if exists:
print '+', relpath sys.exit(0)
assert('\n' not in basename)
assert('\n' not in ext)
print '1', basename+ext
print '2', basename
sys.exit(0)
else:
print '-', relpath
sys.exit(1) # no appropriate dofile found sys.exit(1) # no appropriate dofile found