diff --git a/bin/tools/ocamlformat.ml b/bin/tools/ocamlformat.ml new file mode 100644 index 00000000000..139ecac43a7 --- /dev/null +++ b/bin/tools/ocamlformat.ml @@ -0,0 +1,61 @@ +open! Import +module Pkg_dev_tool = Dune_rules.Pkg_dev_tool + +let exe_path = Path.build @@ Pkg_dev_tool.exe_path Ocamlformat +let exe_name = Pkg_dev_tool.exe_name Ocamlformat + +let run_dev_tool workspace_root ~args = + let exe_path_string = Path.to_string exe_path in + Console.print_user_message + (Dune_rules.Pkg_build_progress.format_user_message + ~verb:"Running" + ~object_:(User_message.command (String.concat ~sep:" " (exe_name :: args)))); + Console.finish (); + restore_cwd_and_execve + workspace_root + exe_path_string + (exe_path_string :: args) + Env.initial +;; + +let dev_tool_exe_exists () = Path.exists exe_path + +let build_dev_tool common = + match dev_tool_exe_exists () with + | true -> + (* Avoid running the build system if the executable already exists + to reduce unnecessary latency in the common case. *) + Fiber.return () + | false -> + let open Fiber.O in + let+ result = + Build_cmd.run_build_system ~common ~request:(fun _build_system -> + Action_builder.path exe_path) + in + (match result with + | Error `Already_reported -> raise Dune_util.Report_error.Already_reported + | Ok () -> ()) +;; + +let term = + let+ builder = Common.Builder.term + and+ args = Arg.(value & pos_all string [] (info [] ~docv:"ARGS")) in + let common, config = Common.init builder in + Scheduler.go ~common ~config (fun () -> + let open Fiber.O in + let* () = Lock_dev_tool.lock_ocamlformat () |> Memo.run in + let+ () = build_dev_tool common in + run_dev_tool (Common.root common) ~args) +;; + +let info = + let doc = + {|Wrapper for running ocamlformat intended to be run automatically + by a text editor. All positional arguments will be passed to the + ocamlformat executable (pass flags to ocamlformat after the '--' + argument, such as 'dune ocamlformat -- --help').|} + in + Cmd.info "ocamlformat" ~doc +;; + +let command = Cmd.v info term diff --git a/bin/tools/ocamlformat.mli b/bin/tools/ocamlformat.mli new file mode 100644 index 00000000000..5505206a171 --- /dev/null +++ b/bin/tools/ocamlformat.mli @@ -0,0 +1,3 @@ +open! Import + +val command : unit Cmd.t diff --git a/bin/tools/tools.ml b/bin/tools/tools.ml index dd399f81b5b..9af01e2b9b1 100644 --- a/bin/tools/tools.ml +++ b/bin/tools/tools.ml @@ -3,7 +3,7 @@ open! Import module Exec = struct let doc = "Command group for running wrapped tools." let info = Cmd.info ~doc "exec" - let group = Cmd.group info [ Ocamllsp.command ] + let group = Cmd.group info [ Ocamlformat.command; Ocamllsp.command ] end let doc = "Command group for wrapped tools." diff --git a/test/blackbox-tests/test-cases/pkg/ocamlformat/ocamlformat-wrapper.t b/test/blackbox-tests/test-cases/pkg/ocamlformat/ocamlformat-wrapper.t new file mode 100644 index 00000000000..0d3b459aff4 --- /dev/null +++ b/test/blackbox-tests/test-cases/pkg/ocamlformat/ocamlformat-wrapper.t @@ -0,0 +1,14 @@ +Exercise running the ocamlformat wrapper command. + + $ . ./helpers.sh + $ mkrepo + + $ make_fake_ocamlformat "0.26.2" + $ make_ocamlformat_opam_pkg "0.26.2" + $ make_project_with_dev_tool_lockdir + + $ dune tools exec ocamlformat + Solution for dev-tools.locks/ocamlformat: + - ocamlformat.0.26.2 + Running 'ocamlformat' + formatted with version 0.26.2