@@ -128,7 +128,7 @@ defmodule Mix.Project do
128
128
end
129
129
130
130
@ doc """
131
- Returns if project is an umbrella project.
131
+ Returns true if project is an umbrella project.
132
132
"""
133
133
def umbrella? do
134
134
config [ :apps_path ] != nil
@@ -141,49 +141,22 @@ defmodule Mix.Project do
141
141
Path . expand ( config [ :apps_path ] )
142
142
end
143
143
144
- @ doc """
145
- Loads mix.exs in the current directory or loads the project from the
146
- mixfile cache and pushes the project to the project stack. Optionally
147
- takes a post_config.
148
- """
149
- def load_project ( app , post_config // [ ] ) do
150
- if cached = Mix.Server . call ( { :mixfile_cache , app } ) do
151
- Mix.Project . post_config ( post_config )
152
- Mix.Project . push ( cached )
153
- cached
154
- else
155
- old_proj = Mix.Project . get
156
-
157
- if File . regular? ( "mix.exs" ) do
158
- Mix.Project . post_config ( post_config )
159
- Code . load_file "mix.exs"
160
- end
161
-
162
- new_proj = Mix.Project . get
163
-
164
- if old_proj == new_proj do
165
- new_proj = nil
166
- Mix.Project . push new_proj
167
- end
168
-
169
- Mix.Server . cast ( { :mixfile_cache , app , new_proj } )
170
- new_proj
171
- end
172
- end
173
-
174
144
@ doc """
175
145
Run fun for every application in the umbrella project. Changes current
176
146
project and working directory.
177
147
"""
178
148
def recursive ( fun ) do
179
- paths = Path . wildcard ( Path . join ( Mix . project [ :apps_path ] , "*" ) )
149
+ apps_path = config [ :apps_path ]
150
+ paths = Path . wildcard ( Path . join ( apps_path , "*" ) )
151
+
180
152
projects = Enum . map paths , fn path ->
181
153
dir = Path . basename ( path )
182
154
app = dir |> String . downcase |> binary_to_atom
183
155
{ app , path }
184
156
end
185
157
186
- projects = topsort_projects ( projects )
158
+ projects = topsort_projects ( projects , Path . expand ( apps_path ) )
159
+
187
160
results = Enum . map projects , fn { app , app_path } ->
188
161
in_project ( app , app_path , fun )
189
162
end
@@ -192,16 +165,15 @@ defmodule Mix.Project do
192
165
end
193
166
194
167
@ doc """
195
- Run fun in the context of project app and working directory app_path.
196
- Optionally takes a post_config.
168
+ Runs the given `fun` inside the given project by changing
169
+ the current working directory and loading the given project
170
+ into the project stack.
197
171
"""
198
172
def in_project ( app , app_path , post_config // [ ] , fun ) do
199
- umbrella_path = apps_path
200
-
201
173
File . cd! app_path , fn ->
202
- load_project ( app , post_config )
174
+ cached = load_project ( app , post_config )
203
175
result = try do
204
- fun . ( umbrella_path )
176
+ fun . ( cached )
205
177
after
206
178
Mix.Project . pop
207
179
end
@@ -232,16 +204,43 @@ defmodule Mix.Project do
232
204
paths ++ compile_paths
233
205
end
234
206
207
+ # Loads mix.exs in the current directory or loads the project from the
208
+ # mixfile cache and pushes the project to the project stack.
209
+ defp load_project ( app , post_config ) do
210
+ if cached = Mix.Server . call ( { :mixfile_cache , app } ) do
211
+ Mix.Project . post_config ( post_config )
212
+ Mix.Project . push ( cached )
213
+ cached
214
+ else
215
+ old_proj = Mix.Project . get
216
+
217
+ if File . regular? ( "mix.exs" ) do
218
+ Mix.Project . post_config ( post_config )
219
+ Code . load_file "mix.exs"
220
+ end
221
+
222
+ new_proj = Mix.Project . get
223
+
224
+ if old_proj == new_proj do
225
+ new_proj = nil
226
+ Mix.Project . push new_proj
227
+ end
228
+
229
+ Mix.Server . cast ( { :mixfile_cache , app , new_proj } )
230
+ new_proj
231
+ end
232
+ end
233
+
235
234
# Sort projects in dependency order
236
- defp topsort_projects ( projects ) do
235
+ defp topsort_projects ( projects , apps_path ) do
237
236
graph = :digraph . new
238
237
239
238
Enum . each projects , fn { app , app_path } ->
240
239
:digraph . add_vertex ( graph , app , app_path )
241
240
end
242
241
243
242
Enum . each projects , fn { app , app_path } ->
244
- in_project app , app_path , fn apps_path ->
243
+ in_project app , app_path , fn _ ->
245
244
Enum . each Mix.Deps . children , fn dep ->
246
245
if Mix.Deps . available? ( dep ) and Mix.Deps . in_umbrella? ( dep , apps_path ) do
247
246
:digraph . add_edge ( graph , dep . app , app )
0 commit comments