Skip to content

Commit 12fdacb

Browse files
authored
Merge pull request #3027 from voodoos/finer-with-accepted-exit-code-restrictions
Finer with-accepted-exit-code restrictions
2 parents 80b7c8c + 424e13f commit 12fdacb

File tree

6 files changed

+219
-11
lines changed

6 files changed

+219
-11
lines changed

CHANGES.md

+5-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@
1212
@fangyi-zhou and @diml)
1313

1414
- Hint when trying to execute an executable defined in the current directory
15-
without using the `./` prefix (#3041).
15+
without using the `./` prefix (#3041, fixes #1094, @voodoos).
16+
17+
- Extend the list of modifiers that can be nested under
18+
`with-accepted-exit-codes` with `chdir`, `setenv`, `ignore-<outputs>`,
19+
`with-stdin-from` and `with-<outputs>-to` (#3027, fixes #3014, @voodoos)
1620

1721
- It is now an error to have a preprocessing dependency on a ppx rewriter
1822
library that is not marked as `(kind ppx_rewriter)` (#3039, @snowleopard).

doc/concepts.rst

+4-2
Original file line numberDiff line numberDiff line change
@@ -651,8 +651,10 @@ The following constructions are available:
651651
- ``(with-stdin-from <file> <DSL>)`` to redirect the input from a file
652652
- ``(with-accepted-exit-codes <pred> <DSL>)`` specifies the list of expected exit codes
653653
for the programs executed in ``<DSL>``. ``<pred>`` is a predicate on integer
654-
values, and is specified using the :ref:`predicate-lang`. ``<DSL>`` must be
655-
one of ``run``, ``bash`` or ``system``. This action is available since dune 2.0.
654+
values, and is specified using the :ref:`predicate-lang`. ``<DSL>`` can only
655+
contain nested occurences of ``run``, ``bash``, ``system``, ``chdir``,
656+
``setenv``, ``ignore-<outputs>``, ``with-stdin-from`` and
657+
``with-<outputs>-to``. This action is available since dune 2.0.
656658
- ``(progn <DSL>...)`` to execute several commands in sequence
657659
- ``(echo <string>)`` to output a string on stdout
658660
- ``(write-file <file> <string>)`` writes ``<string>`` to ``<file>``

src/dune/action_ast.ml

+51-8
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,60 @@ struct
5858
and+ args = repeat String.decode in
5959
Run (prog, args) )
6060
; ( "with-accepted-exit-codes"
61-
, Dune_lang.Syntax.since Stanza.syntax (2, 0)
61+
, let open Dune_lang in
62+
Syntax.since Stanza.syntax (2, 0)
6263
>>> let+ codes = Predicate_lang.decode_one Dune_lang.Decoder.int
63-
and+ t = located t in
64-
match t with
65-
| _, ((Run _ | Bash _ | System _) as t) ->
66-
With_accepted_exit_codes (codes, t)
67-
| loc, _ ->
64+
and+ version = Syntax.get_exn Stanza.syntax
65+
and+ loc, t = located t in
66+
let nesting_support_version = (2, 2) in
67+
let nesting_support =
68+
Syntax.Version.Infix.(version >= nesting_support_version)
69+
in
70+
let rec is_ok = function
71+
| Run _
72+
| Bash _
73+
| System _ ->
74+
true
75+
| Chdir (_, t)
76+
| Setenv (_, _, t)
77+
| Ignore (_, t)
78+
| Redirect_in (_, _, t)
79+
| Redirect_out (_, _, t) ->
80+
if nesting_support then
81+
is_ok t
82+
else
83+
Syntax.Error.since loc Stanza.syntax
84+
nesting_support_version
85+
~what:
86+
"nesting modifiers under 'with-accepted-exit-codes'"
87+
| _ -> false
88+
in
89+
let quote = List.map ~f:(Printf.sprintf "\"%s\"") in
90+
match (is_ok t, nesting_support) with
91+
| true, _ -> With_accepted_exit_codes (codes, t)
92+
| false, true ->
93+
User_error.raise ~loc
94+
[ Pp.textf
95+
"Only %s can be nested under \
96+
\"with-accepted-exit-codes\""
97+
(Stdune.String.enumerate_and
98+
(quote
99+
[ "run"
100+
; "bash"
101+
; "system"
102+
; "chdir"
103+
; "setenv"
104+
; "ignore-<outputs>"
105+
; "with-stdin-from"
106+
; "with-<outputs>-to"
107+
]))
108+
]
109+
| false, false ->
68110
User_error.raise ~loc
69111
[ Pp.textf
70-
"with-accepted-exit-codes can only be used with \
71-
\"run\", \"bash\" or \"system\""
112+
"with-accepted-exit-codes can only be used with %s"
113+
(Stdune.String.enumerate_or
114+
(quote [ "run"; "bash"; "system" ]))
72115
] )
73116
; ( "dynamic-run"
74117
, Dune_lang.Syntax.since Action_plugin.syntax (0, 1)

test/blackbox-tests/dune.inc

+22
Original file line numberDiff line numberDiff line change
@@ -2050,6 +2050,14 @@
20502050
test-cases/with-exit-codes
20512051
(progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))
20522052

2053+
(rule
2054+
(alias with-nested-exit-codes)
2055+
(deps (package dune) (source_tree test-cases/with-nested-exit-codes))
2056+
(action
2057+
(chdir
2058+
test-cases/with-nested-exit-codes
2059+
(progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))
2060+
20532061
(rule
20542062
(alias with-stdin-from)
20552063
(deps (package dune) (source_tree test-cases/with-stdin-from))
@@ -2058,6 +2066,16 @@
20582066
test-cases/with-stdin-from
20592067
(progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))
20602068

2069+
(rule
2070+
(alias with-unsupported-nested-exit-codes)
2071+
(deps
2072+
(package dune)
2073+
(source_tree test-cases/with-unsupported-nested-exit-codes))
2074+
(action
2075+
(chdir
2076+
test-cases/with-unsupported-nested-exit-codes
2077+
(progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected)))))
2078+
20612079
(rule
20622080
(alias workspace-paths)
20632081
(deps (package dune) (source_tree test-cases/workspace-paths))
@@ -2337,7 +2355,9 @@
23372355
(alias virtual-libraries-vlib-wrong-default-impl)
23382356
(alias windows-diff)
23392357
(alias with-exit-codes)
2358+
(alias with-nested-exit-codes)
23402359
(alias with-stdin-from)
2360+
(alias with-unsupported-nested-exit-codes)
23412361
(alias workspace-paths)
23422362
(alias workspaces)
23432363
(alias wrapped-false-main-module-name)
@@ -2558,7 +2578,9 @@
25582578
(alias virtual-libraries-vlib-wrong-default-impl)
25592579
(alias windows-diff)
25602580
(alias with-exit-codes)
2581+
(alias with-nested-exit-codes)
25612582
(alias with-stdin-from)
2583+
(alias with-unsupported-nested-exit-codes)
25622584
(alias workspace-paths)
25632585
(alias workspaces)
25642586
(alias wrapped-false-main-module-name)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
$ cat > dune-project << EOF
2+
> (lang dune 2.2)
3+
> (using action-plugin 0.1)
4+
> EOF
5+
6+
$ cat > dune <<EOF
7+
> (executable
8+
> (name exit)
9+
> (modules exit))
10+
> (rule (with-stdout-to exit.ml (echo "let () = exit (int_of_string Sys.argv.(1))")))
11+
> EOF
12+
13+
$ cat >> dune <<EOF
14+
> (rule
15+
> (alias f)
16+
> (action (with-accepted-exit-codes
17+
> 1
18+
> (with-stdout-to out.txt
19+
> (run ./exit.exe 1)))))
20+
> EOF
21+
22+
$ dune build --display=short --root . @f
23+
ocamldep .exit.eobjs/exit.ml.d
24+
ocamlc .exit.eobjs/byte/dune__exe__Exit.{cmi,cmo,cmt}
25+
ocamlopt .exit.eobjs/native/dune__exe__Exit.{cmx,o}
26+
ocamlopt exit.exe
27+
exit out.txt
28+
29+
$ cat >> dune <<EOF
30+
> (rule
31+
> (alias f2)
32+
> (action (with-accepted-exit-codes
33+
> 1
34+
> (with-stdin-from input
35+
> (chdir .
36+
> (run ./exit.exe 1))))))
37+
> EOF
38+
39+
$ echo "Hello, Dune!" > input
40+
$ dune build --display=short --root . @f2
41+
exit alias f2
42+
43+
$ cat >> dune <<EOF
44+
> (rule
45+
> (alias f3)
46+
> (action (with-accepted-exit-codes
47+
> 0
48+
> (setenv VAR myvar
49+
> (chdir .
50+
> (system "echo \$VAR"))))))
51+
> EOF
52+
53+
$ dune build --display=short --root . @f3
54+
sh alias f3
55+
myvar
56+
57+
$ cat >> dune <<EOF
58+
> (rule
59+
> (alias f4)
60+
> (action (with-accepted-exit-codes
61+
> 0
62+
> (setenv VAR myvar
63+
> (ignore-stdout
64+
> (bash "echo \$VAR"))))))
65+
> EOF
66+
67+
$ dune build --display=short --root . @f4
68+
bash alias f4
69+
70+
$ cat >> dune <<EOF
71+
> (rule
72+
> (alias f5)
73+
> (action (with-accepted-exit-codes
74+
> 0
75+
> (setenv VAR myvar
76+
> (with-stdin-from input
77+
> (chdir .
78+
> (with-stdout-to out2.txt
79+
> (run ./exit.exe 1))))))))
80+
> EOF
81+
$ echo "Hello, Dune!" > input
82+
$ dune build --display=short --root . @f5
83+
exit out2.txt (exit 1)
84+
(cd _build/default && ./exit.exe 1) < _build/default/input > _build/default/out2.txt
85+
[1]
86+
87+
$ cat >> dune <<EOF
88+
> (rule
89+
> (alias g)
90+
> (action
91+
> (with-accepted-exit-codes
92+
> (not 0)
93+
> (setenv VAR myvar
94+
> (chdir .
95+
> (with-stdout-to out.txt
96+
> (dynamic-run ./exit.exe 1)))))))
97+
> EOF
98+
99+
$ dune build --display=short --root . @g
100+
File "dune", line 46, characters 3-98:
101+
46 | (setenv VAR myvar
102+
47 | (chdir .
103+
48 | (with-stdout-to out.txt
104+
49 | (dynamic-run ./exit.exe 1)))))))
105+
Error: Only "run", "bash", "system", "chdir", "setenv", "ignore-<outputs>",
106+
"with-stdin-from" and "with-<outputs>-to" can be nested under
107+
"with-accepted-exit-codes"
108+
[1]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
$ cat > dune-project << EOF
2+
> (lang dune 2.0)
3+
> (using action-plugin 0.1)
4+
> EOF
5+
6+
$ cat > dune <<EOF
7+
> (executable
8+
> (name exit)
9+
> (modules exit))
10+
> (rule (with-stdout-to exit.ml (echo "let () = exit (int_of_string Sys.argv.(1))")))
11+
> EOF
12+
13+
$ cat >> dune <<EOF
14+
> (rule
15+
> (alias a)
16+
> (action (with-accepted-exit-codes
17+
> 1
18+
> (with-stdout-to out.txt
19+
> (run ./exit.exe 1)))))
20+
> EOF
21+
22+
$ dune build --display=short --root . @a
23+
File "dune", line 9, characters 10-64:
24+
9 | (with-stdout-to out.txt
25+
10 | (run ./exit.exe 1)))))
26+
Error: nesting modifiers under 'with-accepted-exit-codes' is only available
27+
since version 2.2 of the dune language. Please update your dune-project file
28+
to have (lang 2.2).
29+
[1]

0 commit comments

Comments
 (0)