Skip to content

Commit 6e5c4fe

Browse files
author
José Valim
committed
Merge pull request #1082 from ericmj/mix-umbrella-appfile2
Clean up mix dependency retrieving and converging
2 parents be16bf4 + 2d870cf commit 6e5c4fe

File tree

5 files changed

+71
-72
lines changed

5 files changed

+71
-72
lines changed

lib/mix/lib/mix/deps.ex

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,7 @@ defmodule Mix.Deps do
4343
@doc """
4444
Returns all direct child dependencies.
4545
"""
46-
def children do
47-
Mix.Deps.Project.all
48-
end
46+
defdelegate children(), to: Mix.Deps.Retriever
4947

5048
@doc """
5149
Returns all dependencies depending on given dependencies.
@@ -162,7 +160,7 @@ defmodule Mix.Deps do
162160
@doc """
163161
Updates the dependency inside the given project.
164162
"""
165-
defdelegate update(dep), to: Mix.Deps.Project
163+
defdelegate update(dep), to: Mix.Deps.Retriever
166164

167165
@doc """
168166
Check if a dependency is ok.
@@ -234,14 +232,14 @@ defmodule Mix.Deps do
234232
end
235233

236234
@doc """
237-
Returns if dependency is a mix project.
235+
Returns true if dependency is a mix project.
238236
"""
239237
def mix?(dep) do
240238
dep.project != nil
241239
end
242240

243241
@doc """
244-
Returns if dependency is a rebar project.
242+
Returns true if dependency is a rebar project.
245243
"""
246244
def rebar?(dep) do
247245
Enum.any? ["rebar.config", "rebar.config.script"], fn file ->
@@ -250,7 +248,7 @@ defmodule Mix.Deps do
250248
end
251249

252250
@doc """
253-
Returns if dependency is a make project.
251+
Returns true if dependency is a make project.
254252
"""
255253
def make?(dep) do
256254
File.regular? Path.join(dep.opts[:dest], "Makefile")

lib/mix/lib/mix/deps/converger.ex

Lines changed: 12 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
defmodule Mix.Deps.Converger do
55
@moduledoc false
66

