Skip to content

Commit

Permalink
Support setting MIX_TARGET (#299)
Browse files Browse the repository at this point in the history
For #248

This allows you to set MIX_TARGET in a config and have it used in Elixir versions >= 1.8

This is most often used with Nerves and removes a lot of compilation errors in repos
relying on a target to be set
  • Loading branch information
jjcarstens authored Jun 21, 2020
1 parent 13b96ef commit 891922f
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 1 deletion.
10 changes: 9 additions & 1 deletion apps/language_server/lib/language_server/build.ex
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,15 @@ defmodule ElixirLS.LanguageServer.Build do
with_build_lock(fn ->
{us, _} =
:timer.tc(fn ->
IO.puts("Compiling with Mix env #{Mix.env()}")
IO.puts("MIX_ENV: #{Mix.env()}")

if function_exported?(Mix, :target, 0) do
# Even though we know we have the function here,
# Compilation will fail calling Mix.target/0 directly
# since Elixir 1.7 is used to compile - So we get around
# that with apply/3
IO.puts("MIX_TARGET: #{apply(Mix, :target, [])}")
end

prev_deps = cached_deps()
:ok = Mix.Project.clear_deps_cache()
Expand Down
34 changes: 34 additions & 0 deletions apps/language_server/lib/language_server/server.ex
Original file line number Diff line number Diff line change
Expand Up @@ -748,11 +748,13 @@ defmodule ElixirLS.LanguageServer.Server do
Dialyzer.check_support() == :ok && Map.get(settings, "dialyzerEnabled", true)

mix_env = Map.get(settings, "mixEnv", "test")
mix_target = Map.get(settings, "mixTarget")
project_dir = Map.get(settings, "projectDir")

state =
state
|> set_mix_env(mix_env)
|> maybe_set_mix_target(mix_target)
|> set_project_dir(project_dir)
|> set_dialyzer_enabled(enable_dialyzer)

Expand Down Expand Up @@ -787,6 +789,38 @@ defmodule ElixirLS.LanguageServer.Server do
state
end

defp maybe_set_mix_target(state, nil), do: state

defp maybe_set_mix_target(state, target) do
if Version.match?(System.version(), ">= 1.8.0") do
set_mix_target(state, target)
else
JsonRpc.show_message(
:warning,
"MIX_TARGET was set, but it requires Elixir >= 1.8.0. This setting will be ignored"
)

state
end
end

defp set_mix_target(state, target) do
target = target || "host"

prev_target = state.settings["mixTarget"]

if is_nil(prev_target) or target == prev_target do
# We've already checked for Elixir >= 1.8.0 by this point
# but compilation will fail if we just call Mix.target/0
# so we get around that via apply/3
apply(Mix, :target, [String.to_atom(target)])
else
JsonRpc.show_message(:warning, "You must restart ElixirLS after changing Mix target")
end

state
end

defp set_project_dir(%{project_dir: prev_project_dir, root_uri: root_uri} = state, project_dir)
when is_binary(root_uri) do
root_dir = SourceFile.path_from_uri(root_uri)
Expand Down

0 comments on commit 891922f

Please sign in to comment.