The reason we'd crash is that we tried to pre-create a file called
$target.redo.tmp, which wouldn't work because the directory containing
$target didn't exist.
We now try to generate a smarter filename by using the innermost directory
of target that *does* exist. It's a little messy, but the idea is to make
sure we won't have to rename() across a filesystem boundary if, for example,
there's a mounted filesystem in the middle of the hierarchy somewhere.
We already did this in minimal/do, and redo-ifchange already did this, but
plain redo didn't. This made constructs like:
for d in *.x; do
echo "${d%.x}"
done | xargs redo
dangerous, because if there were no matching files, we'd try to 'redo all'.
We were accidentally including things like the atime in the comparison,
which is obviously silly; someone reading the file shouldn't mark it as a
manual override.
Since we use ". filename.do" to run the .do files instead of just
"filename.do", shell local variables end up being inherited by the
subprogram. Change all the local variables to be all lowercase, to avoid
conflicting with any typical environment variables someone might use.
The particular variable that triggered this was PREFIX (reported by "ulrik"
on the mailing list) and that fixes this, at least.
Arguably we shouldn't be using ".", but using it avoids unnecessary forks,
which is kind of nice.
If you ". ./filename" and ./filename contains no commands, apparently
ash/dash will give the exit code of the command *before* the ., rather than
defaulting to zero as it supposedly should. This should work around it in
our .do files at least.
Reported by Tim Allen.
It should just build nothing. Because sometimes you want to do something
like:
redo-ifchange $(find -name '*.c')
And the find doesn't return any results. This is consistent with what real
redo does.
Added a test to confirm that it works.
It was working fine, but the style wasn't exactly the way I like it, because
I'm unnecessarily picky. :)
Also, removed the file extension since we should probably learn from the
fact that it's already been rewritten once from one language to another.
Who knows, maybe it will be again someday.
Turns out we don't need sed to process the output of gcc -MD. We can just
do this:
read DEPS <filename.deps
The 'read' command in sh actually handles backslashes correctly, so we don't
have to sed them out after all. And then a simple ${DEPS#*:} removes the
"target:" prefix from the dependency line, and we're done!
By default, the database redo uses to store file state returns filenames
as Unicode strings, and if redo tries to run a build-script whose
fully-qualified path contains non-ASCII characters then redo crashes
when trying to promote the path to a Unicode string.
This patch ensures that the database always returns byte-strings, not
Unicode strings. That way, the fully-qualified path and the target name
are both byte-strings and can be joined without issue.
(Fixes a bug reported by Zoran Zaric.)
Sometimes clean.do implementations want to delete our .do_built file and
directory. If that happens, deal with it quietly, as long as they don't
request any *additional* redo-type operations.
It seems 'set -e' doesn't quite work, in some shells, in that case.
Eric Kow wrote:
> I saw this warning, by the way:
> redo t/shelltest
> warning: 94
> cd: 271: can't cd to /opt/redo-0.05/t/space
> rmdir: failed to remove pace home dir': No such file or directory
> warning: 111
If we're using a .do file from a parent directory, we should set $3 using
the same path prefix as $1. We were previously using just the basename,
which mostly works (since we would rename it to $1$2 eventually anyway) but
is not quite right, and you can't safely rename files across filesystems, so
it could theoretically cause problems.
Also improved t/defaults-nested to test for this behaviour.
Reported by Eric Kow.
Supposedly it's not POSIX, but every shell I have seems to support it, so
let's just reject any that don't. And like magic, anybody using redo can
now count on the 'local' builtin working.
This fails on ash, dash, and busybox sh (for now). But it's kind of
important since $HOME often has spaces on Win32. I hope dash will be fixed
relatively soon.
I downgraded it to a warning since on Unix, this probably isn't a problem.
If that ever happens, we probably got our paths mangled (like in the
previous commit) so we should die right away rather than allow weird things
to happen later.
The result was that t/deps/dirtest was actually failing in some cases. But
it wasn't failing quite reliably enough, because the failing test was
dirtest/dir1/all, which has the same name as some other 'all' files,
confusing the issue. Renamed dirtest/dir1/all.do to dirtest/dir1/go.do instead.
Reported by Prakhar Goel and Berke Durak.
I notice it doesn't quite work on my Ubuntu system - if I "cd version"
and run "../redo", I get the following output:
redo all
redo vars
redo gitvars
[: 24: %H: unexpected operator
[: 24: %d: unexpected operator
[: 24: %ci: unexpected operator
...and then a hang.
We have to go through some pretty scary gyrations to extract this
information from git, but it can be done. This works with both tarballs
generated by 'git archive', or with your local git repo.
(Requested by 'David' on the mailing list.)
- minimal/do is bigger now
- minimal/do is public domain
- link to busybox-w32 as a hint to win32 users
- Instead of talking about "Redofile", just explain how to do it with a case
statement in default.do
- Don't worry about $1 and $2; djb didn't complain :)
- Explain how the search-parent-dirs feature works. The semantics are now
that the .do file runs with $PWD set to the dir containing the .do file,
not the one containing the target. (This is backwards compatible since
the two directories always used to be identical. So now we just change
the documentation and it's all good.)
- Mention that you can send messages to the mailing list without
subscribing.