Skip to content

Commit db5adc1

Browse files
author
José Valim
committed
Merge pull request #2181 from ericmj/override-undef-scm
Allow overriding of undefined dependency SCM
2 parents edfb650 + 5dd7a2b commit db5adc1

File tree

6 files changed

+81
-35
lines changed

6 files changed

+81
-35
lines changed

lib/mix/lib/mix/dep.ex

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,11 @@ defmodule Mix.Dep do
159159
def format_status(%Mix.Dep{status: { :nomatchvsn, vsn }, requirement: req}),
160160
do: "the dependency does not match the requirement #{inspect req}, got #{inspect vsn}"
161161

162+
def format_status(%Mix.Dep{status: :noscm, from: from}),
163+
do: "the dependency defined in #{Path.relative_to_cwd(from)} did not specify a supported scm, " <>
164+
"expected one of :git, :path, :in_umbrella or " <>
165+
"the package manager Hex to be installed"
166+
162167
def format_status(%Mix.Dep{status: { :lockmismatch, _ }}),
163168
do: "lock mismatch: the dependency is out of date"
164169

@@ -215,7 +220,7 @@ defmodule Mix.Dep do
215220
opts = Keyword.put(opts, :lock, rev)
216221
end
217222

218-
if available?(dep) do
223+
if scm && available?(dep) do
219224
case scm.lock_status(opts) do
220225
:mismatch ->
221226
status = if rev, do: { :lockmismatch, rev }, else: :nolock
@@ -257,11 +262,13 @@ defmodule Mix.Dep do
257262
def format_dep(%Mix.Dep{scm: scm, app: app, status: status, opts: opts}) do
258263
version =
259264
case status do
260-
{ :ok, vsn } when vsn != nil -> "#{vsn} "
265+
{ :ok, vsn } when vsn != nil -> " #{vsn}"
261266
_ -> ""
262267
end
263268

264-
"#{app} #{version}(#{scm.format(opts)})"
269+
scm_format = if scm, do: " (#{scm.format(opts)})"
270+
271+
"#{app}#{version}#{scm_format}"
265272
end
266273

