I have:
/custom/path/to/b) and C (added anyhow)Then, if MyCompiler compile task looks like
defmodule Mix.Tasks.Compile.MyCompiler do
use Mix.Task
def run(_args) do
Mix.Project.deps_paths() |> inspect() |> Mix.shell().info()
end
end
then when compiling project A, I get printed:
%{
b: "/path/to/a/deps/b"
}
despite that path to B is /custom/path/to/b.
Mix.Project.deps_paths/0 should always return proper paths, in this case
%{
b: "/custom/path/to/b"
}
as it does in runtime.
Thank you @mat-hek! Can you please push a sample application to GitHub that reproduces the issue? That will make it much easier for us to reproduce and address this.
When reproducing this from scratch, I found out that this only happens if a dependency (B in this case) is overriden in the main (A) project. Here is an example: https://github.com/mat-hek/elixir_deps_paths_bug
Until this is fixed, we're using the following workaround. It seems to work ;)
defmodule MixProjectHelper do
@path_store_name :deps_paths_store
def store_project_path() do
Agent.start(fn -> %{} end, name: @path_store_name)
app = Mix.Project.get!().project |> Keyword.fetch!(:app)
dir = Mix.ProjectStack.peek().file |> Path.dirname()
Agent.update(@path_store_name, &Map.put(&1, app, dir))
end
def deps_paths() do
Agent.start(fn -> %{} end, name: @path_store_name)
app = Mix.Project.get!().project |> Keyword.fetch!(:app)
Mix.Project.deps_paths()
|> Map.merge(Agent.get(@path_store_name, & &1))
|> Map.delete(app)
end
end
This is utilizing the fact that deps added by path are always recompiled, so if store_project_path/0 is called, the proper path is stored. Fallback to Mix.Project.deps_paths/0 makes it work in other cases. Of course works only for deps that have the compiler in project compilers.
Closing in favor of #7834.