Skip to content

Commit 57b9964

Browse files
authored
fix: prompt the user to run mix deps.get when dependency problems happen at runtime (#384)
Closes #53
1 parent e32ac2b commit 57b9964

File tree

3 files changed

+84
-3
lines changed

3 files changed

+84
-3
lines changed

lib/next_ls.ex

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,6 +1065,17 @@ defmodule NextLS do
10651065
{:noreply, lsp}
10661066
end
10671067

1068+
def handle_info({ref, {:runtime_failed, _, _} = error}, %{assigns: %{refresh_refs: refs}} = lsp)
1069+
when is_map_key(refs, ref) do
1070+
Process.demonitor(ref, [:flush])
1071+
{{token, msg}, refs} = Map.pop(refs, ref)
1072+
1073+
Progress.stop(lsp, token, msg)
1074+
send(self(), error)
1075+
1076+
{:noreply, assign(lsp, refresh_refs: refs)}
1077+
end
1078+
10681079
def handle_info({ref, _resp}, %{assigns: %{refresh_refs: refs}} = lsp) when is_map_key(refs, ref) do
10691080
Process.demonitor(ref, [:flush])
10701081
{{token, msg}, refs} = Map.pop(refs, ref)

lib/next_ls/runtime.ex

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ defmodule NextLS.Runtime do
303303
diagnostics
304304

305305
{:error, %Mix.Error{message: "Can't continue due to errors on dependencies"}} ->
306-
nil
306+
{:runtime_failed, state.name, {:error, :deps}}
307307

308308
unknown ->
309309
NextLS.Logger.warning(state.logger, "Unexpected compiler response: #{inspect(unknown)}")
@@ -362,6 +362,13 @@ defmodule NextLS.Runtime do
362362
{:noreply, state}
363363
end
364364

365+
def handle_info({port, {:data, "Unchecked dependencies" <> _ = data}}, %{port: port} = state) do
366+
NextLS.Logger.log(state.logger, data)
367+
368+
state.on_initialized.({:error, :deps})
369+
{:noreply, state}
370+
end
371+
365372
def handle_info({port, {:data, data}}, %{port: port} = state) do
366373
NextLS.Logger.info(state.logger, data)
367374
{:noreply, state}

test/next_ls/dependency_test.exs

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ defmodule NextLS.DependencyTest do
66

77
@moduletag :tmp_dir
88

9-
describe "" do
9+
describe "refetching deps" do
1010
@describetag root_paths: ["my_proj"]
1111

1212
setup %{tmp_dir: cwd} do
@@ -40,7 +40,8 @@ defmodule NextLS.DependencyTest do
4040

4141
setup :with_lsp
4242

43-
test "successfully asks to refetch deps", %{client: client, mixexs: mixexs, lockfile: lockfile} = context do
43+
test "successfully asks to refetch deps on start",
44+
%{client: client, mixexs: mixexs, lockfile: lockfile} = context do
4445
assert :ok == notify(client, %{method: "initialized", jsonrpc: "2.0", params: %{}})
4546

4647
assert_is_ready(context, "my_proj")
@@ -100,6 +101,68 @@ defmodule NextLS.DependencyTest do
100101
assert_is_ready(context, "my_proj")
101102
assert_compiled(context, "my_proj")
102103
end
104+
105+
test "successfully asks to refetch deps on compile",
106+
%{client: client, mixexs: mixexs, lockfile: lockfile} = context do
107+
assert :ok == notify(client, %{method: "initialized", jsonrpc: "2.0", params: %{}})
108+
109+
assert_is_ready(context, "my_proj")
110+
assert_compiled(context, "my_proj")
111+
112+
did_open(client, mixexs, File.read!(mixexs))
113+
114+
# write new mix.exs and lockfile to simulate having them out of sync with the `deps` folder
115+
new_text =
116+
proj_mix_exs("""
117+
[{:temple, "~> 0.12.0"}]
118+
""")
119+
120+
File.write!(mixexs, new_text)
121+
122+
File.write!(lockfile, """
123+
%{
124+
"floki": {:hex, :floki, "0.35.4", "cc947b446024732c07274ac656600c5c4dc014caa1f8fb2dfff93d275b83890d", [:mix], [], "hexpm", "27fa185d3469bd8fc5947ef0f8d5c4e47f0af02eb6b070b63c868f69e3af0204"},
125+
"phoenix_html": {:hex, :phoenix_html, "3.3.3", "380b8fb45912b5638d2f1d925a3771b4516b9a78587249cabe394e0a5d579dc9", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "923ebe6fec6e2e3b3e569dfbdc6560de932cd54b000ada0208b5f45024bdd76c"},
126+
"temple": {:hex, :temple, "0.12.0", "b50b806e1f1805219f0cbffc9c747c14f138543977fa6c01e74756c3e0daaa25", [:mix], [{:floki, ">= 0.0.0", [hex: :floki, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.2", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:typed_struct, "~> 0.3", [hex: :typed_struct, repo: "hexpm", optional: false]}], "hexpm", "0d006e850bf21f6684fa0ee52ceeb2f8516bb0213bd003f6d38c66880262f8a8"},
127+
"typed_struct": {:hex, :typed_struct, "0.3.0", "939789e3c1dca39d7170c87f729127469d1315dcf99fee8e152bb774b17e7ff7", [:mix], [], "hexpm", "c50bd5c3a61fe4e198a8504f939be3d3c85903b382bde4865579bc23111d1b6d"},
128+
}
129+
""")
130+
131+
notify client, %{
132+
method: "textDocument/didSave",
133+
jsonrpc: "2.0",
134+
params: %{
135+
text: new_text,
136+
textDocument: %{uri: uri(mixexs)}
137+
}
138+
}
139+
140+
assert_request(client, "window/showMessageRequest", fn params ->
141+
assert %{
142+
"type" => 1,
143+
"actions" => [
144+
%{"title" => "yes"},
145+
%{"title" => "no"}
146+
]
147+
} = params
148+
149+
# respond with yes
150+
%{"title" => "yes"}
151+
end)
152+
153+
assert_notification "window/logMessage", %{
154+
"message" => "[NextLS] Running `mix deps.get` in directory" <> _,
155+
"type" => 3
156+
}
157+
158+
assert_notification "window/logMessage", %{
159+
"message" => "[NextLS] Restarting runtime" <> _,
160+
"type" => 3
161+
}
162+
163+
assert_is_ready(context, "my_proj")
164+
assert_compiled(context, "my_proj")
165+
end
103166
end
104167

105168
describe "local deps" do

0 commit comments

Comments
 (0)