267274
@doc """

lib/mix/lib/mix/dep/loader.ex

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -122,28 +122,26 @@ defmodule Mix.Dep.Loader do
122122
(new = scm.accepts_options(app, opts)) && { scm, new }
123123
end
124124

125-
if scm do
126-
%Mix.Dep{
127-
scm: scm,
128-
app: app,
129-
requirement: req,
130-
status: scm_status(scm, opts),
131-
opts: opts }
132-
else
133-
raise Mix.Error, message: "#{inspect Mix.Project.get} did not specify a supported scm " <>
134-
"for app #{inspect app}, expected one of :git, :path or :in_umbrella"
135-
end
125+
%Mix.Dep{
126+
scm: scm,
127+
app: app,
128+
requirement: req,
129+
status: scm_status(scm, opts),
130+
opts: opts }
136131
end
137132

138133
defp with_scm_and_app(other, _scms) do
139134
invalid_dep_format(other)
140135
end
141136

142137
defp scm_status(scm, opts) do
143-
if scm.checked_out?(opts) do
144-
{ :ok, nil }
145-
else
146-
{ :unavailable, opts[:dest] }
138+
cond do
139+
nil?(scm) ->
140+
:noscm
141+
scm.checked_out?(opts) ->
142+
{ :ok, nil }
143+
true ->
144+
{ :unavailable, opts[:dest] }
147145
end
148146
end
149147

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ defmodule Mix.Tasks.Deps do
9999
Enum.each loaded(loaded_opts), fn %Mix.Dep{scm: scm} = dep ->
100100
dep = check_lock(dep, lock)
101101
shell.info "* #{format_dep(dep)}"
102-
if formatted = scm.format_lock(dep.opts) do
102+
if scm && (formatted = scm.format_lock(dep.opts)) do
103103
shell.info " locked at #{formatted}"
104104
end
105105
shell.info " #{format_status dep}"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
defmodule NoSCMRepo do
2+
use Mix.Project
3+
4+
def project do
5+
[ app: :noscm_repo,
6+
version: "0.1.0",
7+
deps: [
8+
{ :git_repo, "0.1.0" }
9+
]
10+
]
11+
end
12+
end

lib/mix/test/mix/dep_test.exs

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,6 @@ defmodule Mix.DepTest do
2222
end
2323
end
2424

25-
defmodule NoSCMApp do
26-
def project do
27-
[ deps: [ { :ok, "~> 0.1", not_really: :ok } ] ]
28-
end
29-
end
30-
3125
defmodule InvalidDepsReq do
3226
def project do
3327
[ deps: [ { :ok, "+- 0.1.0", github: "elixir-lang/ok" } ] ]
@@ -58,16 +52,6 @@ defmodule Mix.DepTest do
5852
end
5953
end
6054

61-
test "raises when no SCM is specified" do
62-
Mix.Project.push NoSCMApp
63-
64-
in_fixture "deps_status", fn ->
65-
msg = "Mix.DepTest.NoSCMApp did not specify a supported scm for app :ok, " <>
66-
"expected one of :git, :path or :in_umbrella"
67-
assert_raise Mix.Error, msg, fn -> Mix.Dep.loaded([]) end
68-
end
69-
end
70-
7155
test "does not set the manager before the dependency was loaded" do
7256
# It is important to not eagerly set the manager because the dependency
7357
# needs to be loaded (i.e. available in the filesystem) in order to get

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ defmodule Mix.Tasks.DepsTest do
3939
end
4040
end
4141

42+
defmodule NoSCMApp do
43+
def project do
44+
[ deps: [ { :ok, "~> 0.1", not_really: :ok } ] ]
45+
end
46+
end
47+
4248
test "prints list of dependencies and their status" do
4349
Mix.Project.push DepsApp
4450

@@ -116,6 +122,20 @@ defmodule Mix.Tasks.DepsTest do
116122
end
117123
end
118124

125+
test "raises when no SCM is specified" do
126+
Mix.Project.push NoSCMApp
127+
128+
in_fixture "deps_status", fn ->
129+
Mix.Tasks.Deps.run []
130+
131+
msg = " the dependency defined in mix.exs did not specify a supported scm, " <>
132+
"expected one of :git, :path, :in_umbrella " <>
133+
"or the package manager Hex to be installed"
134+
assert_received { :mix_shell, :info, ["* ok"] }
135+
assert_received { :mix_shell, :info, [^msg] }
136+
end
137+
end
138+
119139
test "checks list of dependencies and their status with success" do
120140
Mix.Project.push SuccessfulDepsApp
121141

@@ -312,6 +332,19 @@ defmodule Mix.Tasks.DepsTest do
312332
end
313333
end
314334

335+
defmodule OverridenSCMApp do
336+
def project do
337+
[
338+
app: :raw_sample,
339+
version: "0.1.0",
340+
deps: [
341+
{ :noscm_repo, path: "custom/noscm_repo" },
342+
{ :git_repo, "0.1.0", git: MixTest.Case.fixture_path("git_repo"), override: true }
343+
]
344+
]
345+
end
346+
end
347+
315348
test "fails on missing dependencies" do
316349
Mix.Project.push SuccessfulDepsApp
317350

@@ -477,6 +510,18 @@ defmodule Mix.Tasks.DepsTest do
477510
purge [GitRepo, GitRepo.Mix]
478511
end
479512

513+
test "overrides unspecified SCM" do
514+
Mix.Project.push OverridenSCMApp
515+
516+
in_fixture "deps_status", fn ->
517+
Mix.Tasks.Deps.Get.run []
518+
message = "* Getting git_repo (#{fixture_path("git_repo")})"
519+
assert_received { :mix_shell, :info, [^message] }
520+
end
521+
after
522+
purge [GitRepo, GitRepo.Mix]
523+
end
524+
480525
test "updates parent dependencies" do
481526
Mix.Project.push NestedDepsApp
482527

0 commit comments

Comments
 (0)