Fix more trouble with .do scripts that cd to other directories.

The interaction of REDO_STARTDIR, REDO_PWD, and getcwd() are pretty
complicated.  In this case, we accidentally assumed that the current
instance of redo was running with getcwd() == REDO_STARTDIR+REDO_PWD, and so
the new target was REDO_STARTDIR+REDO_PWD+t, but this isn't the case if the
current .do script did chdir().

The correct answer is REDO_STARTDIR+getcwd()+t.
This commit is contained in:
Avery Pennarun 2010-11-25 06:35:22 -08:00
commit c29de89051
4 changed files with 22 additions and 12 deletions

View file

@ -95,9 +95,13 @@ class BuildJob:
jwack.start_job(t, self._do_subproc, self._after) jwack.start_job(t, self._do_subproc, self._after)
def _do_subproc(self): def _do_subproc(self):
td = os.environ.get('REDO_PWD', '') # careful: REDO_PWD was the PWD relative to the STARTPATH at the time
# we *started* building the current target; but that target ran
# redo-ifchange, and it might have done it from a different directory
# than we started it in. So os.getcwd() might be != REDO_PWD right now.
dn = os.path.dirname(self.t) dn = os.path.dirname(self.t)
os.environ['REDO_PWD'] = os.path.join(td, dn) newp = os.path.realpath(dn)
os.environ['REDO_PWD'] = state.relpath(newp, vars.STARTDIR)
os.environ['REDO_TARGET'] = os.path.basename(self.t) os.environ['REDO_TARGET'] = os.path.basename(self.t)
os.environ['REDO_DEPTH'] = vars.DEPTH + ' ' os.environ['REDO_DEPTH'] = vars.DEPTH + ' '
if dn: if dn:

View file

@ -67,6 +67,9 @@ def debug(s):
def debug2(s): def debug2(s):
if vars.DEBUG >= 2: if vars.DEBUG >= 2:
log_('redo: %s%s' % (vars.DEPTH, s)) log_('redo: %s%s' % (vars.DEPTH, s))
def debug3(s):
if vars.DEBUG >= 3:
log_('redo: %s%s' % (vars.DEPTH, s))
def close_on_exec(fd, yes): def close_on_exec(fd, yes):

View file

@ -1,7 +1,7 @@
#!/usr/bin/python #!/usr/bin/python
import sys, os, errno import sys, os, errno
import vars, state, builder, jwack import vars, state, builder, jwack
from helpers import debug, err, mkdirp, unlink from helpers import debug, debug2, err, mkdirp, unlink
def dirty_deps(t, depth): def dirty_deps(t, depth):
@ -49,12 +49,13 @@ def should_build(t):
rv = 202 rv = 202
try: try:
me = os.path.join(vars.STARTDIR,
os.path.join(vars.PWD, vars.TARGET))
debug2('TARGET: %r %r %r\n' % (vars.STARTDIR, vars.PWD, vars.TARGET))
try: try:
targets = sys.argv[1:] targets = sys.argv[1:]
for t in targets: for t in targets:
state.add_dep(os.path.join(vars.STARTDIR, state.add_dep(me, 'm', t)
os.path.join(vars.PWD, vars.TARGET)),
'm', t)
rv = builder.main(targets, should_build) rv = builder.main(targets, should_build)
finally: finally:
jwack.force_return_tokens() jwack.force_return_tokens()

View file

@ -1,6 +1,6 @@
import sys, os, errno, glob import sys, os, errno, glob
import vars import vars
from helpers import unlink, err, debug2, mkdirp, close_on_exec from helpers import unlink, err, debug2, debug3, mkdirp, close_on_exec
def init(): def init():
@ -50,15 +50,17 @@ def _sname(typ, t):
# FIXME: t.replace(...) is non-reversible and non-unique here! # FIXME: t.replace(...) is non-reversible and non-unique here!
tnew = relpath(t, vars.BASE) tnew = relpath(t, vars.BASE)
v = vars.BASE + ('/.redo/%s^%s' % (typ, tnew.replace('/', '^'))) v = vars.BASE + ('/.redo/%s^%s' % (typ, tnew.replace('/', '^')))
if vars.DEBUG >= 2: if vars.DEBUG >= 3:
debug2('sname: (%r) %r -> %r\n' % (os.getcwd(), t, tnew)) debug3('sname: (%r) %r -> %r\n' % (os.getcwd(), t, tnew))
return v return v
def add_dep(t, mode, dep): def add_dep(t, mode, dep):
debug2('add-dep(%r)\n' % t) sn = _sname('dep', t)
open(_sname('dep', t), 'a').write('%s %s\n' reldep = relpath(dep, vars.BASE)
% (mode, relpath(dep, vars.BASE))) debug2('add-dep: %r < %s %r\n' % (sn, mode, reldep))
open(sn, 'a').write('%s %s\n' % (mode, reldep))
def deps(t): def deps(t):