232 lines
5.5 KiB
Perl
232 lines
5.5 KiB
Perl
|
|
Test for --action-stdxxx-on-success
|
||
|
|
====================================
|
||
|
|
|
||
|
|
$ export BUILD_PATH_PREFIX_MAP="sh=$(command -v sh):$BUILD_PATH_PREFIX_MAP"
|
||
|
|
|
||
|
|
$ echo '(lang dune 3.0)' > dune-project
|
||
|
|
|
||
|
|
$ cat > dune <<EOF
|
||
|
|
> (rule
|
||
|
|
> (alias default)
|
||
|
|
> (action (system "echo 'Hello, world!'")))
|
||
|
|
>
|
||
|
|
> (rule
|
||
|
|
> (alias default)
|
||
|
|
> (action (system "echo 'Something went wrong!' >&2")))
|
||
|
|
>
|
||
|
|
> (rule
|
||
|
|
> (alias both-stdout-and-stderr-output)
|
||
|
|
> (action (system "echo stdout; echo stderr >&2")))
|
||
|
|
> EOF
|
||
|
|
|
||
|
|
By default, stdout and stderr are always printed:
|
||
|
|
|
||
|
|
$ dune build
|
||
|
|
Hello, world!
|
||
|
|
Something went wrong!
|
||
|
|
|
||
|
|
swallow tests
|
||
|
|
-------------
|
||
|
|
|
||
|
|
$ dune clean
|
||
|
|
$ dune build --action-stdout-on-success=swallow --action-stderr-on-success=swallow
|
||
|
|
|
||
|
|
must-be-empty tests
|
||
|
|
----------------------
|
||
|
|
|
||
|
|
In the two above tests, we ask Dune to enforce that the the stdout
|
||
|
|
(resp. stderr) of actions is empty via the must-be-empty setting.
|
||
|
|
Since the first rule has a non-empty stdout and the second has a
|
||
|
|
non-empty stderr, we observe that in each case the build fails
|
||
|
|
printing the output of the action that had a non-empty output.
|
||
|
|
|
||
|
|
$ dune clean
|
||
|
|
$ dune build --action-stdout-on-success=must-be-empty
|
||
|
|
Something went wrong!
|
||
|
|
File "dune", lines 1-3, characters 0-65:
|
||
|
|
1 | (rule
|
||
|
|
2 | (alias default)
|
||
|
|
3 | (action (system "echo 'Hello, world!'")))
|
||
|
|
Hello, world!
|
||
|
|
[1]
|
||
|
|
|
||
|
|
$ dune clean
|
||
|
|
$ dune build --action-stderr-on-success=must-be-empty
|
||
|
|
Hello, world!
|
||
|
|
File "dune", lines 5-7, characters 0-77:
|
||
|
|
5 | (rule
|
||
|
|
6 | (alias default)
|
||
|
|
7 | (action (system "echo 'Something went wrong!' >&2")))
|
||
|
|
Something went wrong!
|
||
|
|
[1]
|
||
|
|
|
||
|
|
Same but with output on both stdout and stderr:
|
||
|
|
|
||
|
|
$ dune clean
|
||
|
|
$ dune build @both-stdout-and-stderr-output \
|
||
|
|
> --action-stdout-on-success=must-be-empty \
|
||
|
|
> --action-stderr-on-success=must-be-empty
|
||
|
|
File "dune", lines 9-11, characters 0-95:
|
||
|
|
9 | (rule
|
||
|
|
10 | (alias both-stdout-and-stderr-output)
|
||
|
|
11 | (action (system "echo stdout; echo stderr >&2")))
|
||
|
|
stdout
|
||
|
|
stderr
|
||
|
|
[1]
|
||
|
|
|
||
|
|
|
||
|
|
Incremental builds
|
||
|
|
------------------
|
||
|
|
|
||
|
|
Dune handles --action-stdxxx-on-success in such a way that if
|
||
|
|
changing the status of one of the two option changes what is printed
|
||
|
|
to the terminal, then the action is re-executed.
|
||
|
|
|
||
|
|
$ dune clean
|
||
|
|
$ dune build \
|
||
|
|
> --action-stdout-on-success=swallow \
|
||
|
|
> --action-stderr-on-success=swallow
|
||
|
|
|
||
|
|
For instance, if we previously swallowed stdout/stderr and stop doing
|
||
|
|
it, actions that printed something to stdout or stderr are
|
||
|
|
re-executed:
|
||
|
|
|
||
|
|
$ dune build
|
||
|
|
Hello, world!
|
||
|
|
Something went wrong!
|
||
|
|
|
||
|
|
However, we currently re-execute too much. In particular, we
|
||
|
|
re-execute actions whose outcome is not affected by the change:
|
||
|
|
|
||
|
|
$ cat > dune <<EOF
|
||
|
|
> (rule
|
||
|
|
> (alias default)
|
||
|
|
> (action (system "echo a.stdout; echo a.stderr >&2")))
|
||
|
|
>
|
||
|
|
> (rule
|
||
|
|
> (alias default)
|
||
|
|
> (action (system "echo b.stderr >&2")))
|
||
|
|
> EOF
|
||
|
|
|
||
|
|
$ dune clean
|
||
|
|
$ dune build --action-stdout-on-success=swallow
|
||
|
|
a.stderr
|
||
|
|
b.stderr
|
||
|
|
|
||
|
|
You can observe in the below call that both actions are being
|
||
|
|
re-executed:
|
||
|
|
|
||
|
|
$ dune build
|
||
|
|
a.stdout
|
||
|
|
a.stderr
|
||
|
|
b.stderr
|
||
|
|
|
||
|
|
However, re-executing the second action was not necessary given that
|
||
|
|
its stdout was empty. Dune could have recorded the fact that the
|
||
|
|
second action had an empty stdout and so was unaffected by the status
|
||
|
|
of --action-stdout-on-success. Dune could also cache the
|
||
|
|
stdout/stderr of actions across builds and only re-print them rather
|
||
|
|
than re-execute actions entirely.
|
||
|
|
|
||
|
|
In case of errors
|
||
|
|
-----------------
|
||
|
|
|
||
|
|
In case of errors, we print everything no matter what.
|
||
|
|
|
||
|
|
$ cat > dune <<EOF
|
||
|
|
> (rule
|
||
|
|
> (alias default)
|
||
|
|
> (action (system "echo 'Hello, world!'; exit 1")))
|
||
|
|
> EOF
|
||
|
|
|
||
|
|
$ dune build
|
||
|
|
File "dune", lines 1-3, characters 0-73:
|
||
|
|
1 | (rule
|
||
|
|
2 | (alias default)
|
||
|
|
3 | (action (system "echo 'Hello, world!'; exit 1")))
|
||
|
|
Hello, world!
|
||
|
|
[1]
|
||
|
|
|
||
|
|
$ dune clean
|
||
|
|
$ dune build --action-stdout=swallow
|
||
|
|
File "dune", lines 1-3, characters 0-73:
|
||
|
|
1 | (rule
|
||
|
|
2 | (alias default)
|
||
|
|
3 | (action (system "echo 'Hello, world!'; exit 1")))
|
||
|
|
Hello, world!
|
||
|
|
[1]
|
||
|
|
|
||
|
|
$ dune clean
|
||
|
|
$ dune build --action-stdout=must-be-empty
|
||
|
|
File "dune", lines 1-3, characters 0-73:
|
||
|
|
1 | (rule
|
||
|
|
2 | (alias default)
|
||
|
|
3 | (action (system "echo 'Hello, world!'; exit 1")))
|
||
|
|
Hello, world!
|
||
|
|
[1]
|
||
|
|
|
||
|
|
With compound actions
|
||
|
|
---------------------
|
||
|
|
|
||
|
|
At the moment, the behavior is a bit odd. We swallow the stdout of the
|
||
|
|
first command but not the second:
|
||
|
|
|
||
|
|
$ cat > dune <<EOF
|
||
|
|
> (rule
|
||
|
|
> (alias default)
|
||
|
|
> (action
|
||
|
|
> (progn
|
||
|
|
> (system "echo 1")
|
||
|
|
> (system "echo 2; exit 1"))))
|
||
|
|
> EOF
|
||
|
|
|
||
|
|
$ dune build --action-stdout-on-success=swallow
|
||
|
|
File "dune", lines 1-6, characters 0-93:
|
||
|
|
1 | (rule
|
||
|
|
2 | (alias default)
|
||
|
|
3 | (action
|
||
|
|
4 | (progn
|
||
|
|
5 | (system "echo 1")
|
||
|
|
6 | (system "echo 2; exit 1"))))
|
||
|
|
2
|
||
|
|
[1]
|
||
|
|
|
||
|
|
For must-be-empty, if two programs print something without failing we
|
||
|
|
stop at the first program. That's not terrible, but it would seem
|
||
|
|
better if we stop at the end of the whole action.
|
||
|
|
|
||
|
|
$ cat > dune <<EOF
|
||
|
|
> (rule
|
||
|
|
> (alias default)
|
||
|
|
> (action
|
||
|
|
> (progn
|
||
|
|
> (system "echo 1")
|
||
|
|
> (system "echo 2"))))
|
||
|
|
> EOF
|
||
|
|
|
||
|
|
$ dune build --action-stdout-on-success=must-be-empty
|
||
|
|
File "dune", lines 1-6, characters 0-85:
|
||
|
|
1 | (rule
|
||
|
|
2 | (alias default)
|
||
|
|
3 | (action
|
||
|
|
4 | (progn
|
||
|
|
5 | (system "echo 1")
|
||
|
|
6 | (system "echo 2"))))
|
||
|
|
1
|
||
|
|
[1]
|
||
|
|
|
||
|
|
With builtin actions
|
||
|
|
--------------------
|
||
|
|
|
||
|
|
We currently never swallow the output of builtin actions such as
|
||
|
|
`echo`, which is odd:
|
||
|
|
|
||
|
|
$ cat > dune <<EOF
|
||
|
|
> (rule
|
||
|
|
> (alias default)
|
||
|
|
> (action (echo "Hello, world!\n")))
|
||
|
|
> EOF
|
||
|
|
|
||
|
|
$ dune build --action-stdout-on-success=swallow
|
||
|
|
Hello, world!
|