Skip to content

Commit 31aebcd

Browse files
author
José Valim
committed
Automatically merge manager according to internal priority, closes #4230
1 parent afbac81 commit 31aebcd

File tree

3 files changed

+33
-16
lines changed

3 files changed

+33
-16
lines changed

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

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,8 @@ defmodule Mix.Dep.Converger do
213213
in_upper? && other_opts[:override] ->
214214
{other |> with_matching_only(dep, in_upper?), true}
215215
converge?(other, dep) ->
216-
{other |> with_matching_only(dep, in_upper?) |> with_matching_req(dep) |> merge_manager(dep), true}
216+
{other |> with_matching_only(dep, in_upper?)
217+
|> with_matching_req(dep) |> merge_manager(dep, in_upper?), true}
217218
true ->
218219
tag = if in_upper?, do: :overridden, else: :diverged
219220
{%{other | status: {tag, dep}}, true}
@@ -276,19 +277,10 @@ defmodule Mix.Dep.Converger do
276277
end
277278
end
278279

279-
defp converge?(%Mix.Dep{scm: scm1, manager: manager1, opts: opts1},
280-
%Mix.Dep{scm: scm2, manager: manager2, opts: opts2}) do
281-
scm1 == scm2 and
282-
manager_equal?(manager1, manager2) and
283-
opts_equal?(opts1, opts2) and
284-
scm1.equal?(opts1, opts2)
280+
defp converge?(%Mix.Dep{scm: scm1, opts: opts1}, %Mix.Dep{scm: scm2, opts: opts2}) do
281+
scm1 == scm2 and opts_equal?(opts1, opts2) and scm1.equal?(opts1, opts2)
285282
end
286283

287-
defp manager_equal?(manager, manager), do: true
288-
defp manager_equal?(_, nil), do: true
289-
defp manager_equal?(nil, _), do: true
290-
defp manager_equal?(_, _), do: false
291-
292284
defp opts_equal?(opts1, opts2) do
293285
keys = ~w(app env compile)a
294286
Enum.all?(keys, &(Keyword.fetch(opts1, &1) == Keyword.fetch(opts2, &1)))
@@ -300,8 +292,18 @@ defmodule Mix.Dep.Converger do
300292
end
301293
end
302294

303-
defp merge_manager(other, dep) do
304-
%{other | manager: other.manager || dep.manager}
295+
defp merge_manager(%{manager: other_manager} = other, %{manager: manager}, in_upper?) do
296+
%{other | manager: sort_manager(other_manager, manager, in_upper?)}
297+
end
298+
299+
@managers [:mix, :rebar3, :rebar, :make]
300+
301+
defp sort_manager(other_manager, manager, true) do
302+
other_manager || manager
303+
end
304+
defp sort_manager(other_manager, manager, false) do
305+
priority = @managers -- (@managers -- (List.wrap(other_manager) ++ List.wrap(manager)))
306+
List.first(priority) || other_manager || manager
305307
end
306308

307309
defp with_matching_req(%Mix.Dep{} = other, %Mix.Dep{} = dep) do

lib/mix/lib/mix/tasks/deps.compile.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ defmodule Mix.Tasks.Deps.Compile do
2525
"""
2626

2727
import Mix.Dep, only: [loaded: 1, available?: 1, loaded_by_name: 2,
28-
format_dep: 1, make?: 1, mix?: 1, rebar?: 1]
28+
format_dep: 1, make?: 1, mix?: 1]
2929

3030
@spec run(OptionParser.argv) :: :ok
3131
def run(args) do

lib/mix/test/mix/dep_test.exs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,22 @@ defmodule Mix.DepTest do
144144
end
145145
end
146146

147-
test "nested deps convergence with optional dependencies" do
147+
test "nested deps with convergence and managers" do
148+
Process.put(:custom_deps_git_repo_opts, [manager: :make])
149+
150+
deps = [{:deps_repo, "0.1.0", path: "custom/deps_repo", manager: :rebar},
151+
{:git_repo, "0.2.0", git: MixTest.Case.fixture_path("git_repo")}]
152+
153+
with_deps deps, fn ->
154+
in_fixture "deps_status", fn ->
155+
[dep1, dep2] = Mix.Dep.loaded([])
156+
assert dep1.manager == nil
157+
assert dep2.manager == :rebar
158+
end
159+
end
160+
end
161+
162+
test "nested deps with convergence and optional dependencies" do
148163
deps = [{:deps_repo, "0.1.0", path: "custom/deps_repo"},
149164
{:git_repo, "0.2.0", git: MixTest.Case.fixture_path("git_repo")}]
150165

0 commit comments

Comments
 (0)