Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions doc/changes/added/13083.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Add a `shell` field to the cram stanza. This field allows customizing the
shell to be `bash` rather than `sh` (#13083, @haochenx)
7 changes: 7 additions & 0 deletions doc/reference/dune/cram.rst
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,10 @@ Cram
in this field. The order of evaluation for these scripts is deterministic
but is left undefined, so it is not recommended that these scripts have
side effects.

.. describe:: (shell <sh|bash>)

.. versionadded:: 3.22

Determines the shell executable to use to execute the cram script. By
default, cram scripts will execute with ``sh``.
66 changes: 55 additions & 11 deletions src/dune_rules/cram/cram_exec.ml
Original file line number Diff line number Diff line change
Expand Up @@ -432,14 +432,30 @@ let make_temp_dir ~script =
temp_dir
;;

let run_cram_test env ~src ~script ~cram_stanzas ~temp_dir ~cwd ~timeout ~setup_scripts =
let run_cram_test
env
~src
~script
~cram_stanzas
~temp_dir
~cwd
~timeout
~setup_scripts
(shell : Cram_stanza.Shell.t)
=
let open Fiber.O in
let* sh_script = create_sh_script cram_stanzas ~temp_dir ~setup_scripts in
let env = make_run_env env ~temp_dir ~cwd in
let open Fiber.O in
let sh =
let path = Env_path.path Env.initial in
match Bin.which ~path "sh" with
match
Bin.which
~path
(match shell with
| Sh -> "sh"
| Bash -> "bash")
with
| Some sh -> sh
| None ->
User_error.raise [ Pp.text "CRAM test aborted, \"sh\" can not be found in PATH" ]
Expand Down Expand Up @@ -509,14 +525,24 @@ let run_produce_correction
~script
~timeout
~setup_scripts
shell
lexbuf
=
let temp_dir = make_temp_dir ~script in
let cram_stanzas = cram_stanzas lexbuf ~conflict_markers |> List.map ~f:snd in
let cwd = Path.parent_exn script in
let env = make_run_env env ~temp_dir ~cwd in
let open Fiber.O in
run_cram_test env ~src ~script ~cram_stanzas ~temp_dir ~cwd ~timeout ~setup_scripts
run_cram_test
env
~src
~script
~cram_stanzas
~temp_dir
~cwd
~timeout
~setup_scripts
shell
>>| compose_cram_output
;;

Expand All @@ -538,6 +564,7 @@ let run_and_produce_output
~dst
~timeout
~setup_scripts
shell
=
let script_contents = Io.read_file ~binary:false script in
let lexbuf = Lexbuf.from_string script_contents ~fname:(Path.to_string script) in
Expand All @@ -548,7 +575,16 @@ let run_and_produce_output
let env = make_run_env env ~temp_dir ~cwd in
let open Fiber.O in
let+ commands =
run_cram_test env ~src ~script ~cram_stanzas ~temp_dir ~cwd ~timeout ~setup_scripts
run_cram_test
env
~src
~script
~cram_stanzas
~temp_dir
~cwd
~timeout
~setup_scripts
shell
>>| List.filter_map ~f:(function
| Cram_lexer.Command c -> Some c
| Comment _ -> None)
Expand All @@ -567,12 +603,17 @@ module Run = struct
; output : 'target
; timeout : (Loc.t * Time.Span.t) option
; setup_scripts : 'path list
; shell : Cram_stanza.Shell.t
}

let name = "cram-run"
let version = 3
let version = 4

let bimap ({ src = _; dir; script; output; timeout; setup_scripts } as t) f g =
let bimap
({ src = _; dir; script; output; timeout; setup_scripts; shell = _ } as t)
f
g
=
{ t with
dir = f dir
; script = f script
Expand All @@ -584,7 +625,7 @@ module Run = struct

let is_useful_to ~memoize:_ = true

let encode { src = _; dir; script; output; timeout; setup_scripts } path target
let encode { src = _; dir; script; output; timeout; shell; setup_scripts } path target
: Sexp.t
=
List
Expand All @@ -595,11 +636,12 @@ module Run = struct
option float (Option.map ~f:(fun (_, time) -> Time.Span.to_secs time) timeout))
|> Dune_sexp.to_sexp
; List (List.map ~f:path setup_scripts)
; Atom (Cram_stanza.Shell.to_string shell)
]
;;

let action
{ src; dir; script; output; timeout; setup_scripts }
{ src; dir; script; output; timeout; setup_scripts; shell }
~ectx:_
~(eenv : Action.env)
=
Expand All @@ -612,14 +654,15 @@ module Run = struct
~dst:output
~timeout
~setup_scripts
shell
;;
end

include Action_ext.Make (Spec)
end

let run ~src ~dir ~script ~output ~timeout ~setup_scripts =
Run.action { src; dir; script; output; timeout; setup_scripts }
let run ~src ~dir ~script ~output ~timeout ~setup_scripts shell =
Run.action { src; dir; script; output; timeout; setup_scripts; shell }
;;

