@@ -49,16 +49,12 @@ defmodule Mix.Dep.Converger do
4949 end
5050
5151 defp all ( acc , lock , opts , callback ) do
52- deps = Mix.Dep.Loader . children ( )
53- deps = Enum . map ( deps , & ( % { & 1 | top_level: true } ) )
54- lock_given? = ! ! lock
52+ main = Mix.Dep.Loader . children ( )
53+ main = Enum . map ( main , & ( % { & 1 | top_level: true } ) )
54+ apps = Enum . map ( main , & ( & 1 . app ) )
5555
56- # Filter the dependencies per environment. We pass the ones
57- # left out as accumulator and upper breadth to help catch
58- # inconsistencies across environment, specially regarding
59- # the :only option. They are filtered again later.
60- current = Enum . map ( deps , & ( & 1 . app ) )
61- { main , only } = Mix.Dep.Loader . partition_by_env ( deps , opts )
56+ lock_given? = ! ! lock
57+ env = opts [ :env ]
6258
6359 # If no lock was given, let's read one to fill in the deps
6460 lock = lock || Mix.Dep.Lock . read
@@ -68,17 +64,14 @@ defmodule Mix.Dep.Converger do
6864 # lazily loaded, we need to check for it on every
6965 # iteration.
7066 { deps , rest , lock } =
71- all ( main , only , [ ] , current , callback , acc , lock , fn dep ->
67+ all ( main , apps , callback , acc , lock , env , fn dep ->
7268 if ( remote = Mix.RemoteConverger . get ) && remote . remote? ( dep ) do
7369 { :loaded , dep }
7470 else
7571 { :unloaded , dep , nil }
7672 end
7773 end )
7874
79- # Filter deps per environment once more. If the filtered
80- # dependencies had no conflicts, they are removed now.
81- { deps , _ } = Mix.Dep.Loader . partition_by_env ( deps , opts )
8275 diverged? = Enum . any? ( deps , & Mix.Dep . diverged? / 1 )
8376
8477 # Run remote converger if one is available and rerun Mix's
@@ -99,19 +92,26 @@ defmodule Mix.Dep.Converger do
9992 # In case no lock was given, we will use the local lock
10093 # which is potentially stale. So remote.deps/2 needs to always
10194 # check if the data it finds in the lock is actually valid.
102- all ( main , [ ] , [ ] , Enum . map ( main , & ( & 1 . app ) ) , callback , rest , lock , fn dep ->
103- cond do
104- cached = deps [ dep . app ] ->
105- { :loaded , cached }
106- true ->
107- { :unloaded , dep , remote . deps ( dep , lock ) }
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 ) }
108100 end
109101 end )
110102 else
111103 { deps , rest , lock }
112104 end
113105 end
114106
107+ defp all ( main , apps , callback , rest , lock , env , cache ) do
108+ { deps , rest , lock } = all ( main , [ ] , [ ] , apps , callback , rest , lock , env , cache )
109+ # When traversing dependencies, we keep skipped ones to
110+ # find conflicts. We remove them now after traversal.
111+ { deps , _ } = Mix.Dep.Loader . partition_by_env ( deps , env )
112+ { deps , rest , lock }
113+ end
114+
115115 # We traverse the tree of dependencies in a breadth-first
116116 # fashion. The reason for this is that we converge
117117 # dependencies, but allow the parent to override any
@@ -151,10 +151,14 @@ defmodule Mix.Dep.Converger do
151151 # Now, since "d" was specified in a parent project, no
152152 # exception is going to be raised since d is considered
153153 # to be the authoritative source.
154- defp all ( [ dep | t ] , acc , upper_breadths , current_breadths , callback , rest , lock , cache ) do
154+ defp all ( [ dep | t ] , acc , upper_breadths , current_breadths , callback , rest , lock , env , cache ) do
155155 cond do
156156 new_acc = diverged_deps ( acc , upper_breadths , dep ) ->
157- all ( t , new_acc , upper_breadths , current_breadths , callback , rest , lock , cache )
157+ all ( t , new_acc , upper_breadths , current_breadths , callback , rest , lock , env , cache )
158+ Mix.Dep.Loader . skip? ( dep , env ) ->
159+ # We still keep skipped dependencies around to detect conflicts.
160+ # They must be rejected after every all iteration.
161+ all ( t , [ dep | acc ] , upper_breadths , current_breadths , callback , rest , lock , env , cache )
158162 true ->
159163 dep =
160164 case cache . ( dep ) do
@@ -170,12 +174,15 @@ defmodule Mix.Dep.Converger do
170174 end
171175
172176 dep = % { dep | deps: reject_non_fullfilled_optional ( dep . deps , current_breadths ) }
173- { acc , rest , lock } = all ( t , [ dep | acc ] , upper_breadths , current_breadths , callback , rest , lock , cache )
174- all ( dep . deps , acc , current_breadths , Enum . map ( dep . deps , & ( & 1 . app ) ) ++ current_breadths , callback , rest , lock , cache )
177+ { acc , rest , lock } =
178+ all ( t , [ dep | acc ] , upper_breadths , current_breadths , callback , rest , lock , env , cache )
179+
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 )
175182 end
176183 end
177184
178- defp all ( [ ] , acc , _upper , _current , _callback , rest , lock , _cache ) do
185+ defp all ( [ ] , acc , _upper , _current , _callback , rest , lock , _env , _cache ) do
179186 { acc , rest , lock }
180187 end
181188
0 commit comments