@@ -49,16 +49,12 @@ defmodule Mix.Dep.Converger do
49
49
end
50
50
51
51
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 ) )
55
55
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 ]
62
58
63
59
# If no lock was given, let's read one to fill in the deps
64
60
lock = lock || Mix.Dep.Lock . read
@@ -68,17 +64,14 @@ defmodule Mix.Dep.Converger do
68
64
# lazily loaded, we need to check for it on every
69
65
# iteration.
70
66
{ deps , rest , lock } =
71
- all ( main , only , [ ] , current , callback , acc , lock , fn dep ->
67
+ all ( main , apps , callback , acc , lock , env , fn dep ->
72
68
if ( remote = Mix.RemoteConverger . get ) && remote . remote? ( dep ) do
73
69
{ :loaded , dep }
74
70
else
75
71
{ :unloaded , dep , nil }
76
72
end
77
73
end )
78
74
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 )
82
75
diverged? = Enum . any? ( deps , & Mix.Dep . diverged? / 1 )
83
76
84
77
# Run remote converger if one is available and rerun Mix's
@@ -99,19 +92,26 @@ defmodule Mix.Dep.Converger do
99
92
# In case no lock was given, we will use the local lock
100
93
# which is potentially stale. So remote.deps/2 needs to always
101
94
# 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 ) }
108
100
end
109
101
end )
110
102
else
111
103
{ deps , rest , lock }
112
104
end
113
105
end
114
106
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
+
115
115
# We traverse the tree of dependencies in a breadth-first
116
116
# fashion. The reason for this is that we converge
117
117
# dependencies, but allow the parent to override any
@@ -151,10 +151,14 @@ defmodule Mix.Dep.Converger do
151
151
# Now, since "d" was specified in a parent project, no
152
152
# exception is going to be raised since d is considered
153
153
# 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
155
155
cond do
156
156
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 )
158
162
true ->
159
163
dep =
160
164
case cache . ( dep ) do
@@ -170,12 +174,15 @@ defmodule Mix.Dep.Converger do
170
174
end
171
175
172
176
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 )
175
182
end
176
183
end
177
184
178
- defp all ( [ ] , acc , _upper , _current , _callback , rest , lock , _cache ) do
185
+ defp all ( [ ] , acc , _upper , _current , _callback , rest , lock , _env , _cache ) do
179
186
{ acc , rest , lock }
180
187
end
181
188
0 commit comments