diff --git a/clean.do b/clean.do index ed3fc5e..0ae01b6 100644 --- a/clean.do +++ b/clean.do @@ -10,3 +10,4 @@ rm -rf minimal/.do_built minimal/.do_built.dir website redo t/clean Documentation/clean version/clean rm -f *~ .*~ */*~ */.*~ *.pyc install.wrapper find . -name '*.tmp' -exec rm -fv {} \; +find . -name '*.did' -exec rm -fv {} \; diff --git a/deps.py b/deps.py index d2ac6a2..e803870 100644 --- a/deps.py +++ b/deps.py @@ -39,6 +39,17 @@ def isdirty(f, depth, max_changed, if f.stamp != newstamp: if newstamp == state.STAMP_MISSING: debug('%s-- DIRTY (missing)\n' % depth) + if f.stamp and f.is_generated: + # previously was stamped and generated, but suddenly missing. + # We can safely forget that it is/was a target; if someone + # does redo-ifchange on it and it doesn't exist, we'll mark + # it a target again, but if someone creates it by hand, + # it'll be a source. This should reduce false alarms when + # files change from targets to sources as a project evolves. + debug('%s converted target -> source\n' % depth) + f.is_generated = False + #f.update_stamp() + f.save() else: debug('%s-- DIRTY (mtime)\n' % depth) if f.csum: @@ -103,5 +114,3 @@ def isdirty(f, depth, max_changed, state.warn_override(f.name) set_checked(f) return CLEAN - - diff --git a/redo-ood.py b/redo-ood.py index d1ef5ae..be0016f 100755 --- a/redo-ood.py +++ b/redo-ood.py @@ -21,9 +21,10 @@ def set_checked(f): cache[f.id] = 1 +cwd = os.getcwd() for f in state.files(): if f.is_generated and f.read_stamp() != state.STAMP_MISSING: if deps.isdirty(f, depth='', max_changed=vars.RUNID, already_checked=[], is_checked=is_checked, set_checked=set_checked): - print f.nicename() + print state.relpath(os.path.join(vars.BASE, f.name), cwd) diff --git a/redo-sources.py b/redo-sources.py index 579145d..2e19684 100755 --- a/redo-sources.py +++ b/redo-sources.py @@ -4,15 +4,16 @@ import sys, os import vars_init vars_init.init([]) -import state +import state, vars from logs import err if len(sys.argv[1:]) != 0: err('%s: no arguments expected.\n' % sys.argv[0]) sys.exit(1) +cwd = os.getcwd() for f in state.files(): if f.name.startswith('//'): continue # special name, ignore if not f.is_generated and f.read_stamp() != state.STAMP_MISSING: - print f.nicename() + print state.relpath(os.path.join(vars.BASE, f.name), cwd) diff --git a/redo-targets.py b/redo-targets.py index cfed75d..95ef5c9 100755 --- a/redo-targets.py +++ b/redo-targets.py @@ -4,13 +4,14 @@ import sys, os import vars_init vars_init.init([]) -import state +import state, vars from logs import err if len(sys.argv[1:]) != 0: err('%s: no arguments expected.\n' % sys.argv[0]) sys.exit(1) +cwd = os.getcwd() for f in state.files(): if f.is_generated and f.read_stamp() != state.STAMP_MISSING: - print f.nicename() + print state.relpath(os.path.join(vars.BASE, f.name), cwd) diff --git a/t/102-empty/clean.do b/t/102-empty/clean.do index 799f5f4..ec65690 100644 --- a/t/102-empty/clean.do +++ b/t/102-empty/clean.do @@ -1 +1 @@ -rm -f touch1 touch1-ran *~ .*~ +rm -f touch1 touch1-ran *~ .*~ silence.do diff --git a/t/351-deps-forget/.gitignore b/t/351-deps-forget/.gitignore new file mode 100644 index 0000000..d51b82d --- /dev/null +++ b/t/351-deps-forget/.gitignore @@ -0,0 +1,6 @@ +bork +bork.do +bork.log +sub +sub.log +targets.out diff --git a/t/351-deps-forget/all.do b/t/351-deps-forget/all.do new file mode 100644 index 0000000..a799cec --- /dev/null +++ b/t/351-deps-forget/all.do @@ -0,0 +1,55 @@ +exec >&2 +rm -f bork.do bork bork.log sub sub.log targets.out + +qgrep() { + # like "grep -q", but portable + grep "$@" >/dev/null +} + +cp bork.do.in bork.do +redo bork +[ "$(cat bork.log)" = "x" ] || exit 2 +redo bork +[ "$(cat bork.log)" = "xx" ] || exit 3 + +redo-ifchange sub +[ "$(cat bork.log)" = "xx" ] || exit 10 +[ "$(cat sub.log)" = "y" ] || exit 11 +. ../skip-if-minimal-do.sh +redo-sources | qgrep '^bork$' && exit 12 +redo-targets | tee targets.out | qgrep '^bork$' || exit 13 + +# Might as well test redo-ood while we're here +../flush-cache +redo bork +redo-targets | qgrep '^bork$' || exit 15 +redo-targets | qgrep '^sub$' || exit 16 +redo-ood | qgrep '^sub$' || exit 17 + +redo-ifchange sub +[ "$(cat bork.log)" = "xxx" ] || exit 18 +[ "$(cat sub.log)" = "yy" ] || exit 19 + +rm -f bork +../flush-cache +redo-ifchange sub # rebuilds, and sub.do drops dependency on bork +[ "$(cat bork.log)" = "xxx" ] || exit 20 +[ "$(cat sub.log)" = "yyy" ] || exit 21 +redo-sources | qgrep '^bork$' && exit 22 # nonexistent, so not a source +redo-targets | qgrep '^bork$' && exit 23 # deleted; not a target anymore + +echo static >bork +../flush-cache +redo-ifchange sub # doesn't depend on bork anymore, so doesn't rebuild +[ "$(cat bork.log)" = "xxx" ] || exit 30 +[ "$(cat sub.log)" = "yyy" ] || exit 31 + +# bork should now be considered static, so no warning or need to rebuild. +# It should now be considered a source, not a target. +redo sub # force rebuild; sub.do now declares dependency on bork +[ "$(cat bork.log)" = "xxx" ] || exit 40 +[ "$(cat sub.log)" = "yyyy" ] || exit 41 +redo-sources | qgrep '^bork$' || exit 42 +redo-targets | qgrep '^bork$' && exit 43 + +exit 0 diff --git a/t/351-deps-forget/bork.do.in b/t/351-deps-forget/bork.do.in new file mode 100644 index 0000000..29d4871 --- /dev/null +++ b/t/351-deps-forget/bork.do.in @@ -0,0 +1,2 @@ +echo bork +printf x >>$1.log diff --git a/t/351-deps-forget/clean.do b/t/351-deps-forget/clean.do new file mode 100644 index 0000000..5caef9d --- /dev/null +++ b/t/351-deps-forget/clean.do @@ -0,0 +1,2 @@ +rm -f *~ .*~ bork bork.do bork.log sub sub.log targets.out + diff --git a/t/351-deps-forget/sub.do b/t/351-deps-forget/sub.do new file mode 100644 index 0000000..5747903 --- /dev/null +++ b/t/351-deps-forget/sub.do @@ -0,0 +1,3 @@ +[ -e bork ] && redo-ifchange bork +echo sub +printf y >>$1.log