Skip to content

Commit c3582f9

Browse files
author
José Valim
committed
Reject non fullfilled optional dependencies later on
Imagine this dependency tree: * parent * child * ecto * postgrex * ja_serializer * ecto where postgrex is an optional dependency of Ecto. Because optional dependencies were rejected later on, ecto would have its postgrex dependency stripped and later failed to top-sort. This commit changes it to so optional dependencies are rejected only later on. Signed-off-by: José Valim <[email protected]>
1 parent bd83a45 commit c3582f9

File tree

1 file changed

+21
-11
lines changed

1 file changed

+21
-11
lines changed

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

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -92,15 +92,18 @@ defmodule Mix.Dep.Converger do
9292
# In case no lock was given, we will use the local lock
9393
# which is potentially stale. So remote.deps/2 needs to always
9494
# check if the data it finds in the lock is actually valid.
95-
all(main, apps, callback, rest, lock, env, fn dep ->
96-
if cached = deps[dep.app] do
97-
{:loaded, cached}
98-
else
99-
{:unloaded, dep, remote.deps(dep, lock)}
100-
end
101-
end)
95+
{deps, rest, lock} =
96+
all(main, apps, callback, rest, lock, env, fn dep ->
97+
if cached = deps[dep.app] do
98+
{:loaded, cached}
99+
else
100+
{:unloaded, dep, remote.deps(dep, lock)}
101+
end
102+
end)
103+
104+
{reject_non_fullfilled_optional(deps), rest, lock}
102105
else
103-
{deps, rest, lock}
106+
{reject_non_fullfilled_optional(deps), rest, lock}
104107
end
105108
end
106109

@@ -173,12 +176,12 @@ defmodule Mix.Dep.Converger do
173176
Mix.Dep.Loader.load(dep, children)
174177
end
175178

176-
dep = %{dep | deps: reject_non_fullfilled_optional(dep.deps, current_breadths)}
177179
{acc, rest, lock} =
178180
all(t, [dep|acc], upper_breadths, current_breadths, callback, rest, lock, env, cache)
179181

180-
new_breadths = Enum.map(dep.deps, &(&1.app)) ++ current_breadths
181-
all(dep.deps, acc, current_breadths, new_breadths, callback, rest, lock, env, cache)
182+
deps = reject_non_fullfilled_optional(dep.deps, current_breadths)
183+
new_breadths = Enum.map(deps, &(&1.app)) ++ current_breadths
184+
all(deps, acc, current_breadths, new_breadths, callback, rest, lock, env, cache)
182185
end
183186
end
184187

@@ -286,6 +289,13 @@ defmodule Mix.Dep.Converger do
286289
Enum.all?(keys, &(Keyword.fetch(opts1, &1) == Keyword.fetch(opts2, &1)))
287290
end
288291

292+
defp reject_non_fullfilled_optional(deps) do
293+
apps = Enum.map(deps, & &1.app)
294+
for dep <- deps do
295+
update_in dep.deps, &reject_non_fullfilled_optional(&1, apps)
296+
end
297+
end
298+
289299
defp reject_non_fullfilled_optional(children, upper_breadths) do
290300
Enum.reject children, fn %Mix.Dep{app: app, opts: opts} ->
291301
opts[:optional] && not(app in upper_breadths)

0 commit comments

Comments
 (0)