@@ -86,9 +86,7 @@ defmodule Mix.Deps.Converger do
86
86
# to be the authorative source.
87
87
defp all ( [ dep | t ] , acc , upper_breadths , current_breadths , callback , rest ) do
88
88
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 ) ->
92
90
all ( t , new_acc , upper_breadths , current_breadths , callback , rest )
93
91
true ->
94
92
{ dep , rest } = callback . ( dep , rest )
@@ -109,67 +107,42 @@ defmodule Mix.Deps.Converger do
109
107
{ acc , rest }
110
108
end
111
109
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
144
121
Mix.Dep [ app : app ] = dep
122
+ in_upper? = app in upper_breadths
145
123
146
124
{ acc , match } =
147
125
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
149
127
150
128
cond do
151
129
app != other_app ->
152
130
{ other , match }
153
- converge? ( other , dep ) ->
131
+ ( in_upper? && other_opts [ :override ] ) || converge? ( other , dep ) ->
154
132
{ with_matching_req ( other , dep ) , true }
155
133
true ->
156
- { other . status ( { :diverged , dep } ) , true }
134
+ tag = if in_upper? , do: :overridden , else: :diverged
135
+ { other . status ( { tag , dep } ) , true }
157
136
end
158
137
end
159
138
160
139
if match , do: acc
161
140
end
162
141
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 )
169
144
end
170
145
171
- defp converge? ( _ , _ ) , do: false
172
-
173
146
defp reject_non_fullfilled_optional ( children , upper_breadths ) do
174
147
Enum . reject children , fn Mix.Dep [ app : app , opts: opts ] ->
175
148
opts [ :optional ] && not ( app in upper_breadths )
0 commit comments