2011-02-22 22:15:28 -06:00
|
|
|
#!/usr/bin/env python
|
2010-12-19 02:31:40 -08:00
|
|
|
import sys, os
|
2010-12-11 19:08:53 -08:00
|
|
|
|
|
|
|
|
import vars_init
|
|
|
|
|
vars_init.init(sys.argv[1:])
|
|
|
|
|
|
2010-12-19 02:31:40 -08:00
|
|
|
import vars, state, builder, jwack, deps
|
2010-12-11 18:32:40 -08:00
|
|
|
from helpers import unlink
|
|
|
|
|
from log import debug, debug2, err
|
2010-11-13 00:45:49 -08:00
|
|
|
|
2010-11-21 04:14:52 -08:00
|
|
|
def should_build(t):
|
2010-12-07 02:17:22 -08:00
|
|
|
f = state.File(name=t)
|
2010-12-10 20:53:31 -08:00
|
|
|
if f.is_failed():
|
|
|
|
|
raise builder.ImmediateReturn(32)
|
2010-12-19 02:31:40 -08:00
|
|
|
dirty = deps.isdirty(f, depth = '', max_changed = vars.RUNID)
|
|
|
|
|
return dirty==[f] and deps.DIRTY or dirty
|
2010-11-21 04:14:52 -08:00
|
|
|
|
|
|
|
|
|
2010-11-19 07:32:16 -08:00
|
|
|
rv = 202
|
2010-11-13 02:09:42 -08:00
|
|
|
try:
|
2010-12-11 19:08:53 -08:00
|
|
|
if vars.TARGET and not vars.UNLOCKED:
|
|
|
|
|
me = os.path.join(vars.STARTDIR,
|
|
|
|
|
os.path.join(vars.PWD, vars.TARGET))
|
|
|
|
|
f = state.File(name=me)
|
|
|
|
|
debug2('TARGET: %r %r %r\n' % (vars.STARTDIR, vars.PWD, vars.TARGET))
|
|
|
|
|
else:
|
|
|
|
|
f = me = None
|
|
|
|
|
debug2('redo-ifchange: not adding depends.\n')
|
2010-11-21 21:15:24 -08:00
|
|
|
try:
|
2010-11-21 23:33:11 -08:00
|
|
|
targets = sys.argv[1:]
|
2010-12-11 19:08:53 -08:00
|
|
|
if f:
|
The second half of redo-stamp: out-of-order building.
If a depends on b depends on c, and c is dirty but b uses redo-stamp
checksums, then 'redo-ifchange a' is indeterminate: we won't know if we need
to run a.do unless we first build b, but the script that *normally* runs
'redo-ifchange b' is a.do, and we don't want to run that yet, because we
don't know for sure if b is dirty, and we shouldn't build a unless one of
its dependencies is dirty. Eek!
Luckily, there's a safe solution. If we *know* a is dirty - eg. because
a.do or one of its children has definitely changed - then we can just run
a.do immediately and there's no problem, even if b is indeterminate, because
we were going to run a.do anyhow.
If a's dependencies are *not* definitely dirty, and all we have is
indeterminate ones like b, then that means a's build process *hasn't
changed*, which means its tree of dependencies still includes b, which means
we can deduce that if we *did* run a.do, it would end up running b.do.
Since we know that anyhow, we can safely just run b.do, which will either
b.set_checked() or b.set_changed(). Once that's done, we can re-parse a's
dependencies and this time conclusively tell if it needs to be redone or
not. Even if it does, b is already up-to-date, so the 'redo-ifchange b'
line in a.do will be fast.
...now take all the above and do it recursively to handle nested
dependencies, etc, and you're done.
2010-12-11 04:40:05 -08:00
|
|
|
for t in targets:
|
|
|
|
|
f.add_dep('m', t)
|
|
|
|
|
f.save()
|
2010-11-21 23:33:11 -08:00
|
|
|
rv = builder.main(targets, should_build)
|
2010-11-21 21:15:24 -08:00
|
|
|
finally:
|
|
|
|
|
jwack.force_return_tokens()
|
2010-11-13 02:09:42 -08:00
|
|
|
except KeyboardInterrupt:
|
|
|
|
|
sys.exit(200)
|
2010-12-11 19:08:53 -08:00
|
|
|
state.commit()
|
2010-11-19 07:32:16 -08:00
|
|
|
sys.exit(rv)
|