From 5d674c44a42d03b4bee5223a7eb761ba5d596625 Mon Sep 17 00:00:00 2001 From: Stephen Sherratt Date: Thu, 5 Sep 2024 12:28:57 +1000 Subject: [PATCH] Add command to build and run ocamllsp This command will exit with an error message unless it's run within a dune project with a dune.lock directory containing a lockfile for the package "ocaml" so it's not ready for use by editors. Support for falling back to a system or opam-managed installation of ocamllsp will come in a later change. Signed-off-by: Stephen Sherratt --- bin/lock_dev_tool.ml | 1 + bin/lock_dev_tool.mli | 1 + bin/main.ml | 1 + bin/tools/ocamllsp.ml | 62 ++++++++++++++++++++++++++++++++++++ bin/tools/ocamllsp.mli | 4 +++ bin/tools/tools.ml | 11 +++++++ bin/tools/tools.mli | 3 ++ src/dune_rules/dune_rules.ml | 2 ++ 8 files changed, 85 insertions(+) create mode 100644 bin/tools/ocamllsp.ml create mode 100644 bin/tools/ocamllsp.mli create mode 100644 bin/tools/tools.ml create mode 100644 bin/tools/tools.mli diff --git a/bin/lock_dev_tool.ml b/bin/lock_dev_tool.ml index 1bfc6593983..7aa04163df9 100644 --- a/bin/lock_dev_tool.ml +++ b/bin/lock_dev_tool.ml @@ -208,3 +208,4 @@ let lock_ocamlformat () = ;; let lock_odoc () = lock_dev_tool Odoc None +let lock_ocamllsp () = lock_dev_tool Ocamllsp None diff --git a/bin/lock_dev_tool.mli b/bin/lock_dev_tool.mli index 82b4f41e665..eb4309e7960 100644 --- a/bin/lock_dev_tool.mli +++ b/bin/lock_dev_tool.mli @@ -3,3 +3,4 @@ open! Import val is_enabled : bool Lazy.t val lock_ocamlformat : unit -> unit Memo.t val lock_odoc : unit -> unit Memo.t +val lock_ocamllsp : unit -> unit Memo.t diff --git a/bin/main.ml b/bin/main.ml index 61ca4904449..96bd2b6c8bc 100644 --- a/bin/main.ml +++ b/bin/main.ml @@ -39,6 +39,7 @@ let all : _ Cmdliner.Cmd.t list = ; Promotion.group ; Pkg.group ; Pkg.Alias.group + ; Tools.group ] in terms @ groups diff --git a/bin/tools/ocamllsp.ml b/bin/tools/ocamllsp.ml new file mode 100644 index 00000000000..8f3ca407d43 --- /dev/null +++ b/bin/tools/ocamllsp.ml @@ -0,0 +1,62 @@ +open! Import +module Pkg_dev_tool = Dune_rules.Pkg_dev_tool + +let ocamllsp_exe_path = Path.build @@ Pkg_dev_tool.exe_path Ocamllsp +let ocamllsp_exe_name = Pkg_dev_tool.exe_name Ocamllsp + +(* Replace the current dune process with ocamllsp. *) +let run_ocamllsp common ~args = + let exe_path_string = Path.to_string ocamllsp_exe_path in + Console.print_user_message + (Dune_rules.Pkg_build_progress.format_user_message + ~verb:"Running" + ~object_: + (User_message.command (String.concat ~sep:" " (ocamllsp_exe_name :: args)))); + Console.finish (); + restore_cwd_and_execve common exe_path_string (exe_path_string :: args) Env.initial +;; + +let build_ocamllsp common = + let open Fiber.O in + let+ result = + Build_cmd.run_build_system ~common ~request:(fun _build_system -> + Action_builder.path ocamllsp_exe_path) + in + match result with + | Error `Already_reported -> raise Dune_util.Report_error.Already_reported + | Ok () -> () +;; + +let is_in_dune_project builder = + Workspace_root.create + ~default_is_cwd:(Common.Builder.default_root_is_cwd builder) + ~specified_by_user:(Common.Builder.root builder) + |> Result.is_ok +;; + +let term = + let+ builder = Common.Builder.term + and+ args = Arg.(value & pos_all string [] (info [] ~docv:"ARGS")) in + match is_in_dune_project builder with + | false -> + User_error.raise + [ Pp.textf + "Unable to run %s as a dev-tool because you don't appear to be inside a dune \ + project." + ocamllsp_exe_name + ] + | true -> + let common, config = Common.init builder in + Scheduler.go ~common ~config (fun () -> + let open Fiber.O in + let* () = Lock_dev_tool.lock_ocamllsp () |> Memo.run in + let+ () = build_ocamllsp common in + run_ocamllsp common ~args) +;; + +let info = + let doc = "Run ocamllsp, installing it as a dev tool if necessary." in + Cmd.info "ocamllsp" ~doc +;; + +let command = Cmd.v info term diff --git a/bin/tools/ocamllsp.mli b/bin/tools/ocamllsp.mli new file mode 100644 index 00000000000..ad07b0fd314 --- /dev/null +++ b/bin/tools/ocamllsp.mli @@ -0,0 +1,4 @@ +open! Import + +(** Command to run ocamllsp, installing it if necessary *) +val command : unit Cmd.t diff --git a/bin/tools/tools.ml b/bin/tools/tools.ml new file mode 100644 index 00000000000..dd399f81b5b --- /dev/null +++ b/bin/tools/tools.ml @@ -0,0 +1,11 @@ +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 ] +end + +let doc = "Command group for wrapped tools." +let info = Cmd.info ~doc "tools" +let group = Cmd.group info [ Exec.group ] diff --git a/bin/tools/tools.mli b/bin/tools/tools.mli new file mode 100644 index 00000000000..d4c5902fcd6 --- /dev/null +++ b/bin/tools/tools.mli @@ -0,0 +1,3 @@ +open Import + +val group : unit Cmd.t diff --git a/src/dune_rules/dune_rules.ml b/src/dune_rules/dune_rules.ml index 9c71a562ff8..8ea18a09c52 100644 --- a/src/dune_rules/dune_rules.ml +++ b/src/dune_rules/dune_rules.ml @@ -70,6 +70,8 @@ module Executables = Executables module Tests = Tests module Stanzas = Stanzas module Lock_dir = Lock_dir +module Pkg_dev_tool = Pkg_dev_tool +module Pkg_build_progress = Pkg_build_progress module Install_rules = struct let install_file = Install_rules.install_file