Skip to content

Commit

Permalink
Add mix clean custom command (#730)
Browse files Browse the repository at this point in the history
* rename compile

* add clean

* add mix clean as a custom command

* add test

* fix tests

* fix tests
  • Loading branch information
lukaszsamson committed Sep 19, 2022
1 parent 6c1833c commit c3b73d8
Show file tree
Hide file tree
Showing 8 changed files with 120 additions and 3 deletions.
32 changes: 30 additions & 2 deletions apps/language_server/lib/language_server/build.ex
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ defmodule ElixirLS.LanguageServer.Build do

# if we won't do it elixir >= 1.11 warns that protocols have already been consolidated
purge_consolidated_protocols()
{status, diagnostics} = compile()
{status, diagnostics} = run_mix_compile()

diagnostics = Diagnostics.normalize(diagnostics, root_path)
Server.build_finished(parent, {status, mixfile_diagnostics ++ diagnostics})
Expand All @@ -46,6 +46,13 @@ defmodule ElixirLS.LanguageServer.Build do
end
end

def clean(clean_deps? \\ false) do
with_build_lock(fn ->
Mix.Task.clear()
run_mix_clean(clean_deps?)
end)
end

def with_build_lock(func) do
:global.trans({__MODULE__, self()}, func)
end
Expand Down Expand Up @@ -104,7 +111,8 @@ defmodule ElixirLS.LanguageServer.Build do
end
end

defp compile do
defp run_mix_compile do
# TODO consider adding --no-compile
case Mix.Task.run("compile", ["--return-errors", "--ignore-module-conflict"]) do
{status, diagnostics} when status in [:ok, :error, :noop] and is_list(diagnostics) ->
{status, diagnostics}
Expand All @@ -117,6 +125,26 @@ defmodule ElixirLS.LanguageServer.Build do
end
end

defp run_mix_clean(clean_deps?) do
opts = []

opts =
if clean_deps? do
opts ++ ["--deps"]
else
opts
end

results = Mix.Task.run("clean", opts) |> List.wrap()

if Enum.all?(results, &match?(:ok, &1)) do
:ok
else
JsonRpc.log_message(:error, "mix clean returned #{inspect(results)}")
{:error, :clean_failed}
end
end

defp purge_consolidated_protocols do
config = Mix.Project.config()
path = Mix.Project.consolidation_path(config)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand do
"spec" => ExecuteCommand.ApplySpec,
"expandMacro" => ExecuteCommand.ExpandMacro,
"manipulatePipes" => ExecuteCommand.ManipulatePipes,
"restart" => ExecuteCommand.Restart
"restart" => ExecuteCommand.Restart,
"mixClean" => ExecuteCommand.MixClean
}

@callback execute([any], %ElixirLS.LanguageServer.Server{}) ::
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand.MixClean do
@behaviour ElixirLS.LanguageServer.Providers.ExecuteCommand

@impl ElixirLS.LanguageServer.Providers.ExecuteCommand
def execute([clean_deps?], _state) do
case ElixirLS.LanguageServer.Build.clean(clean_deps?) do
:ok -> {:ok, %{}}
{:error, reason} -> {:error, :server_error, inspect(reason)}
end
end
end
5 changes: 5 additions & 0 deletions apps/language_server/test/fixtures/clean/lib/a.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defmodule A do
def fun do
:ok = B.fun()
end
end
5 changes: 5 additions & 0 deletions apps/language_server/test/fixtures/clean/lib/b.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defmodule B do
def fun do
:error
end
end
5 changes: 5 additions & 0 deletions apps/language_server/test/fixtures/clean/lib/c.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
defmodule C do
def myfun do
1
end
end
15 changes: 15 additions & 0 deletions apps/language_server/test/fixtures/clean/mix.exs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
defmodule ElixirLS.LanguageServer.Fixtures.Clean.Mixfile do
use Mix.Project

def project do
[app: :els_clean_test, version: "0.1.0"]
end

# Configuration for the OTP application
#
# Type "mix help compile.app" for more information
def application do
# Specify extra applications you'll use from Erlang/Elixir
[]
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
defmodule ElixirLS.LanguageServer.Providers.ExecuteCommand.MixCleanTest do
alias ElixirLS.LanguageServer.{Server, Protocol, SourceFile}
use ElixirLS.Utils.MixTest.Case, async: false
use Protocol

setup do
server = ElixirLS.LanguageServer.Test.ServerTestHelpers.start_server()

{:ok, %{server: server}}
end

@tag fixture: true
test "mix clean", %{server: server} do
in_fixture(Path.join(__DIR__, "../.."), "clean", fn ->
root_uri = SourceFile.path_to_uri(File.cwd!())
Server.receive_packet(server, initialize_req(1, root_uri, %{}))

Server.receive_packet(
server,
did_change_configuration(%{
"elixirLS" => %{"dialyzerEnabled" => false}
})
)

assert_receive %{
"method" => "window/logMessage",
"params" => %{"message" => "Compile took" <> _}
},
20000

path = ".elixir_ls/build/test/lib/els_clean_test/ebin/Elixir.A.beam"
assert File.exists?(path)

server_instance_id = :sys.get_state(server).server_instance_id

Server.receive_packet(
server,
execute_command_req(4, "mixClean:#{server_instance_id}", [false])
)

res = assert_receive(%{"id" => 4}, 5000)
assert res["result"] == %{}

refute File.exists?(path)
end)
end
end

0 comments on commit c3b73d8

Please sign in to comment.