module Make_script = struct
Expand Down Expand Up @@ -743,7 +786,8 @@ module Action = struct
~env:eenv.env
~script
~timeout:None
~setup_scripts:[])
~setup_scripts:[]
Sh)
;;
end

Expand Down
1 change: 1 addition & 0 deletions src/dune_rules/cram/cram_exec.mli
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ val run
-> output:Path.Build.t
-> timeout:(Loc.t * Time.Span.t) option
-> setup_scripts:Path.t list
-> Cram_stanza.Shell.t
-> Action.t

(** Produces a diff if [src] needs to be updated *)
Expand Down
6 changes: 6 additions & 0 deletions src/dune_rules/cram/cram_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Spec = struct
; timeout : (Loc.t * Time.Span.t) option
; conflict_markers : Cram_stanza.Conflict_markers.t
; setup_scripts : Path.t list
; shell : Cram_stanza.Shell.t
}

let make_empty ~test_name_alias =
Expand All @@ -28,6 +29,7 @@ module Spec = struct
; timeout = None
; conflict_markers = Ignore
; setup_scripts = []
; shell = Sh
}
;;
end
Expand Down Expand Up @@ -64,6 +66,7 @@ let test_rule
; timeout
; conflict_markers
; setup_scripts
; shell
} :
Spec.t)
(test : (Cram_test.t, error) result)
Expand Down Expand Up @@ -151,6 +154,7 @@ let test_rule
~output
~timeout
~setup_scripts
shell
|> Action.Full.make ~locks ~sandbox)
|> Action_builder.with_file_targets ~file_targets:[ output ]
|> Super_context.add_rule sctx ~dir ~loc
Expand Down Expand Up @@ -302,6 +306,7 @@ let rules ~sctx ~dir tests =
let conflict_markers =
Option.value ~default:acc.conflict_markers stanza.conflict_markers
in
let shell = Option.value ~default:acc.shell stanza.shell in
let setup_scripts =
let more_current_scripts =
List.map stanza.setup_scripts ~f:(fun (_loc, script) ->
Expand All @@ -328,6 +333,7 @@ let rules ~sctx ~dir tests =
; timeout
; conflict_markers
; setup_scripts
; shell
} ))
in
let extra_aliases =
Expand Down
19 changes: 19 additions & 0 deletions src/dune_rules/cram/cram_stanza.ml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,21 @@ module Conflict_markers = struct
let decode = enum (List.map all ~f:(fun x -> to_string x, x))
end

module Shell = struct
type t =
| Sh
| Bash

let all = [ "sh", Sh; "bash", Bash ]

let to_string =
let all = List.rev_map all ~f:Tuple.T2.swap in
fun x -> Option.value_exn (List.assoc all x)
;;

let decode = enum all
end

type t =
{ loc : Loc.t
; applies_to : applies_to
Expand All @@ -46,6 +61,7 @@ type t =
; runtest_alias : (Loc.t * bool) option
; timeout : (Loc.t * Time.Span.t) option
; setup_scripts : (Loc.t * string) list
; shell : Shell.t option
}

include Stanza.Make (struct
Expand Down Expand Up @@ -108,6 +124,8 @@ let decode =
(Dune_lang.Syntax.since Stanza.syntax (3, 21) >>> repeat (located string))
in
Option.value scripts ~default:[]
and+ shell =
field_o "shell" (Dune_lang.Syntax.since Stanza.syntax (3, 22) >>> Shell.decode)
in
{ loc
; alias
Expand All @@ -120,5 +138,6 @@ let decode =
; timeout
; conflict_markers
; setup_scripts
; shell
})
;;
9 changes: 9 additions & 0 deletions src/dune_rules/cram/cram_stanza.mli
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@ type applies_to =
| Whole_subtree
| Files_matching_in_this_dir of Predicate_lang.Glob.t

module Shell : sig
type t =
| Sh
| Bash

val to_string : t -> string
end

module Conflict_markers : sig
type t =
| Error
Expand All @@ -24,6 +32,7 @@ type t =
; runtest_alias : (Loc.t * bool) option
; timeout : (Loc.t * Time.Span.t) option
; setup_scripts : (Loc.t * string) list
; shell : Shell.t option
}

val decode : t Dune_lang.Decoder.t
Expand Down
32 changes: 32 additions & 0 deletions test/blackbox-tests/test-cases/cram/bash-shell.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Demonstrate the shell field in the cram stanza

$ cat > dune-project <<EOF
> (lang dune 3.22)
> EOF

$ printShell() {
> dune trace cat | jq '.[] | select(.cat == "process" and (.args.categories | index("cram"))) | .args | .prog | split("/") | last'
> }

$ cat >foo.t <<'EOF'
> $ echo foo
> EOF

$ dune runtest foo.t
File "foo.t", line 1, characters 0-0:
Error: Files _build/default/foo.t and _build/default/foo.t.corrected differ.
[1]
$ printShell
"sh"

$ cat > dune <<EOF
> (cram
> (shell bash))
> EOF

$ dune runtest foo.t
File "foo.t", line 1, characters 0-0:
Error: Files _build/default/foo.t and _build/default/foo.t.corrected differ.
[1]
$ printShell
"bash"
Loading