If redo searched all the way up to /default.do, it would run ./default.do instead.

This only happened if the containing project was buggy, ie. you tried
to build a target that has no .do file available anywhere. However, it
resulted in a confusing outcome for that case, where we'd run the wrong
default.do file with the wrong parameters.

Extended an existing test to catch this mistake.
This commit is contained in:
Avery Pennarun 2019-03-02 02:53:02 -05:00
commit e5a27f04e8
4 changed files with 18 additions and 4 deletions

View file

@ -183,6 +183,8 @@ class _BuildJob(object):
return self._finalize(0) return self._finalize(0)
else: else:
err('no rule to redo %r\n' % t) err('no rule to redo %r\n' % t)
sf.set_failed()
sf.save()
return self._finalize(1) return self._finalize(1)
# There is no good place for us to pre-create a temp file for # There is no good place for us to pre-create a temp file for
# stdout. The target dir might not exist yet, or it might currently # stdout. The target dir might not exist yet, or it might currently

View file

@ -32,7 +32,7 @@ def possible_do_files(t):
# since t is an absolute path, dirbits[0] is always '', so we don't # since t is an absolute path, dirbits[0] is always '', so we don't
# need to count all the way down to i=0. # need to count all the way down to i=0.
for i in range(len(dirbits), 0, -1): for i in range(len(dirbits), 0, -1):
basedir = '/'.join(dirbits[:i]) basedir = '/'.join(dirbits[:i]) or '/'
subdir = '/'.join(dirbits[i:]) subdir = '/'.join(dirbits[i:])
for dofile, basename, ext in _default_do_files(filename): for dofile, basename, ext in _default_do_files(filename):
yield (basedir, dofile, yield (basedir, dofile,

View file

@ -1,7 +1,6 @@
rm -f x/shouldfail rm -f x/shouldfail
log=$PWD/$1.log log=$PWD/$1.log
rm -f "$log"
expect_fail() { expect_fail() {
local rv=$1 local rv=$1
@ -15,8 +14,19 @@ expect_fail() {
fi fi
} }
# These should all fail because there is no matching .do file.
# In previous versions of redo, it would accidentally try to use
# $PWD/default.do even for ../path/file, which is incorrect. That
# could cause it to return success accidentally.
rm -f "$log"
cd inner cd inner
expect_fail 11 redo ../x/shouldfail # should fail expect_fail 11 redo ../x/shouldfail
expect_fail 12 redo-ifchange ../x/shouldfail # should fail again expect_fail 12 redo-ifchange ../x/shouldfail
rm -f "$log"
cd ../inner2
expect_fail 21 redo ../x/shouldfail2
expect_fail 22 redo-ifchange ../x/shouldfail2
exit 0 exit 0

View file

@ -0,0 +1,2 @@
echo "inner/default.do: PWD=$PWD '$1' '$2' '$3'" >&2
# output file is left empty