From 6ead4991039575c961cb09d63c5762297c82dcf0 Mon Sep 17 00:00:00 2001 From: doorgan Date: Fri, 29 Aug 2025 15:33:45 -0300 Subject: [PATCH] fix: make sure asdf shims are in the PATH --- apps/expert/lib/expert/engine_node.ex | 24 ++++++++++++++------- apps/expert/lib/expert/port.ex | 30 +++++++++++++++++++++------ 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/apps/expert/lib/expert/engine_node.ex b/apps/expert/lib/expert/engine_node.ex index c70d5f32..edcf2633 100644 --- a/apps/expert/lib/expert/engine_node.ex +++ b/apps/expert/lib/expert/engine_node.ex @@ -2,6 +2,8 @@ defmodule Expert.EngineNode do alias Forge.Project require Logger + use Expert.Project.Progress.Support + defmodule State do defstruct [ :project, @@ -169,7 +171,7 @@ defmodule Expert.EngineNode do # Expert release, and we build it on the fly for the project elixir+opt # versions if it was not built yet. defp glob_paths(%Project{} = project) do - {:ok, elixir, _} = Expert.Port.elixir_executable(project) + {:ok, elixir, env} = Expert.Port.elixir_executable(project) expert_priv = :code.priv_dir(:expert) packaged_engine_source = Path.join([expert_priv, "engine_source", "apps", "engine"]) @@ -192,20 +194,26 @@ defmodule Expert.EngineNode do "--vsn", Expert.vsn() ], + env: Expert.Port.ensure_charlists(env), cd: engine_source ] launcher = Expert.Port.path() - Logger.info("Finding or building engine for project #{Project.name(project)}") + GenLSP.info( + Expert.get_lsp(), + "Finding or building engine for project #{Project.name(project)}" + ) - port = - Port.open( - {:spawn_executable, launcher}, - opts - ) + with_progress(project, "Building engine for #{Project.name(project)}", fn -> + port = + Port.open( + {:spawn_executable, launcher}, + opts + ) - wait_for_engine(port) + wait_for_engine(port) + end) end defp wait_for_engine(port) do diff --git a/apps/expert/lib/expert/port.ex b/apps/expert/lib/expert/port.ex index 9a9ff36d..936554cc 100644 --- a/apps/expert/lib/expert/port.ex +++ b/apps/expert/lib/expert/port.ex @@ -64,13 +64,31 @@ defmodule Expert.Port do # We launch expert by asking the version managers to provide an environment, # which contains path munging. This initial environment is present in the running # VM, and needs to be undone so we can find the correct elixir executable in the project. - defp reset_env("asdf", _root_path) do - orig_path = System.get_env("PATH_SAVE", System.get_env("PATH")) + defp reset_env("asdf", root_path) do + {env, _} = System.cmd("asdf", ~w(env elixir), cd: root_path) + + env = + env + |> String.trim() + |> String.split("\n") + |> Enum.map(fn key_and_value -> + [key, value] = + key_and_value + |> String.split("=", parts: 2) + |> Enum.map(&String.trim/1) + + {key, value} + end) + |> Enum.reject(&is_nil/1) + + asdf_path = + case List.keyfind(env, "ASDF_INSTALL_PATH", 0) do + {_, path} -> Path.join(path, "../../../shims") + _ -> "" + end Enum.map(System.get_env(), fn - {"ASDF_ELIXIR_VERSION", _} -> {"ASDF_ELIXIR_VERSION", nil} - {"ASDF_ERLANG_VERSION", _} -> {"ASDF_ERLANG_VERSION", nil} - {"PATH", _} -> {"PATH", orig_path} + {"PATH", path} -> {"PATH", "#{asdf_path}:#{path}"} other -> other end) end @@ -169,7 +187,7 @@ defmodule Expert.Port do raise ArgumentError, "Operating system #{inspect(os_tuple)} is not currently supported" end - defp ensure_charlists(environment_variables) do + def ensure_charlists(environment_variables) do Enum.map(environment_variables, fn {key, value} -> # using to_string ensures nil values won't blow things up erl_key = key |> to_string() |> String.to_charlist()