Move 'redo --ifchange' into 'redo-ifchange' to match djb's style.
It does simplify the logic of both redo.py and redo-ifchange.py, I suppose.
This commit is contained in:
parent
63c596ac61
commit
c57de820fb
12 changed files with 103 additions and 87 deletions
27
libdo.py
Normal file
27
libdo.py
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
import sys, os
|
||||||
|
import vars
|
||||||
|
|
||||||
|
def relpath(t, base):
|
||||||
|
t = os.path.abspath(t)
|
||||||
|
tparts = t.split('/')
|
||||||
|
bparts = base.split('/')
|
||||||
|
for tp,bp in zip(tparts,bparts):
|
||||||
|
if tp != bp:
|
||||||
|
break
|
||||||
|
tparts.pop(0)
|
||||||
|
bparts.pop(0)
|
||||||
|
while bparts:
|
||||||
|
tparts.insert(0, '..')
|
||||||
|
bparts.pop(0)
|
||||||
|
return '/'.join(tparts)
|
||||||
|
|
||||||
|
|
||||||
|
def sname(typ, t):
|
||||||
|
# FIXME: t.replace(...) is non-reversible and non-unique here!
|
||||||
|
tnew = relpath(t, vars.BASE)
|
||||||
|
#log('sname: (%r) %r -> %r\n' % (vars.BASE, t, tnew))
|
||||||
|
return vars.BASE + ('/.redo/%s^%s' % (typ, tnew.replace('/', '^')))
|
||||||
|
|
||||||
|
|
||||||
|
def add_dep(t, mode, dep):
|
||||||
|
open(sname('dep', t), 'a').write('%s %s\n' % (mode, dep))
|
||||||
1
redo-ifchange
Symbolic link
1
redo-ifchange
Symbolic link
|
|
@ -0,0 +1 @@
|
||||||
|
redo-ifchange.py
|
||||||
61
redo-ifchange.py
Executable file
61
redo-ifchange.py
Executable file
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
import sys, os
|
||||||
|
import vars
|
||||||
|
from helpers import *
|
||||||
|
from log import *
|
||||||
|
from libdo import *
|
||||||
|
|
||||||
|
|
||||||
|
def _dirty_deps(t, depth):
|
||||||
|
debug('%s?%s\n' % (depth, t))
|
||||||
|
if not os.path.exists(sname('stamp', t)):
|
||||||
|
debug('%s-- DIRTY (no stamp)\n' % depth)
|
||||||
|
return True
|
||||||
|
|
||||||
|
stamptime = os.stat(sname('stamp', t)).st_mtime
|
||||||
|
try:
|
||||||
|
realtime = os.stat(t).st_mtime
|
||||||
|
except OSError:
|
||||||
|
realtime = 0
|
||||||
|
|
||||||
|
if stamptime != realtime:
|
||||||
|
debug('%s-- DIRTY (mtime)\n' % depth)
|
||||||
|
return True
|
||||||
|
|
||||||
|
for sub in open(sname('dep', t)).readlines():
|
||||||
|
assert(sub[0] in ('c','m'))
|
||||||
|
assert(sub[1] == ' ')
|
||||||
|
assert(sub[-1] == '\n')
|
||||||
|
mode = sub[0]
|
||||||
|
name = sub[2:-1]
|
||||||
|
if mode == 'c':
|
||||||
|
if os.path.exists(name):
|
||||||
|
debug('%s-- DIRTY (created)\n' % depth)
|
||||||
|
return True
|
||||||
|
elif mode == 'm':
|
||||||
|
if dirty_deps(name, depth + ' '):
|
||||||
|
#debug('%s-- DIRTY (sub)\n' % depth)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def dirty_deps(t, depth):
|
||||||
|
if _dirty_deps(t, depth):
|
||||||
|
unlink(sname('stamp', t)) # short circuit future checks
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
if not vars.TARGET:
|
||||||
|
sys.stderr.write('redo-ifchange: error: must be run from inside a .do\n')
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
want_build = []
|
||||||
|
for t in sys.argv[1:]:
|
||||||
|
mkdirp('%s/.redo' % vars.BASE)
|
||||||
|
add_dep(vars.TARGET, 'm', t)
|
||||||
|
if dirty_deps(t, depth = ''):
|
||||||
|
want_build.append(t)
|
||||||
|
|
||||||
|
if want_build:
|
||||||
|
os.execvp('redo', ['redo', '--'] + want_build)
|
||||||
85
redo.py
85
redo.py
|
|
@ -8,8 +8,6 @@ redo [targets...]
|
||||||
--
|
--
|
||||||
d,debug print dependency checks as they happen
|
d,debug print dependency checks as they happen
|
||||||
v,verbose print commands as they are run
|
v,verbose print commands as they are run
|
||||||
ifchange only redo if the file is modified or deleted
|
|
||||||
ifcreate only redo if the file is created
|
|
||||||
"""
|
"""
|
||||||
o = options.Options('redo', optspec)
|
o = options.Options('redo', optspec)
|
||||||
(opt, flags, extra) = o.parse(sys.argv[1:])
|
(opt, flags, extra) = o.parse(sys.argv[1:])
|
||||||
|
|
@ -17,90 +15,24 @@ o = options.Options('redo', optspec)
|
||||||
targets = extra or ['it']
|
targets = extra or ['it']
|
||||||
|
|
||||||
|
|
||||||
def relpath(t, base):
|
|
||||||
t = os.path.abspath(t)
|
|
||||||
tparts = t.split('/')
|
|
||||||
bparts = base.split('/')
|
|
||||||
for tp,bp in zip(tparts,bparts):
|
|
||||||
if tp != bp:
|
|
||||||
break
|
|
||||||
tparts.pop(0)
|
|
||||||
bparts.pop(0)
|
|
||||||
while bparts:
|
|
||||||
tparts.insert(0, '..')
|
|
||||||
bparts.pop(0)
|
|
||||||
return '/'.join(tparts)
|
|
||||||
|
|
||||||
|
|
||||||
def sname(typ, t):
|
|
||||||
# FIXME: t.replace(...) is non-reversible and non-unique here!
|
|
||||||
tnew = relpath(t, vars.BASE)
|
|
||||||
#log('sname: (%r) %r -> %r\n' % (vars.BASE, t, tnew))
|
|
||||||
return vars.BASE + ('/.redo/%s^%s' % (typ, tnew.replace('/', '^')))
|
|
||||||
|
|
||||||
|
|
||||||
def add_dep(t, mode, dep):
|
|
||||||
open(sname('dep', t), 'a').write('%s %s\n' % (mode, dep))
|
|
||||||
|
|
||||||
|
|
||||||
def find_do_file(t):
|
def find_do_file(t):
|
||||||
dofile = '%s.do' % t
|
dofile = '%s.do' % t
|
||||||
if os.path.exists(dofile):
|
if os.path.exists(dofile):
|
||||||
add_dep(t, 'm', dofile)
|
add_dep(t, 'm', dofile)
|
||||||
if dirty_deps(dofile, depth = ''):
|
|
||||||
build(dofile)
|
|
||||||
return dofile
|
return dofile
|
||||||
else:
|
else:
|
||||||
add_dep(t, 'c', dofile)
|
add_dep(t, 'c', dofile)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def _dirty_deps(t, depth):
|
|
||||||
debug('%s?%s\n' % (depth, t))
|
|
||||||
if not os.path.exists(sname('stamp', t)):
|
|
||||||
debug('%s-- DIRTY (no stamp)\n' % depth)
|
|
||||||
return True
|
|
||||||
|
|
||||||
stamptime = os.stat(sname('stamp', t)).st_mtime
|
|
||||||
try:
|
|
||||||
realtime = os.stat(t).st_mtime
|
|
||||||
except OSError:
|
|
||||||
realtime = 0
|
|
||||||
|
|
||||||
if stamptime != realtime:
|
|
||||||
debug('%s-- DIRTY (mtime)\n' % depth)
|
|
||||||
return True
|
|
||||||
|
|
||||||
for sub in open(sname('dep', t)).readlines():
|
|
||||||
assert(sub[0] in ('c','m'))
|
|
||||||
assert(sub[1] == ' ')
|
|
||||||
assert(sub[-1] == '\n')
|
|
||||||
mode = sub[0]
|
|
||||||
name = sub[2:-1]
|
|
||||||
if mode == 'c':
|
|
||||||
if os.path.exists(name):
|
|
||||||
debug('%s-- DIRTY (created)\n' % depth)
|
|
||||||
return True
|
|
||||||
elif mode == 'm':
|
|
||||||
if dirty_deps(name, depth + ' '):
|
|
||||||
#debug('%s-- DIRTY (sub)\n' % depth)
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def dirty_deps(t, depth):
|
|
||||||
if _dirty_deps(t, depth):
|
|
||||||
unlink(sname('stamp', t)) # short circuit future checks
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def stamp(t):
|
def stamp(t):
|
||||||
stampfile = sname('stamp', t)
|
stampfile = sname('stamp', t)
|
||||||
|
depfile = sname('dep', t)
|
||||||
if not os.path.exists(vars.BASE + '/.redo'):
|
if not os.path.exists(vars.BASE + '/.redo'):
|
||||||
# .redo might not exist in a 'make clean' target
|
# .redo might not exist in a 'make clean' target
|
||||||
return
|
return
|
||||||
open(stampfile, 'w').close()
|
open(stampfile, 'w').close()
|
||||||
|
open(depfile, 'a').close()
|
||||||
try:
|
try:
|
||||||
mtime = os.stat(t).st_mtime
|
mtime = os.stat(t).st_mtime
|
||||||
except OSError:
|
except OSError:
|
||||||
|
|
@ -126,6 +58,7 @@ def build(t):
|
||||||
return # success
|
return # success
|
||||||
else:
|
else:
|
||||||
raise Exception('no rule to make %r' % t)
|
raise Exception('no rule to make %r' % t)
|
||||||
|
stamp(dofile)
|
||||||
unlink(t)
|
unlink(t)
|
||||||
tmpname = '%s.redo.tmp' % t
|
tmpname = '%s.redo.tmp' % t
|
||||||
unlink(tmpname)
|
unlink(tmpname)
|
||||||
|
|
@ -158,7 +91,6 @@ if opt.debug:
|
||||||
os.environ['REDO_DEBUG'] = '1'
|
os.environ['REDO_DEBUG'] = '1'
|
||||||
if opt.verbose:
|
if opt.verbose:
|
||||||
os.environ['REDO_VERBOSE'] = '1'
|
os.environ['REDO_VERBOSE'] = '1'
|
||||||
assert(not (opt.ifchange and opt.ifcreate))
|
|
||||||
|
|
||||||
if not os.environ.get('REDO_BASE', ''):
|
if not os.environ.get('REDO_BASE', ''):
|
||||||
base = os.path.commonprefix([os.path.abspath(os.path.dirname(t))
|
base = os.path.commonprefix([os.path.abspath(os.path.dirname(t))
|
||||||
|
|
@ -173,6 +105,7 @@ if not os.environ.get('REDO_BASE', ''):
|
||||||
|
|
||||||
import vars
|
import vars
|
||||||
from log import *
|
from log import *
|
||||||
|
from libdo import *
|
||||||
|
|
||||||
if not vars.DEPTH:
|
if not vars.DEPTH:
|
||||||
# toplevel call to redo
|
# toplevel call to redo
|
||||||
|
|
@ -188,11 +121,5 @@ for t in targets:
|
||||||
os.chdir(startdir)
|
os.chdir(startdir)
|
||||||
|
|
||||||
if vars.TARGET:
|
if vars.TARGET:
|
||||||
add_dep(vars.TARGET, opt.ifcreate and 'c' or 'm', t)
|
add_dep(vars.TARGET, 'm', t)
|
||||||
if opt.ifcreate:
|
build(t)
|
||||||
pass # just adding the dependency (above) is enough
|
|
||||||
elif opt.ifchange:
|
|
||||||
if dirty_deps(t, depth = ''):
|
|
||||||
build(t)
|
|
||||||
else:
|
|
||||||
build(t)
|
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
redo --ifchange LD yellow.o
|
redo-ifchange LD yellow.o
|
||||||
./LD bellow yellow.o
|
./LD bellow yellow.o
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
redo --ifchange LD hello.o
|
redo-ifchange LD hello.o
|
||||||
./LD hello hello.o
|
./LD hello hello.o
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
redo --ifchange CC hello.c /usr/include/stdio.h
|
redo-ifchange CC hello.c /usr/include/stdio.h
|
||||||
./CC hello.c
|
./CC hello.c
|
||||||
|
|
|
||||||
2
t/it.do
2
t/it.do
|
|
@ -1,2 +1,2 @@
|
||||||
redo --ifchange hello yellow bellow
|
redo-ifchange hello yellow bellow
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
redo --ifchange it
|
redo-ifchange it
|
||||||
./hello >&2
|
./hello >&2
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
redo --ifchange LD yellow.o
|
redo-ifchange LD yellow.o
|
||||||
./LD yellow yellow.o
|
./LD yellow yellow.o
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,2 @@
|
||||||
redo --ifchange CC hello.c
|
redo-ifchange CC hello.c
|
||||||
gcc -o $3 -c hello.c
|
gcc -o $3 -c hello.c
|
||||||
|
|
|
||||||
2
test.do
2
test.do
|
|
@ -1,4 +1,4 @@
|
||||||
redo --ifchange t/it
|
redo-ifchange t/it
|
||||||
wvtestrun redo runtests >&2
|
wvtestrun redo runtests >&2
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue