Skip to content

Commit 0ba42f1

Browse files
authored
Dev tool which command fails if tool not installed (ocaml#11922)
Previously `dune tool which` would print the path to where a dev tool would be installed, regardless of whether it is currently installed. This is inconsistent with how the `which` unix command works. This commit changes its default behaviour to print an error and exit with non-zero if the specified tool is not installed, allowing the command to be used to check whether a given tool is currently inalled and bring it into line with how `which` commands conventionally behave. The original behaviour is preserved with the `--allow-not-installed` flag. Signed-off-by: Stephen Sherratt <[email protected]>
1 parent 11ac7f4 commit 0ba42f1

File tree

9 files changed

+74
-59
lines changed

9 files changed

+74
-59
lines changed

bin/tools/ocamlformat.ml

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
open! Import
22
module Pkg_dev_tool = Dune_rules.Pkg_dev_tool
33

4-
let exe_path = Path.build @@ Pkg_dev_tool.exe_path Ocamlformat
5-
64
module Exec = struct
75
let term =
86
let+ builder = Common.Builder.term
@@ -23,18 +21,3 @@ module Exec = struct
2321

2422
let command = Cmd.v info term
2523
end
26-
27-
module Which = struct
28-
let term =
29-
let+ builder = Common.Builder.term in
30-
let _ : Common.t * Dune_config_file.Dune_config.t = Common.init builder in
31-
print_endline (Path.to_string exe_path)
32-
;;
33-
34-
let info =
35-
let doc = {|Prints the path to the ocamlformat binary.|} in
36-
Cmd.info "ocamlformat" ~doc
37-
;;
38-
39-
let command = Cmd.v info term
40-
end

bin/tools/ocamlformat.mli

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,3 @@ open! Import
33
module Exec : sig
44
val command : unit Cmd.t
55
end
6-
7-
module Which : sig
8-
val command : unit Cmd.t
9-
end

bin/tools/ocamllsp.ml

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
open! Import
22
module Pkg_dev_tool = Dune_rules.Pkg_dev_tool
33

4-
let ocamllsp_exe_path = Path.build @@ Pkg_dev_tool.exe_path Ocamllsp
54
let ocamllsp_exe_name = Pkg_dev_tool.exe_name Ocamllsp
65

76
let is_in_dune_project builder =
@@ -35,18 +34,3 @@ module Exec = struct
3534

3635
let command = Cmd.v info term
3736
end
38-
39-
module Which = struct
40-
let term =
41-
let+ builder = Common.Builder.term in
42-
let _ : Common.t * Dune_config_file.Dune_config.t = Common.init builder in
43-
print_endline (Path.to_string ocamllsp_exe_path)
44-
;;
45-
46-
let info =
47-
let doc = "Prints the path to the ocamllsp binary." in
48-
Cmd.info "ocamllsp" ~doc
49-
;;
50-
51-
let command = Cmd.v info term
52-
end

bin/tools/ocamllsp.mli

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,3 @@ open! Import
55
module Exec : sig
66
val command : unit Cmd.t
77
end
8-
9-
(** Command to print ocamllsp's path if exists *)
10-
11-
module Which : sig
12-
val command : unit Cmd.t
13-
end

bin/tools/tools.ml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ end
99
module Which = struct
1010
let doc = "Command group for printing the path to wrapped tools."
1111
let info = Cmd.info ~doc "which"
12-
let group = Cmd.group info [ Ocamlformat.Which.command; Ocamllsp.Which.command ]
12+
13+
let group =
14+
Cmd.group info (List.map [ Ocamlformat; Ocamllsp ] ~f:Tools_common.which_command)
15+
;;
1316
end
1417

1518
let doc = "Command group for wrapped tools."

bin/tools/tools_common.ml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,3 +54,37 @@ let lock_build_and_run_dev_tool ~common ~config dev_tool ~args =
5454
lock_and_build_dev_tool ~common ~config dev_tool;
5555
run_dev_tool (Common.root common) dev_tool ~args
5656
;;
57+
58+
let which_command dev_tool =
59+
let exe_path = dev_tool_exe_path dev_tool in
60+
let exe_name = Pkg_dev_tool.exe_name dev_tool in
61+
let term =
62+
let+ builder = Common.Builder.term
63+
and+ allow_not_installed =
64+
Arg.(
65+
value
66+
& flag
67+
& info
68+
[ "allow-not-installed" ]
69+
~doc:
70+
(sprintf
71+
"If %s is not installed as a dev tool, still print where it would be \
72+
installed."
73+
exe_name))
74+
in
75+
let _ : Common.t * Dune_config_file.Dune_config.t = Common.init builder in
76+
if allow_not_installed || Path.exists exe_path
77+
then print_endline (Path.to_string exe_path)
78+
else User_error.raise [ Pp.textf "%s is not installed as a dev tool" exe_name ]
79+
in
80+
let info =
81+
let doc =
82+
sprintf
83+
"Prints the path to the %s dev tool executable if it exists, errors out \
84+
otherwise."
85+
exe_name
86+
in
87+
Cmd.info exe_name ~doc
88+
in
89+
Cmd.v info term
90+
;;

bin/tools/tools_common.mli

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ val lock_build_and_run_dev_tool
99
-> Dune_pkg.Dev_tool.t
1010
-> args:string list
1111
-> 'a
12+
13+
val which_command : Dune_pkg.Dev_tool.t -> unit Cmd.t

test/blackbox-tests/test-cases/pkg/dev-tools-which.t

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
Test `dune tools which ocamlformat`:
2+
$ . ./helpers.sh
3+
$ mkrepo
4+
5+
$ make_fake_ocamlformat "0.26.2"
6+
$ make_ocamlformat_opam_pkg "0.26.2"
7+
$ make_project_with_dev_tool_lockdir
8+
9+
Update ".ocamlformat" file with unknown version of OCamlFormat.
10+
$ cat > .ocamlformat <<EOF
11+
> version = 0.26.2
12+
> EOF
13+
14+
The command will fail because the dev tool is not installed:
15+
$ dune tools which ocamlformat
16+
Error: ocamlformat is not installed as a dev tool
17+
[1]
18+
19+
$ dune tools which ocamlformat --allow-not-installed
20+
_build/_private/default/.dev-tool/ocamlformat/ocamlformat/target/bin/ocamlformat
21+
22+
Install the dev tool:
23+
$ dune tools exec ocamlformat
24+
Solution for dev-tools.locks/ocamlformat:
25+
- ocamlformat.0.26.2
26+
Running 'ocamlformat'
27+
formatted with version 0.26.2
28+
29+
Now the command will succeed because the tool has been installed:
30+
$ dune tools which ocamlformat
31+
_build/_private/default/.dev-tool/ocamlformat/ocamlformat/target/bin/ocamlformat
32+
33+
Make sure the file is actually there:
34+
$ test -f $(dune tools which ocamlformat)

0 commit comments

Comments
 (0)