Handle .do files that start with "#!/" to specify an explicit interpreter.
Now you can have your .do files interpreted by whatever interpreter you want.
This commit is contained in:
parent
f24d4f142b
commit
f641e52e3b
7 changed files with 38 additions and 11 deletions
29
README.md
29
README.md
|
|
@ -437,15 +437,28 @@ changed, you can run `redo-ifchange target` instead.
|
|||
|
||||
# Can my .do files be written in a language other than sh?
|
||||
|
||||
FIXME: Not presently. In theory, we could support starting your .do files
|
||||
with the magic "#!/" sequence (eg. #!/usr/bin/python) and then using that
|
||||
shell to run your .do script. But that opens new problems, like figuring
|
||||
out what is the equivalent of the `redo-ifchange` command in python. Do you
|
||||
just run it in a subprocess? That might be unnecessarily slow. And so on.
|
||||
Yes. If the first line of your .do file starts with the
|
||||
magic "#!/" sequence (eg. `#!/usr/bin/python`), then redo
|
||||
will execute your script using that particular interpreter.
|
||||
|
||||
Right now, `redo` explicitly runs `sh filename.do`. The main reasons for
|
||||
this are to make the #!/ line optional, and so you don't have to remember to
|
||||
`chmod +x` your .do files.
|
||||
Note that this is slightly different from normal Unix
|
||||
execution semantics: redo never execs your script directly;
|
||||
it only looks for the "#!/" line. The main reason for this
|
||||
is so that your .do scripts don't have to be marked
|
||||
executable (chmod +x). Executable .do scripts would
|
||||
suggest to users that they should run them directly, and
|
||||
they shouldn't; .do scripts should always be executed
|
||||
inside an instance of redo, so that dependencies can be
|
||||
tracked correctly.
|
||||
|
||||
WARNING: If your .do script *is* written in Unix sh, we
|
||||
recommend *not* including the `#!/bin/sh` line. That's
|
||||
because there are many variations of /bin/sh, and not all
|
||||
of them are POSIX compliant. redo tries pretty hard to
|
||||
find a good default shell that will be "as POSIXy as
|
||||
possible," and if you override it using #!/bin/sh, you lose
|
||||
this benefit and you'll have to worry more about
|
||||
portability.
|
||||
|
||||
|
||||
# Can a single .do script generate multiple outputs?
|
||||
|
|
|
|||
|
|
@ -128,6 +128,9 @@ class BuildJob:
|
|||
if vars.VERBOSE: argv[1] += 'v'
|
||||
if vars.XTRACE: argv[1] += 'x'
|
||||
if vars.VERBOSE or vars.XTRACE: log_('\n')
|
||||
firstline = open(dofile).readline().strip()
|
||||
if firstline.startswith('#!/'):
|
||||
argv[0:2] = firstline[2:].split(' ')
|
||||
log('%s\n' % _nice(t))
|
||||
self.argv = argv
|
||||
sf.is_generated = True
|
||||
|
|
|
|||
|
|
@ -57,7 +57,13 @@ _run_dofile()
|
|||
export DO_DEPTH="$DO_DEPTH "
|
||||
export REDO_TARGET=$PWD/$TARGET
|
||||
set -e
|
||||
read line1 <"$PWD/$DOFILE"
|
||||
cmd=${line1#"#!/"}
|
||||
if [ "$cmd" != "$line1" ]; then
|
||||
/$cmd "$PWD/$DOFILE" "$@" >"$TARGET.tmp2"
|
||||
else
|
||||
. "$PWD/$DOFILE" >"$TARGET.tmp2"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
1
t/.gitignore
vendored
1
t/.gitignore
vendored
|
|
@ -23,3 +23,4 @@ test2.args
|
|||
/ifcreate[12]
|
||||
/broken
|
||||
/shellfile
|
||||
/nonshelltest
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
redo example/clean curse/clean deps/clean "space dir/clean" stamp/clean \
|
||||
defaults-flat/clean
|
||||
rm -f broken shellfile mode1 makedir.log chdir1 deltest2 \
|
||||
rm -f broken nonshelltest shellfile mode1 makedir.log chdir1 deltest2 \
|
||||
hello [by]ellow *.o *~ .*~ *.log CC LD passfail silence silence.do \
|
||||
touch1 touch1.do always1 ifcreate[12].dep ifcreate[12]
|
||||
rm -rf makedir
|
||||
|
|
|
|||
3
t/nonshelltest.do
Normal file
3
t/nonshelltest.do
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#!/usr/bin/env perl
|
||||
$a="perly";
|
||||
print "hello $a world\n";
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
redo-ifchange all
|
||||
./hello >&2
|
||||
redo shelltest deltest deltest2 test.args test2.args passfailtest chdirtest \
|
||||
redo nonshelltest shelltest \
|
||||
deltest deltest2 test.args test2.args passfailtest chdirtest \
|
||||
curse/test deps/test "space dir/test" modetest makedir2 \
|
||||
silencetest touchtest stamp/test alwaystest ifcreate-test
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue