Skip to content

Commit

Permalink
{ood,sources,targets}: fix relative paths; turn missing targets into …
Browse files Browse the repository at this point in the history
…sources.

When we check dependencies and a previously-is_generated dependency
existed before, but no longer does, forget that it was is_generated.
This slightly improves the situation where as a project evolves, a file
that used to be a target gets removed, and then later is re-added as a
static source file.  (It doesn't fix the other variant, where a file is
changed from target to source in a single atomic change, and is never
missing.  That one will be trickier to handle.)

While adding a test for this behaviour, I discovered that redo-sources,
redo-targets, and redo-ood were reporting their output relative to
STARTDIR instead of relative to $PWD, so fix that too.
  • Loading branch information
apenwarr committed Nov 24, 2018
1 parent 5596b9f commit c06d1fb
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 8 deletions.
1 change: 1 addition & 0 deletions clean.do
Expand Up @@ -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 {} \;
13 changes: 11 additions & 2 deletions deps.py
Expand Up @@ -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:
Expand Down Expand Up @@ -103,5 +114,3 @@ def isdirty(f, depth, max_changed,
state.warn_override(f.name)
set_checked(f)
return CLEAN


3 changes: 2 additions & 1 deletion redo-ood.py
Expand Up @@ -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)
5 changes: 3 additions & 2 deletions redo-sources.py
Expand Up @@ -4,15 +4,16 @@
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)
5 changes: 3 additions & 2 deletions redo-targets.py
Expand Up @@ -4,13 +4,14 @@
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)
2 changes: 1 addition & 1 deletion t/102-empty/clean.do
@@ -1 +1 @@
rm -f touch1 touch1-ran *~ .*~
rm -f touch1 touch1-ran *~ .*~ silence.do
6 changes: 6 additions & 0 deletions t/351-deps-forget/.gitignore
@@ -0,0 +1,6 @@
bork
bork.do
bork.log
sub
sub.log
targets.out
55 changes: 55 additions & 0 deletions 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
2 changes: 2 additions & 0 deletions t/351-deps-forget/bork.do.in
@@ -0,0 +1,2 @@
echo bork
printf x >>$1.log
2 changes: 2 additions & 0 deletions t/351-deps-forget/clean.do
@@ -0,0 +1,2 @@
rm -f *~ .*~ bork bork.do bork.log sub sub.log targets.out

3 changes: 3 additions & 0 deletions t/351-deps-forget/sub.do
@@ -0,0 +1,3 @@
[ -e bork ] && redo-ifchange bork
echo sub
printf y >>$1.log

0 comments on commit c06d1fb

Please sign in to comment.