Skip to content
Open
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
45 changes: 25 additions & 20 deletions src/dune_rules/pkg_rules.ml
Original file line number Diff line number Diff line change
Expand Up @@ -920,27 +920,32 @@ module Action_expander = struct
let dir = t.paths.source_dir in
Memo.return @@ Ok (Path.relative dir program)
| In_path ->
let* artifacts = t.artifacts in
(match Filename.Map.find artifacts program with
| Some s -> Memo.return @@ Ok s
| None ->
(let path = Global.env () |> Env_path.path in
Which.which ~path program)
>>= (function
| Some p -> Memo.return (Ok p)
(match program with
| "dune" ->
let dune = Path.of_string Sys.executable_name in
Memo.return @@ Ok dune
| program ->
let* artifacts = t.artifacts in
(match Filename.Map.find artifacts program with
| Some s -> Memo.return @@ Ok s
| None ->
let+ depexts = filtered_depexts t in
let hint =
Run_with_path.depexts_hint depexts
|> Option.map ~f:(fun pp -> Format.asprintf "%a" Pp.to_fmt pp)
in
Error
(Action.Prog.Not_found.create
?hint
~program
~context:t.context
~loc:(Some loc)
()))))
(let path = Global.env () |> Env_path.path in
Which.which ~path program)
>>= (function
| Some p -> Memo.return (Ok p)
| None ->
let+ depexts = filtered_depexts t in
let hint =
Run_with_path.depexts_hint depexts
|> Option.map ~f:(fun pp -> Format.asprintf "%a" Pp.to_fmt pp)
in
Error
(Action.Prog.Not_found.create
?hint
~program
~context:t.context
~loc:(Some loc)
())))))
in
Result.map prog ~f:(map_exe t)
;;
Expand Down
12 changes: 9 additions & 3 deletions test/blackbox-tests/test-cases/pkg/different-dune-in-path.t
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,18 @@ Remember the digests, to not to have to call nested Dunes:
Call Dune with an absolute PATH as argv[0]:

$ PATH=$fakepath $DUNE build "$pkg_root/$foo_digest/target/"
Fake dune! (args: build -p foo @install)
$ PATH=$fakepath $DUNE build "$pkg_root/$bar_digest/target/"
Fake dune! (args: build -p bar @install)

Make sure that fake dune is not picked up when dune is called with argv[0] = "dune":
argv[0] is set by the calling program (like a shell or cram test runner) and
could be wrong, hence it cannot always be trusted. In the examples above we
launch dune with an absolute path, thus one could just use argv[0] to get the
exact path to the `dune` binary.

To make sure that we pick up the right dune even when argv[0] is being set to
unhelpful values we launch the binary but set the value to a relative value,
namely argv[0] = "dune". This is exactly what happens if `dune` is in the PATH
and the user launches `dune` in a shell.

$ dune clean
$ PATH=$fakepath dune_cmd exec-a "dune" $DUNE build "$pkg_root/$foo_digest/target/"
Fake dune! (args: build -p foo @install)
Loading