@@ -86,9 +86,7 @@ defmodule Mix.Deps.Converger do
8686 # to be the authorative source.
8787 defp all ( [ dep | t ] , acc , upper_breadths , current_breadths , callback , rest ) do
8888 cond do
89- new_acc = overridden_deps ( acc , upper_breadths , dep ) ->
90- all ( t , new_acc , upper_breadths , current_breadths , callback , rest )
91- new_acc = diverged_deps ( acc , dep ) ->
89+ new_acc = diverged_deps ( acc , upper_breadths , dep ) ->
9290 all ( t , new_acc , upper_breadths , current_breadths , callback , rest )
9391 true ->
9492 { dep , rest } = callback . ( dep , rest )
@@ -109,67 +107,42 @@ defmodule Mix.Deps.Converger do
109107 { acc , rest }
110108 end
111109
112- # Look for an overriding dep in the upper breadths, if
113- # found return a new acc without the overridden dep and
114- # with the proper status set on the overrider. The
115- # overrider is moved to the front of the accumulator to
116- # preserve the position of the removed dep.
117- defp overridden_deps ( acc , upper_breadths , dep ) do
118- if dep . app in upper_breadths do
119- Mix.Dep [ app : app ] = dep
120-
121- { overrider , acc } =
122- Enum . reduce ( acc , { nil , [ ] } , fn other , { overrider , acc } ->
123- Mix.Dep [ app : other_app , opts: other_opts ] = other
124-
125- cond do
126- app == other_app && ( other_opts [ :override ] || converge? ( other , dep ) ) ->
127- { with_matching_req ( other , dep ) , acc }
128- app == other_app ->
129- { other . status ( { :overridden , dep } ) , acc }
130- true ->
131- { overrider , [ other | acc ] }
132- end
133- end )
134-
135- [ overrider | Enum . reverse ( acc ) ]
136- end
137- end
138-
139- # Check the list for matching dependencies.
140- # In case dependencies are found, check if their
141- # scm info match. If not, mark the dependencies
142- # as diverged.
143- defp diverged_deps ( list , dep ) do
110+ # Look for divergence in dependencies.
111+ #
112+ # If the same dependency is specified more than once,
113+ # we need to guarantee they converge. If they don't
114+ # converge, we mark them as diverged.
115+ #
116+ # The only exception is when the dependency that
117+ # diverges is in the upper breadth, in those cases we
118+ # also check for the override option and mark the dependency
119+ # as overridden instead of diverged.
120+ defp diverged_deps ( list , upper_breadths , dep ) do
144121 Mix.Dep [ app : app ] = dep
122+ in_upper? = app in upper_breadths
145123
146124 { acc , match } =
147125 Enum . map_reduce list , false , fn ( other , match ) ->
148- Mix.Dep [ app : other_app ] = other
126+ Mix.Dep [ app : other_app , opts: other_opts ] = other
149127
150128 cond do
151129 app != other_app ->
152130 { other , match }
153- converge? ( other , dep ) ->
131+ ( in_upper? && other_opts [ :override ] ) || converge? ( other , dep ) ->
154132 { with_matching_req ( other , dep ) , true }
155133 true ->
156- { other . status ( { :diverged , dep } ) , true }
134+ tag = if in_upper? , do: :overridden , else: :diverged
135+ { other . status ( { tag , dep } ) , true }
157136 end
158137 end
159138
160139 if match , do: acc
161140 end
162141
163- defp converge? ( _ , Mix.Dep [ scm : Mix . SCM.Optional ] ) do
164- true
165- end
166-
167- defp converge? ( Mix.Dep [ scm : scm , opts: opts1 ] , Mix.Dep [ scm : scm , opts: opts2 ] ) do
168- scm . equal? ( opts1 , opts2 )
142+ defp converge? ( Mix.Dep [ scm : scm1 , opts: opts1 ] , Mix.Dep [ scm : scm2 , opts: opts2 ] ) do
143+ scm1 == scm2 and scm1 . equal? ( opts1 , opts2 )
169144 end
170145
171- defp converge? ( _ , _ ) , do: false
172-
173146 defp reject_non_fullfilled_optional ( children , upper_breadths ) do
174147 Enum . reject children , fn Mix.Dep [ app : app , opts: opts ] ->
175148 opts [ :optional ] && not ( app in upper_breadths )
0 commit comments