Skip to content

Commit 50820df

Browse files
author
José Valim
committed
Mark dependencies as requiring compilation every time they are fetched
1 parent ee0fb39 commit 50820df

File tree

6 files changed

+64
-33
lines changed

6 files changed

+64
-33
lines changed

lib/mix/lib/mix/deps.ex

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ defmodule Mix.Deps do
209209
def format_status(Mix.Dep[status: { :noappfile, path }]),
210210
do: "could not find an app file at #{Path.relative_to_cwd(path)}, " <>
211211
"this may happen when you specified the wrong application name in your deps " <>
212-
"or if the dependency did not compile (which can be amended with `mix deps.compile`)"
212+
"or if the dependency did not compile (which can be amended with `#{mix_env_var}mix deps.compile`)"
213213

214214
def format_status(Mix.Dep[status: { :invalidapp, path }]),
215215
do: "the app file at #{Path.relative_to_cwd(path)} is invalid"
@@ -229,6 +229,9 @@ defmodule Mix.Deps do
229229
def format_status(Mix.Dep[status: :nolock]),
230230
do: "the dependency is not locked"
231231

232+
def format_status(Mix.Dep[status: :compile]),
233+
do: "the dependency build is outdated, please run `#{mix_env_var}mix deps.compile`"
234+
232235
def format_status(Mix.Dep[app: app, status: { :divergedreq, other }] = dep) do
233236
"the dependency #{app} defined\n" <>
234237
"#{dep_status(dep)}" <>
@@ -251,14 +254,14 @@ defmodule Mix.Deps do
251254

252255
def format_status(Mix.Dep[status: { :unavailable, _ }, scm: scm]) do
253256
if scm.fetchable? do
254-
"the dependency is not available, run `mix deps.get`"
257+
"the dependency is not available, run `#{mix_env_var}mix deps.get`"
255258
else
256259
"the dependency is not available"
257260
end
258261
end
259262

260263
def format_status(Mix.Dep[status: { :elixirlock, _ }]),
261-
do: "the dependency is built with an out-of-date elixir version, run `mix deps.get`"
264+
do: "the dependency is built with an out-of-date elixir version, run `#{mix_env_var}mix deps.get`"
262265

263266
defp dep_status(Mix.Dep[app: app, requirement: req, opts: opts, from: from]) do
264267
info = { app, req, Dict.drop(opts, [:dest, :lock, :env, :build]) }
@@ -302,16 +305,6 @@ defmodule Mix.Deps do
302305
def available?(Mix.Dep[status: { :unavailable, _ }]), do: false
303306
def available?(Mix.Dep[]), do: true
304307

