From d12379f5a54c48076ad8bf287f9101e9361b2bc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Boillot?= Date: Thu, 22 Jun 2023 14:08:21 +0200 Subject: [PATCH 1/3] fix(ocamllsp): fix in pp handling the file permissions --- CHANGES.md | 6 ++++++ ocaml-lsp-server/src/ocaml_lsp_server.ml | 9 +++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 8b8a33965..d369e6e84 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,9 @@ +# Unreleased + +## Fixes + +- Fix file permissions used when specifying output files of pp and ppx. (#1153) + # 1.16.1 ## Fixes diff --git a/ocaml-lsp-server/src/ocaml_lsp_server.ml b/ocaml-lsp-server/src/ocaml_lsp_server.ml index 790792020..129eeae6c 100644 --- a/ocaml-lsp-server/src/ocaml_lsp_server.ml +++ b/ocaml-lsp-server/src/ocaml_lsp_server.ml @@ -878,12 +878,13 @@ let run_in_directory ~prog ~prog_is_quoted:_ ~args ~cwd ?stdin ?stdout ?stderr let argv = [ "sh"; "-c"; cmd ] in let stdin = match stdin with - | Some file -> Unix.openfile file [ Unix.O_WRONLY ] 0x664 - | None -> Unix.openfile "/dev/null" [ Unix.O_RDONLY ] 0x777 + | Some file -> Unix.openfile file [ Unix.O_WRONLY ] 0o664 + | None -> Unix.openfile "/dev/null" [ Unix.O_RDONLY ] 0o777 in let stdout, should_close_stdout = match stdout with - | Some file -> (Unix.openfile file [ Unix.O_WRONLY ] 0x664, true) + | Some file -> + (Unix.openfile file [ Unix.O_WRONLY; Unix.O_CREAT ] 0o664, true) | None -> (* Runned programs should never output to stdout since it is the channel used by LSP to communicate with the editor *) @@ -891,7 +892,7 @@ let run_in_directory ~prog ~prog_is_quoted:_ ~args ~cwd ?stdin ?stdout ?stderr in let stderr = Option.map stderr ~f:(fun file -> - Unix.openfile file [ Unix.O_WRONLY ] 0x664) + Unix.openfile file [ Unix.O_WRONLY; Unix.O_CREAT ] 0o664) in let pid = let cwd : Spawn.Working_dir.t = Path cwd in From 37bc499507bf54ca63c20de510f2dc101b8c5db7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Boillot?= Date: Thu, 22 Jun 2023 15:17:30 +0200 Subject: [PATCH 2/3] change flag of input file from write-only to read-only --- ocaml-lsp-server/src/ocaml_lsp_server.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ocaml-lsp-server/src/ocaml_lsp_server.ml b/ocaml-lsp-server/src/ocaml_lsp_server.ml index 129eeae6c..73fc8a4de 100644 --- a/ocaml-lsp-server/src/ocaml_lsp_server.ml +++ b/ocaml-lsp-server/src/ocaml_lsp_server.ml @@ -878,7 +878,7 @@ let run_in_directory ~prog ~prog_is_quoted:_ ~args ~cwd ?stdin ?stdout ?stderr let argv = [ "sh"; "-c"; cmd ] in let stdin = match stdin with - | Some file -> Unix.openfile file [ Unix.O_WRONLY ] 0o664 + | Some file -> Unix.openfile file [ Unix.O_RDONLY ] 0o664 | None -> Unix.openfile "/dev/null" [ Unix.O_RDONLY ] 0o777 in let stdout, should_close_stdout = From d494f4d3bf207c0171b9b41b280107a0a7cfe5f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulysse=20G=C3=A9rard?= Date: Thu, 22 Jun 2023 17:23:13 +0200 Subject: [PATCH 3/3] Add a test for preprocessing --- ocaml-lsp-server/test/e2e-new/dune | 22 +++++++- ocaml-lsp-server/test/e2e-new/for_pp.ml | 1 + ocaml-lsp-server/test/e2e-new/for_pp.sh | 2 + ocaml-lsp-server/test/e2e-new/with_pp.ml | 71 ++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 ocaml-lsp-server/test/e2e-new/for_pp.ml create mode 100755 ocaml-lsp-server/test/e2e-new/for_pp.sh create mode 100644 ocaml-lsp-server/test/e2e-new/with_pp.ml diff --git a/ocaml-lsp-server/test/e2e-new/dune b/ocaml-lsp-server/test/e2e-new/dune index 4f5b7d6dd..130fa8a30 100644 --- a/ocaml-lsp-server/test/e2e-new/dune +++ b/ocaml-lsp-server/test/e2e-new/dune @@ -12,6 +12,7 @@ (deps %{bin:ocamlformat-rpc} for_ppx.ml + for_pp.ml (package ocaml-lsp-server))) (libraries stdune @@ -32,4 +33,23 @@ ppx_expect.config_types ppx_inline_test.config) (preprocess - (pps ppx_expect))) + (per_module + ((action + (run %{dep:for_pp.sh} %{input-file})) + for_pp) + ((pps ppx_expect) + action_extract + action_inline + code_actions + document_flow + for_ppx + hover_extended + metrics + semantic_hl_data + semantic_hl_helpers + semantic_hl_tests + start_stop + test + with_pp + with_ppx + workspace_change_config)))) diff --git a/ocaml-lsp-server/test/e2e-new/for_pp.ml b/ocaml-lsp-server/test/e2e-new/for_pp.ml new file mode 100644 index 000000000..dbc0f819e --- /dev/null +++ b/ocaml-lsp-server/test/e2e-new/for_pp.ml @@ -0,0 +1 @@ +type world diff --git a/ocaml-lsp-server/test/e2e-new/for_pp.sh b/ocaml-lsp-server/test/e2e-new/for_pp.sh new file mode 100755 index 000000000..62e26a1ef --- /dev/null +++ b/ocaml-lsp-server/test/e2e-new/for_pp.sh @@ -0,0 +1,2 @@ +#!/bin/sh +sed 's/world/universe/g' $1 diff --git a/ocaml-lsp-server/test/e2e-new/with_pp.ml b/ocaml-lsp-server/test/e2e-new/with_pp.ml new file mode 100644 index 000000000..e6b4b19fe --- /dev/null +++ b/ocaml-lsp-server/test/e2e-new/with_pp.ml @@ -0,0 +1,71 @@ +open! Test.Import + +let path = Filename.concat (Sys.getcwd ()) "for_pp.ml" + +let uri = DocumentUri.of_path path + +let print_hover hover = + match hover with + | None -> print_endline "no hover response" + | Some hover -> + hover |> Hover.yojson_of_t + |> Yojson.Safe.pretty_to_string ~std:false + |> print_endline + +let hover_req client position = + Client.request + client + (TextDocumentHover + { HoverParams.position + ; textDocument = TextDocumentIdentifier.create ~uri + ; workDoneToken = None + }) + +let%expect_test "with-pp" = + let position = Position.create ~line:0 ~character:9 in + let handler = + Client.Handler.make + ~on_notification:(fun client _notification -> + Client.state client; + Fiber.return ()) + () + in + let output = + Test.run ~handler @@ fun client -> + let run_client () = + let capabilities = ClientCapabilities.create () in + Client.start client (InitializeParams.create ~capabilities ()) + in + let run () = + let* (_ : InitializeResult.t) = Client.initialized client in + let textDocument = + let text = Io.String_path.read_file path in + TextDocumentItem.create ~uri ~languageId:"ocaml" ~version:0 ~text + in + let* () = + Client.notification + client + (TextDocumentDidOpen (DidOpenTextDocumentParams.create ~textDocument)) + in + let* () = + let+ resp = hover_req client position in + print_hover resp + in + let output = [%expect.output] in + let* () = Client.request client Shutdown in + let+ () = Client.stop client in + output + in + Fiber.fork_and_join_unit run_client run + in + let (_ : string) = [%expect.output] in + print_endline output; + [%expect + {| + { + "contents": { "kind": "plaintext", "value": "type universe" }, + "range": { + "end": { "character": 13, "line": 0 }, + "start": { "character": 0, "line": 0 } + } + }|}]