7-
import Mix.Deps, only: [available?: 1]
8-
97
@doc """
108
Clear up the mixfile cache.
119
"""
@@ -20,11 +18,10 @@ defmodule Mix.Deps.Converger do
2018
an updated depedency in case some processing is done.
2119
"""
2220
def all(rest, callback) do
23-
main = Enum.reverse Mix.Deps.Project.all
2421
config = [ deps_path: Path.expand(Mix.project[:deps_path]),
2522
root_lockfile: Path.expand(Mix.project[:lockfile]) ]
26-
{ deps, rest } = all(main, [], [], main, config, callback, rest)
27-
{ nest_deps(deps, config), rest }
23+
{ main, rest } = Mix.Deps.Retriever.all(rest, config,callback)
24+
{ all(Enum.reverse(main), [], [], main), rest }
2825
end
2926

3027
# We traverse the tree of dependencies in a breadth-
@@ -66,27 +63,25 @@ defmodule Mix.Deps.Converger do
6663
# Now, since `d` was specified in a parent project, no
6764
# exception is going to be raised since d is considered
6865
# to be the authorative source.
69-
defp all([dep|t], acc, upper_breadths, current_breadths, config, callback, rest) do
66+
defp all([dep|t], acc, upper_breadths, current_breadths) do
7067
cond do
7168
contains_dep?(upper_breadths, dep) ->
72-
all(t, acc, upper_breadths, current_breadths, config, callback, rest)
69+
all(t, acc, upper_breadths, current_breadths)
7370
match?({ diverged_acc, true }, diverged_dep?(acc, dep)) ->
74-
all(t, diverged_acc, upper_breadths, current_breadths, config, callback, rest)
71+
all(t, diverged_acc, upper_breadths, current_breadths)
7572
true ->
76-
{ dep, rest } = callback.(dep, rest)
77-
78-
if available?(dep) and mixfile?(dep) do
79-
{ project, deps } = nested_deps(dep, config)
80-
{ acc, rest } = all(t, [dep.project(project)|acc], upper_breadths, current_breadths, config, callback, rest)
81-
all(deps, acc, current_breadths, deps ++ current_breadths, config, callback, rest)
73+
deps = dep.deps
74+
if deps != [] do
75+
acc = all(t, [dep|acc], upper_breadths, current_breadths)
76+
all(deps, acc, current_breadths, deps ++ current_breadths)
8277
else
83-
all(t, [dep|acc], upper_breadths, current_breadths, config, callback, rest)
78+
all(t, [dep|acc], upper_breadths, current_breadths)
8479
end
8580
end
8681
end
8782

88-
defp all([], acc, _upper, _current, _config, _callback, rest) do
89-
{ acc, rest }
83+
defp all([], acc, _upper, _current) do
84+
acc
9085
end
9186

9287
# Does the list contain the given dependency?
@@ -111,40 +106,4 @@ defmodule Mix.Deps.Converger do
111106
end
112107
end
113108
end
114-
115-
defp mixfile?(dep) do
116-
File.regular?(Path.join dep.opts[:dest], "mix.exs")
117-
end
118-
119-
# Sets the `deps` field to the child dependencies of all
120-
# given dependencies and does so recursively.
121-
defp nest_deps(deps, config) do
122-
Enum.map deps, fn dep ->
123-
nest_deps(dep, deps, config)
124-
end
125-
end
126-
127-
defp nest_deps(dep, deps, config) do
128-
if available?(dep) and mixfile?(dep) do
129-
nested_apps = nested_names(dep, config)
130-
sub_deps = Enum.filter(deps, fn dep -> dep.app in nested_apps end)
131-
dep.deps Enum.map(sub_deps, nest_deps(&1, deps, config))
132-
else
133-
dep
134-
end
135-
end
136-
137-
defp nested_names(dep, post_config) do
138-
Mix.Deps.in_dependency dep, post_config, fn _ ->
139-
Mix.Deps.Project.all_names
140-
end
141-
end
142-
143-
# The dependency contains a Mixfile, so let's
144-
# load it and retrieve its nested dependencies.
145-
defp nested_deps(dep, post_config) do
146-
Mix.Deps.in_dependency dep, post_config, fn project ->
147-
{ project, Enum.reverse Mix.Deps.Project.all }
148-
end
149-
end
150109
end

lib/mix/lib/mix/deps/project.ex renamed to lib/mix/lib/mix/deps/retriever.ex

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
# This module is responsible for interacting
2-
# with dependencies of a given project. This
1+
# This module is responsible for retrieving
2+
# dependencies of a given project. This
33
# module and its functions are private to Mix.
4-
defmodule Mix.Deps.Project do
4+
defmodule Mix.Deps.Retriever do
55
@moduledoc false
66

77
@doc """
@@ -13,18 +13,56 @@ defmodule Mix.Deps.Project do
1313
This function raises an exception in case the developer
1414
provides a dependency in the wrong format.
1515
"""
16-
def all do
17-
deps = Mix.project[:deps] || []
18-
scms = Mix.SCM.available
19-
Enum.map deps, with_scm_and_status(&1, scms)
16+
def all(post_config // []) do
17+
{ deps, _ } = all(nil, post_config, fn(dep, acc) -> { dep, acc } end)
18+
deps
19+
end
20+
21+
@doc """
22+
Like `all/0` but takes a callback that is invoked for
23+
each dependency and must return an updated depedency
24+
in case some processing is done.
25+
"""
26+
def all(rest, post_config // [], callback) do
27+
Enum.map_reduce children, rest, fn (dep, rest) ->
28+
{ dep, rest } = callback.(dep, rest)
29+
30+
if Mix.Deps.available?(dep) and Mix.Deps.mix?(dep) do
31+
{ dep, rest } = Mix.Deps.in_dependency dep, post_config, fn _ ->
32+
{ deps, rest } = all(rest, callback)
33+
{ dep.deps(deps), rest }
34+
end
35+
end
36+
37+
{ dep, rest }
38+
end
2039
end
2140

2241
@doc """
23-
Returns all application names of current project's dependencies.
42+
Gets all direct children for the current Mix.Project
43+
as a `Mix.Dep` record. Unlike with `all` the `deps`
44+
field is not populated.
2445
"""
25-
def all_names do
46+
def children() do
2647
deps = Mix.project[:deps] || []
27-
Enum.map(deps, elem(&1, 0))
48+
scms = Mix.SCM.available
49+
50+
Enum.map deps, fn dep ->
51+
dep = with_scm_and_status(dep, scms)
52+
53+
# Set properties if dependency is a mix project
54+
if Mix.Deps.available?(dep) and mixfile?(dep) do
55+
dep = Mix.Deps.in_dependency dep, fn project ->
56+
if match?({ :noappfile, _ }, dep.status) and Mix.Project.umbrella? do
57+
dep = dep.update_opts(Keyword.put(&1, :app, false))
58+
.status({ :ok, nil })
59+
end
60+
dep.project(project)
61+
end
62+
end
63+
64+
dep
65+
end
2866
end
2967

3068
@doc """
@@ -106,4 +144,8 @@ defmodule Mix.Deps.Project do
106144
defp vsn_match?(nil, _actual), do: true
107145
defp vsn_match?(expected, actual) when is_binary(expected), do: actual == expected
108146
defp vsn_match?(expected, actual) when is_regex(expected), do: actual =~ expected
147+
148+
defp mixfile?(dep) do
149+
File.regular?(Path.join dep.opts[:dest], "mix.exs")
150+
end
109151
end

lib/mix/lib/mix/tasks/deps.check.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@ defmodule Mix.Tasks.Deps.Check do
4343

4444
defp ok?(Mix.Dep[status: { :ok, _ }]), do: true
4545
defp ok?(_), do: false
46-
end
46+
end

lib/mix/test/fixtures/umbrella_dep/mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ defmodule UmbrellaDep.Mixfile do
77
end
88

99
defp deps do
10-
[ { :umbrella, path: "deps/umbrella", app: false } ]
10+
[ { :umbrella, path: "deps/umbrella" } ]
1111
end
1212
end

0 commit comments

Comments
 (0)