305-
@doc """
306-
Checks if a dependency can be compiled.
307-
308-
All available dependencies can be compiled except for
309-
umbrella applications.
310-
"""
311-
def compilable?(Mix.Dep[manager: manager, extra: extra] = dep) do
312-
available?(dep) and (manager != :mix or !extra[:umbrella?])
313-
end
314-
315308
@doc """
316309
Checks if a dependency is out of date, also considering its
317310
lock status. Therefore, be sure to call `check_lock` before
@@ -395,6 +388,14 @@ defmodule Mix.Deps do
395388

396389
## Helpers
397390

391+
defp mix_env_var do
392+
if Mix.env == :dev do
393+
""
394+
else
395+
"MIX_ENV=#{Mix.env} "
396+
end
397+
end
398+
398399
defp to_app_names(given) do
399400
Enum.map given, fn(app) ->
400401
if is_binary(app), do: binary_to_atom(app), else: app

lib/mix/lib/mix/deps/fetcher.ex

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,21 @@ defmodule Mix.Deps.Fetcher do
8383
lock = Dict.merge(old_lock, new_lock)
8484
Mix.Deps.Lock.write(lock)
8585

86+
require_compilation(deps)
8687
do_compile(deps, opts)
8788
{ apps, all_deps }
8889
end
8990

91+
defp require_compilation(deps) do
92+
envs = Mix.Project.build_path
93+
|> Path.join("*/lib")
94+
|> Path.wildcard()
95+
96+
lc Mix.Dep[app: app] inlist deps, env inlist envs do
97+
File.touch Path.join [env, app, ".compile"]
98+
end
99+
end
100+
90101
defp do_compile(deps, opts) do
91102
apps = Enum.map(deps, &(&1.app)) |> Enum.uniq
92103

lib/mix/lib/mix/deps/loader.ex

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,12 @@ defmodule Mix.Deps.Loader do
123123
end
124124

125125
defp scm_status(scm, opts) do
126-
if scm.checked_out? opts do
127-
{ :ok, nil }
126+
if scm.checked_out?(opts) do
127+
if File.exists?(Path.join(opts[:build], ".compile")) do
128+
:compile
129+
else
130+
{ :ok, nil }
131+
end
128132
else
129133
{ :unavailable, opts[:dest] }
130134
end

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

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ defmodule Mix.Tasks.Deps.Check do
2020
all = Enum.map loaded, &check_lock(&1, lock)
2121

2222
prune_deps(all)
23-
{ not_ok, recompile } = partition_deps(all, [], [])
23+
{ not_ok, compile } = partition_deps(all, [], [])
2424

2525
cond do
2626
not_ok != [] ->
@@ -33,28 +33,27 @@ defmodule Mix.Tasks.Deps.Check do
3333
end
3434

3535
raise Mix.Error, message: "Can't continue due to errors on dependencies"
36-
recompile == [] or "--no-compile" in args ->
36+
compile == [] or "--no-compile" in args ->
3737
:ok
3838
true ->
39-
Mix.Task.run "deps.compile", Enum.map(recompile, & &1.app)
39+
Mix.Task.run "deps.compile", Enum.map(compile, & &1.app)
4040
end
4141
end
4242

43-
defp partition_deps([Mix.Dep[status: { :ok, _ }]|deps], not_ok, recompile) do
44-
partition_deps(deps, not_ok, recompile)
45-
end
43+
defp partition_deps([Mix.Dep[status: { :ok, _ }]|deps], not_ok, compile),
44+
do: partition_deps(deps, not_ok, compile)
4645

47-
defp partition_deps([Mix.Dep[status: { :noappfile, _ }] = dep|deps], not_ok, recompile) do
48-
partition_deps(deps, not_ok, [dep|recompile])
49-
end
46+
defp partition_deps([Mix.Dep[status: :compile] = dep|deps], not_ok, compile),
47+
do: partition_deps(deps, not_ok, [dep|compile])
5048

51-
defp partition_deps([dep|deps], not_ok, recompile) do
52-
partition_deps(deps, [dep|not_ok], recompile)
53-
end
49+
defp partition_deps([Mix.Dep[status: { :noappfile, _ }] = dep|deps], not_ok, compile),
50+
do: partition_deps(deps, not_ok, [dep|compile])
5451

55-
defp partition_deps([], not_ok, recompile) do
56-
{ not_ok, recompile }
57-
end
52+
defp partition_deps([dep|deps], not_ok, compile),
53+
do: partition_deps(deps, [dep|not_ok], compile)
54+
55+
defp partition_deps([], not_ok, compile),
56+
do: { not_ok, compile }
5857

5958
# If the build is per environment, we should be able to look
6059
# at all dependencies and remove the builds that no longer

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ defmodule Mix.Tasks.Deps.Compile do
2727
2828
"""
2929

30-
import Mix.Deps, only: [loaded: 0, compilable?: 1, loaded_by_name: 1,
30+
import Mix.Deps, only: [loaded: 0, available?: 1, loaded_by_name: 1,
3131
format_dep: 1, make?: 1, mix?: 1, rebar?: 1]
3232

3333
def run(args) do
@@ -41,6 +41,12 @@ defmodule Mix.Tasks.Deps.Compile do
4141
end
4242
end
4343

44+
# All available dependencies can be compiled
45+
# except for umbrella applications.
46+
defp compilable?(Mix.Dep[manager: manager, extra: extra] = dep) do
47+
available?(dep) and (manager != :mix or !extra[:umbrella?])
48+
end
49+
4450
defp do_run(deps, run_opts) do
4551
shell = Mix.shell
4652
config = Mix.Project.deps_config
@@ -69,6 +75,7 @@ defmodule Mix.Tasks.Deps.Compile do
6975
end
7076

7177
unless mix?(dep), do: build_structure(dep, config)
78+
File.rm(Path.join(opts[:build], ".compile"))
7279
compiled
7380
end
7481

lib/mix/test/mix/tasks/deps_test.exs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,17 @@ defmodule Mix.Tasks.DepsTest do
122122
end
123123
end
124124

125+
test "marks dependencies as needing compilation but automatically compile them on check" do
126+
Mix.Project.push SuccessfulDepsApp
127+
128+
in_fixture "deps_status", fn ->
129+
File.touch!("_build/dev/lib/ok/.compile")
130+
Mix.Tasks.Deps.Check.run []
131+
assert_received { :mix_shell, :info, ["* Compiling ok"] }
132+
refute File.exists?("_build/dev/lib/ok/.compile")
133+
end
134+
end
135+
125136
test "checks list of dependencies and their status on failure" do
126137
Mix.Project.push DepsApp
127138

@@ -436,8 +447,6 @@ defmodule Mix.Tasks.DepsTest do
436447

437448
message = "* Updating git_repo (#{fixture_path("git_repo")})"
438449
assert_received { :mix_shell, :info, [^message] }
439-
440-
Mix.Tasks.Deps.Check.run []
441450
end
442451
after
443452
purge [GitRepo, GitRepo.Mix]

0 commit comments

Comments
 (0)