Print a better message when detecting pre-existing cyclic dependencies.

We already printed an error at build time, but added the broken
dependency anyway.  If the .do script decided to succeed despite
redo-ifchange aborting, the target would be successfully created
and we'd end up with an infinite loop when running isdirty() later.

The result was still "correct", because python helpfully aborted
the infinite loop after the recursion got too deep.  But let's
explicitly detect it and print a better error message.

(Thanks to Nils Dagsson Moskopp's redo-testcases repo for exposing this
problem.  If you put a #!/bin/sh header on your .do script means you
need to run 'set -e' yourself if you want .do scripts to abort after an
error, which you almost always do, and those testcases don't, which
exposed this bug if you ran the tests twice.)
This commit is contained in:
Avery Pennarun 2018-10-30 23:03:46 -04:00
commit 711b05766f
5 changed files with 17 additions and 3 deletions

View file

@ -6,8 +6,15 @@ CLEAN = 0
DIRTY = 1
def isdirty(f, depth, max_changed,
already_checked,
is_checked=state.File.is_checked,
set_checked=state.File.set_checked_save):
if f.id in already_checked:
raise state.CyclicDependencyError()
# make a copy of the list, so upon returning, our parent's copy
# is unaffected
already_checked = list(already_checked) + [f.id]
if vars.DEBUG >= 1:
debug('%s?%s\n' % (depth, f.nicename()))
@ -50,6 +57,7 @@ def isdirty(f, depth, max_changed,
sub = isdirty(f2, depth = depth + ' ',
max_changed = max(f.changed_runid,
f.checked_runid),
already_checked=already_checked,
is_checked=is_checked, set_checked=set_checked)
if sub:
debug('%s-- DIRTY (sub)\n' % depth)