Skip to content

Commit 1eae754

Browse files
ktecjosevalim
authored andcommitted
Ensure proper divergence error between remote and non-remote dep(#7802)
- Add test for deps diverged from remote converger (@ericmj) - Add scm to the deps cache - Add code comments to help explain reasoning
1 parent 4bab217 commit 1eae754

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

lib/mix/lib/mix/dep/converger.ex

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,17 +94,19 @@ defmodule Mix.Dep.Converger do
9494
# on, there is no lock, so we won't hit this branch.
9595
lock = if lock_given?, do: remote.converge(deps, lock), else: lock
9696

97-
deps =
97+
# Build a cache using both dep_name and dep_scm to ensure we only
98+
# return :loaded for deps which have been loaded from the same source.
99+
cache =
98100
deps
99101
|> Enum.reject(&remote.remote?(&1))
100-
|> Enum.into(%{}, &{&1.app, &1})
102+
|> Enum.into(%{}, &{{&1.app, &1.scm}, &1})
101103

102104
# In case no lock was given, we will use the local lock
103105
# which is potentially stale. So remote.deps/2 needs to always
104106
# check if the data it finds in the lock is actually valid.
105107
{deps, rest, lock} =
106108
all(main, apps, callback, rest, lock, env, fn dep ->
107-
if cached = deps[dep.app] do
109+
if cached = cache[{dep.app, dep.scm}] do
108110
{:loaded, cached}
109111
else
110112
{:unloaded, dep, remote.deps(dep, lock)}

lib/mix/test/mix/dep_test.exs

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ defmodule Mix.DepTest do
292292
end)
293293
end
294294

295-
## Remove converger
295+
## Remote converger
296296

297297
defmodule IdentityRemoteConverger do
298298
@behaviour Mix.RemoteConverger
@@ -330,6 +330,44 @@ defmodule Mix.DepTest do
330330
Mix.RemoteConverger.register(nil)
331331
end
332332

333+
defmodule DivergingRemoteConverger do
334+
@behaviour Mix.RemoteConverger
335+
336+
def remote?(%Mix.Dep{app: :deps_repo, scm: Mix.SCM.Path}), do: true
337+
def remote?(%Mix.Dep{app: :git_repo, scm: Mix.SCM.Path}), do: true
338+
def remote?(%Mix.Dep{}), do: false
339+
def deps(%Mix.Dep{app: :deps_repo}, _lock), do: [{:git_repo, path: "custom/git_repo"}]
340+
def deps(%Mix.Dep{app: :git_repo}, _lock), do: []
341+
def post_converge, do: :ok
342+
343+
def converge(_deps, lock) do
344+
lock
345+
|> Map.put(:deps_repo, :custom)
346+
|> Map.put(:git_repo, :custom)
347+
end
348+
end
349+
350+
test "converger detects diverged deps from remote converger" do
351+
deps = [
352+
{:deps_on_git_repo, "0.2.0", git: MixTest.Case.fixture_path("deps_on_git_repo")},
353+
{:deps_repo, "0.1.0", path: "custom/deps_repo"}
354+
]
355+
356+
with_deps(deps, fn ->
357+
Mix.RemoteConverger.register(DivergingRemoteConverger)
358+
359+
in_fixture("deps_status", fn ->
360+
assert_raise Mix.Error, fn ->
361+
Mix.Tasks.Deps.Get.run([])
362+
end
363+
364+
assert_received {:mix_shell, :error, ["Dependencies have diverged:"]}
365+
end)
366+
end)
367+
after
368+
Mix.RemoteConverger.register(nil)
369+
end
370+
333371
test "pass dependencies to remote converger in defined order" do
334372
deps = [
335373
{:ok, "0.1.0", path: "deps/ok"},

0 commit comments

Comments
 (0)