Commit graph

492 commits

Author SHA1 Message Date
Avery Pennarun
6b0da1fda0 Add a -x option that just passes -x to the subshell.
This is often more useful than -v, since it prints the actual commands being
executed, not just the lines being input from the script.
2010-11-21 06:36:15 -08:00
Avery Pennarun
03a054ca79 Add a --debug-locks option.
Get rid of the "locked..." and "...unlocked!" messages by default, since
they're not usually interesting.  But add a new option to bring them back in
case we end up with trouble debugging the locking stuff.  (I don't really
100% trust it yet, although I haven't had a problem for a while now.)
2010-11-21 06:23:41 -08:00
Avery Pennarun
4d47b5ec7f Add a new test for filenames with spaces. 2010-11-21 06:20:16 -08:00
Avery Pennarun
e8584c8d76 Add a new passfailtest.
This tests that the target file isn't removed or changed if building fails.
2010-11-21 06:12:27 -08:00
Avery Pennarun
39ef065443 Refactor all.do and test.do in various directories.
Now 'redo test' runs the tests, but 'redo t' just builds the programs.

Also removed wvtest stuff; we're not really using it properly anyway and
it's not helping our testing right now.  It might come back later.
2010-11-21 05:47:48 -08:00
Avery Pennarun
27407f8f8e t/all.do: make sure the subdir all.do's always run.
...not just when their dependencies are dirty.  Some of them want to do some
explicit checks of redo's behaviour.
2010-11-21 05:39:00 -08:00
Avery Pennarun
d6c5c06364 redo-ifchange: unstamp() was in the wrong spot, causing unnecessary rebuilds.
dirty_deps() changed its meaning now that we also have to check
state.isbuilt().  Now, just because dirty_deps() returns true doesn't mean
that the file should be unstamped (which forces a rebuild); this might have
happened because of state.isbuilt, which means someone already *did* do a
rebuild.

If we get past state.isbuilt() and into looking at the children, however,
and one of the children is dirty, then we should definitely unstamp the
current target.
2010-11-21 05:34:02 -08:00
Avery Pennarun
47edb9527d state.py: remove all the ugly fromdir= stuff.
Instead, just change the target name to be more specific, in the one place
in redo-ifchange that actually needed it.
2010-11-21 04:57:04 -08:00
Avery Pennarun
b19a918894 Test for the previous bugfix.
This fails if you make test *twice* without the preceding patch.
Unfortunately I couldn't find a good way to make it fail if you only make
test once.
2010-11-21 04:41:03 -08:00
Avery Pennarun
0652bc9911 Oops, earlier state.mark() stuff was a little too radical.
If someone else built and marked one of our dependencies, then that
dependency would show up as *clean* in a later redo-ifchange, so other
dependents of that file wouldn't be rebuilt.

We actually have to track two session-specific variables: whether the file
has been checked, and whether it was rebuilt.  (Or alternatively, whether it
was dirty when we checked it the first time.  But we store the former.)
2010-11-21 04:39:28 -08:00
Avery Pennarun
cd702a8126 state.Lock: initialize self.owner first, to avoid problems in __del__
...if an exception is ever thrown in _sname().  Which shouldn't happen, but
we might as well be careful.
2010-11-21 03:57:52 -08:00
Avery Pennarun
f644f3bd04 Remove the need for relpath (and thus abspath) in builder.py. 2010-11-21 03:35:19 -08:00
Avery Pennarun
61c7e0f8a8 vars.py: it's safe to assume REDO_BASE and REDO_STARTDIR are set correctly.
This lets us remove an extra call to os.abspath().
2010-11-21 03:09:43 -08:00
Avery Pennarun
700873a90f Slightly clarify the initialization code in redo.py. 2010-11-21 02:26:18 -08:00
Avery Pennarun
12983bd88d Move initialization of .redo directory into state.init(). 2010-11-21 02:26:18 -08:00
Avery Pennarun
2f604b2c8f Don't re-check dependencies in a single run.
If a depends on b depends on c, then if when we consider building a, we have
to check b and c.  If we then are asked about a2 which depends on b, there
is no reason to re-check b and its dependencies; we already know it's done.

This takes the time to do 'redo t/curse/all' the *second* time down from
1.0s to 0.13s.  (make can still do it in 0.07s.)

'redo t/curse/all' the first time is down from 5.4s to to 4.6s.  With -j4,
from 3.0s to 2.5s.
2010-11-21 01:29:55 -08:00
Avery Pennarun
de042fc2f2 t/curse: add a Makefile so we can compare speed when using GNU make.
redo: 5.4s
redo -j4: 3.0s
make: 2.3s
make -j4: 1.4s
make SHELL=/bin/dash: 1.2s
make SHELL=/bin/dash -j4: 0.83s

We have some distance to go yet.  Of course, redo is still written in
python, not C, so it's very expensive, and the on-disk dependency store is
very inefficient.
2010-11-21 00:31:48 -08:00
Avery Pennarun
81cbe49938 minimal/do: write my own replacements for dirname and basename.
This greatly reduces the number of fork+exec calls, so in particular,
t/curse/all.do now runs much faster:

   /bin/sh (bash): was 5.9s, now 2.2s
   /bin/dash: was 3.2s, now 1.1s

Obviously improving the speed of minimal/do doesn't really matter, except
that it makes a good benchmark to compare the "real" redo against.  So far
it's losing badly: 5.4s.
2010-11-21 00:19:31 -08:00
Avery Pennarun
f62176f809 README: explain stdout redirection and the meanings of $1,$2,$3.
Luke reported some trouble figuring these out, what with their being totally
undocumented.
2010-11-20 23:30:59 -08:00
Avery Pennarun
2f5814c0fe Add curse/all to t/all, now that it passes. 2010-11-19 07:33:45 -08:00
Avery Pennarun
22f8cb48f4 redo-ifchange: call builder directly, rather than forking redo.
Now we no longer rebuild the same stuff over and over!
2010-11-19 07:32:16 -08:00
Avery Pennarun
f7734c3b8d Split build functions into builder.py. 2010-11-19 07:32:04 -08:00
Avery Pennarun
116e7e5f13 We now check the lock before releasing our jwack token.
That way, if everything is locked, we can determine that with a single
token, reducing context switches.

But mostly this is good because the code is simpler.
2010-11-19 07:20:55 -08:00
Avery Pennarun
c10875d7d7 Don't unlink(t) before building; always rebuild the target if it was locked.
The 'redo' command is supposed to *always* rebuild, not just if nobody else
rebuilt it.  (If you want "rebuild sometimes" behaviour, use redo-ifchange.)
Thus, we shouldn't be short circuiting it just because a file was previously
locked and then built okay.

However, there's still a race condition in parallel builds, because
redo-ifchange only checks the build stamp of each file once, then passes it
to redo.  Thus, we end up trying to build the same stuff over and over.
This change actually makes it build *more* times, which seems dumb, but is
one step closer to right.

Doing this broke 'make test', however, because we were unlinking the target
right before building it, rather than replacing it atomically as djb's
original design suggested we should do.  Thus, because of the combination of
the above two bugs, CC would appear and then disappear even as people were
trying to actually use it.  Now it gets replaced atomically so it should
at least work at all times... even though we're still building it more than
once, which is incorrect.
2010-11-19 06:43:18 -08:00
Avery Pennarun
362ca2997a A whole bunch of cleanups to state.Lock.
Now t/curse passes again when parallelized (except for the countall
mismatch, since we haven't fixed the source of that problem yet).  At least
it's consistent now.

There's a bunch of stuff rearranged in here, but the actual important
problem was that we were doing unlink() on the lock fifo even if ENXIO,
which meant a reader could connect in between ENXIO and unlink(), and thus
never get notified of the disconnection.  This would cause the build to
randomly freeze.
2010-11-19 06:07:41 -08:00
Avery Pennarun
132ff02840 Only mkdirp() the .redo directory in one place right at the beginning.
This doesn't really seem to change anything, but it's more correct and
should reveal weirdness (especially an incorrect .redo directory in a
sub-redo) sooner.
2010-11-19 03:16:39 -08:00
Avery Pennarun
dc3efb69cc Extract .redo dir state management stuff into its own file.
In preparation for changing the on-disk format eventually, as well as making
the main code more readable.
2010-11-19 03:16:29 -08:00
Avery Pennarun
81356931a4 Oops, when searching up the tree, we'd use ../.redo/.redo as the redodir.
Obviously it should be ../.redo instead.  REDO_BASE is .., not ../.redo.
2010-11-19 03:15:45 -08:00
Avery Pennarun
65d4639b48 t/curse: test that 'redo' (not redo-ifchange) always redoes a command.
...if the containing .do file is getting redone at all, of course.

Currently passes in serial mode, fails in parallel.
2010-11-19 02:20:17 -08:00
Avery Pennarun
8e4bfd10f9 .gitignore 2010-11-19 02:20:17 -08:00
Avery Pennarun
a5ff60ccf3 Fix a race condition generating stampfiles.
This makes 'redo -j1000' now run successfully in t/curse, except that we
foolishly generate the same files more than once.  But at least not more
than once *in parallel*.
2010-11-19 00:57:27 -08:00
Avery Pennarun
ec6f61949b t/curse: test to make sure the same file isn't generated more than once.
redo currently passes this when running serially, but not in parallel.
2010-11-19 00:55:36 -08:00
Avery Pennarun
2a9a332451 jwack.py: print the full traceback if a task fails to run. 2010-11-19 00:54:36 -08:00
Avery Pennarun
9b23b2c67a Add t/curse, a multi-level dependency build that really aggravates redo.
...because it seems my locking isn't very good.  It exposes annoying
problems involving rebuilding the same files more than once, screwing up
stamp files with redo -j, and being unnecessarily slow when checking
dependencies.  So it's a pretty good test considering how simple it is.

Didn't add it to t/all.do yet, because it would fail.
2010-11-19 00:28:16 -08:00
Avery Pennarun
c4287b9d81 Improve 'redo -v' output whitespace.
It was too hard to tell when an ifchange ended and the commands from the
prior level started running again.  Now it's a little better.
2010-11-18 23:06:38 -08:00
Avery Pennarun
eae3e7cdef Add t/example, a basic example build environment suitable for a tutorial. 2010-11-18 22:48:46 -08:00
Avery Pennarun
2b71e662cb Replace lockfile stuff with fifos instead.
Now people waiting for a lock can wait for the fifo to be ready, which means
it's instant instead of polled.  Very pretty.  Probably doesn't work on
Windows though.
2010-11-18 22:46:30 -08:00
Avery Pennarun
b9853d3858 minimal/do: handle nonzero exit codes and set $1/$2 correctly.
Also add some tests to confirm this.
2010-11-17 19:07:27 -08:00
Avery Pennarun
c7585558ef If the .do script deletes $3, don't die. 2010-11-17 17:55:16 -08:00
Avery Pennarun
abbde40a4f Add README.md and LICENSE.
LGPLv2, by the way.
2010-11-17 00:53:58 -08:00
Avery Pennarun
84046bcab2 Some very suspicious changes to relpath() and sname() calls.
The problem is that redo-ifchange has a different $PWD than its
sub-dependencies, so as it's chasing them down, fixing up the relative paths
totally doesn't work at all.

There's probably a much smarter fix than this, but it's too late at night to
think of it right now.
2010-11-16 05:47:33 -08:00
Avery Pennarun
d9fe4806ac Oops, 'redo t/c.c' didn't work, because find_do_file() was slightly wrong.
We weren't searching for default.*.do in the subdir when needed.
2010-11-16 04:16:01 -08:00
Avery Pennarun
94b0e7166e Move atoi() into atoi.py and add a new debug2() debug level.
atoi() was getting redundant, and unfortunately we can't easily load
helpers.py in some places where we'd want to, because it depends on vars.py.
So move it to its own module.
2010-11-16 04:13:17 -08:00
Avery Pennarun
75063244b2 redo.py: we weren't removing the lock if there was a build error, oops.
try/finally doesn't work if there's an os._exit() in there.
2010-11-16 04:06:26 -08:00
Avery Pennarun
95d4e64a11 If foo and foo.do exist, then foo is always a target, not a source file.
The problem is if someone accidentally creates a file called "test" *before*
.redo/gen^test got created, then 'redo test' would do nothing, because redo
would assume it's a source file instead of a destination, according to djb's
rule.  But in this case, we know it's not, since test.do exists, so let's
build it anyway.  The problem is related to .PHONY rules in make.

This workaround is kind of cheating, because we can't safely apply that rule
if foo and default.do exist, even though default.do can be used to build
foo.

This probably won't happen very often... except with minimal/do, which
creates these empty files even when it shouldn't.  I'm not sure if I should
try to fix that or not, though.
2010-11-16 03:40:13 -08:00
Avery Pennarun
41afb96f25 minimal/do: pretty up the output.
We're up to 1315 bytes now, though.  Lame.
2010-11-16 03:28:44 -08:00
Avery Pennarun
4b8c929cdc minimal/do: add support for default.* targets.
Unit tests now pass again with 'minimal/do test'.
2010-11-16 03:20:52 -08:00
Avery Pennarun
ac36dcf136 minimal/do: given a directory name, build dirname/all
Like redo does.
2010-11-16 03:11:28 -08:00
Avery Pennarun
c1f09f564b Support for default.*.do rules.
I *think* this was the last missing part from djb's spec.  Certainly it's an
important one for any real project.
2010-11-16 03:04:11 -08:00
Avery Pennarun
b25e79f353 Add a --shuffle option to let you enable dependency randomization.
Previously, for testing, we were *always* randomizing the build order of
dependencies.  That's annoying since it'll make build logs differ randomly
from one run to the next, which could make comparisons harder.  However, the
feature is still useful for uncovering hidden dependencies between objects.
2010-11-16 00:28:01 -08:00