Skip to content

Commit e3be6dd

Browse files
author
José Valim
committed
Add deps.precompile hook and --include-children option
1 parent c076fdb commit e3be6dd

File tree

3 files changed

+47
-7
lines changed

3 files changed

+47
-7
lines changed

lib/mix/lib/mix/dep.ex

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ defmodule Mix.Dep do
103103

104104
# We need to keep the order of deps, loaded/1 properly orders them
105105
deps = Enum.filter(all_deps, &(&1.app in apps))
106+
deps = if opts[:include_children], do: include_children(deps, all_deps), else: deps
106107

107108
Enum.each apps, fn(app) ->
108109
unless Enum.any?(all_deps, &(&1.app == app)) do
@@ -113,6 +114,18 @@ defmodule Mix.Dep do
113114
deps
114115
end
115116

117+
# If we need to include children, we need to traverse all
118+
# them, fetch the uniq app names, and once again filter all
119+
# deps to keep the proper dependency ordering.
120+
defp include_children(deps, all_deps) do
121+
deps = include_children(deps)
122+
apps = deps |> Enum.map(& &1.app) |> Enum.uniq
123+
Enum.filter(all_deps, &(&1.app in apps))
124+
end
125+
126+
defp include_children([]), do: []
127+
defp include_children(deps), do: deps ++ include_children(Enum.flat_map(deps, & &1.deps))
128+
116129
@doc """
117130
Runs the given `fun` inside the given dependency project by
118131
changing the current working directory and loading the given

lib/mix/lib/mix/tasks/deps.compile.ex

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ defmodule Mix.Tasks.Deps.Compile do
66
@moduledoc """
77
Compiles dependencies.
88
9-
By default, compile all dependencies. A list of dependencies can
10-
be given to force the compilation of specific dependencies.
9+
By default, compile all dependencies. A list of dependencies
10+
can be given to force the compilation of specific dependencies.
1111
1212
This task attempts to detect if the project contains one of
1313
the following files and act accordingly:
@@ -22,23 +22,31 @@ defmodule Mix.Tasks.Deps.Compile do
2222
2323
{:some_dependency, "0.1.0", compile: "command to compile"}
2424
25+
If a list of dependencies is given, Mix will attempt to compile
26+
them as is. For example, if project `a` depends on `b`, calling
27+
`mix deps.compile a` will compile `a` even if `b` is out of
28+
date. This is to allow parts of the dependency tree to be
29+
recompiled without propagating those changes upstream. To ensure
30+
`b` is included in the compilation step, pass `--include-children`.
2531
"""
2632

2733
import Mix.Dep, only: [loaded: 1, available?: 1, loaded_by_name: 2,
2834
format_dep: 1, make?: 1, mix?: 1]
2935

36+
@switches [include_children: :boolean]
37+
3038
@spec run(OptionParser.argv) :: :ok
3139
def run(args) do
3240
Mix.Project.get!
3341

34-
case OptionParser.parse(args) do
42+
case OptionParser.parse(args, switches: @switches) do
3543
{_, [], _} ->
36-
# Because this command is invoked explicitly with
44+
# Because this command may be invoked explicitly with
3745
# deps.compile, we simply try to compile any available
3846
# dependency.
3947
compile(Enum.filter(loaded(env: Mix.env), &available?/1))
40-
{_, tail, _} ->
41-
compile(loaded_by_name(tail, env: Mix.env))
48+
{opts, tail, _} ->
49+
compile(loaded_by_name(tail, [env: Mix.env] ++ opts))
4250
end
4351
end
4452

@@ -47,7 +55,7 @@ defmodule Mix.Tasks.Deps.Compile do
4755
shell = Mix.shell
4856
config = Mix.Project.deps_config
4957

50-
Mix.Task.run "deps.loadpaths"
58+
Mix.Task.run "deps.precompile"
5159

5260
compiled =
5361
Enum.map(deps, fn %Mix.Dep{app: app, status: status, opts: opts, scm: scm} = dep ->
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
defmodule Mix.Tasks.Deps.Precompile do
2+
use Mix.Task
3+
4+
@moduledoc """
5+
Extension point for precompiling dependencies.
6+
7+
This is a task that can be aliased by projects
8+
that need to execute certain tasks to before
9+
compiling dependencies:
10+
11+
aliases: ["deps.precompile": ["nerves.precompile", "deps.precompile"]]
12+
13+
By default, this task has a single responsibility
14+
of loading all dependencies paths.
15+
"""
16+
def run(_) do
17+
Mix.Task.run "deps.loadpaths"
18+
end
19+
end

0 commit comments

Comments
 (0)