Skip to content

Commit eb43a6a

Browse files
sabiwarajosevalim
authored andcommitted
Mix.install accepts atoms as paths (#12204)
1 parent fcb7b69 commit eb43a6a

File tree

3 files changed

+76
-2
lines changed

3 files changed

+76
-2
lines changed

_build/dev/lib/git_app/.mix/compile.lock

Whitespace-only changes.

lib/mix/lib/mix.ex

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,17 @@ defmodule Mix do
615615
Hexpm.Repo.query!("SELECT COUNT(1) from packages")
616616
#=> ...
617617
618+
The example above can be simplified by passing the application
619+
name as an atom for `:config_path` and `:lockfile`:
620+
621+
Mix.install(
622+
[
623+
{:hexpm, path: "/tmp/hexpm", env: :dev},
624+
],
625+
config_path: :hexpm,
626+
lockfile: :hexpm
627+
)
628+
618629
## Limitations
619630
620631
There is one limitation to `Mix.install/2`, which is actually an Elixir
@@ -682,7 +693,7 @@ defmodule Mix do
682693
end)
683694

684695
config = Keyword.get(opts, :config, [])
685-
config_path = opts[:config_path] && Path.expand(opts[:config_path])
696+
config_path = expand_path(opts[:config_path], deps, :config_path, "config/config.exs")
686697
system_env = Keyword.get(opts, :system_env, [])
687698
consolidate_protocols? = Keyword.get(opts, :consolidate_protocols, true)
688699

@@ -729,7 +740,7 @@ defmodule Mix do
729740
:ok = Mix.Local.append_archives()
730741
:ok = Mix.ProjectStack.push(@mix_install_project, config, "nofile")
731742
build_dir = Path.join(install_dir, "_build")
732-
external_lockfile = opts[:lockfile] && Path.expand(opts[:lockfile])
743+
external_lockfile = expand_path(opts[:lockfile], deps, :lockfile, "mix.lock")
733744

734745
try do
735746
first_build? = not File.dir?(build_dir)
@@ -800,6 +811,24 @@ defmodule Mix do
800811
end
801812
end
802813

814+
defp expand_path(_path = nil, _deps, _key, _), do: nil
815+
defp expand_path(path, _deps, _key, _) when is_binary(path), do: Path.expand(path)
816+
817+
defp expand_path(app_name, deps, key, relative_path) when is_atom(app_name) do
818+
app_dir =
819+
case List.keyfind(deps, app_name, 0) do
820+
{_, _, opts} when is_list(opts) -> opts[:path]
821+
{_, opts} when is_list(opts) -> opts[:path]
822+
_ -> Mix.raise("unknown dependency #{inspect(app_name)} given to #{inspect(key)}")
823+
end
824+
825+
unless app_dir do
826+
Mix.raise("#{inspect(app_name)} given to #{inspect(key)} must be a path dependency")
827+
end
828+
829+
Path.join(app_dir, relative_path)
830+
end
831+
803832
defp install_dir(cache_id) do
804833
install_root =
805834
System.get_env("MIX_INSTALL_DIR") ||

lib/mix/test/mix_test.exs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,27 @@ defmodule MixTest do
153153
Application.delete_env(:unknown_app, :foo, persistent: true)
154154
end
155155

156+
test ":config_path with application name", %{tmp_dir: tmp_dir} do
157+
config_path = Path.join(tmp_dir, "install_test/config/config.exs")
158+
config_path |> Path.dirname() |> File.mkdir_p!()
159+
160+
File.write!(config_path, """
161+
import Config
162+
config :myapp, :foo, 1
163+
""")
164+
165+
Mix.install(
166+
[
167+
{:install_test, path: Path.join(tmp_dir, "install_test")}
168+
],
169+
config_path: :install_test
170+
)
171+
172+
assert Application.fetch_env!(:myapp, :foo) == 1
173+
after
174+
Application.delete_env(:myapp, :foo)
175+
end
176+
156177
test ":config_path", %{tmp_dir: tmp_dir} do
157178
config_path = Path.join(tmp_dir, "config.exs")
158179

@@ -271,6 +292,30 @@ defmodule MixTest do
271292
purge([GitRepo, GitRepo.MixProject])
272293
end
273294

295+
test ":lockfile with application name", %{tmp_dir: tmp_dir} do
296+
lockfile = Path.join(tmp_dir, "install_test/mix.lock")
297+
lockfile |> Path.dirname() |> File.mkdir_p!()
298+
Mix.Project.push(GitApp)
299+
[_latest_rev, rev | _] = get_git_repo_revs("git_repo")
300+
Mix.Dep.Lock.write(%{git_repo: {:git, fixture_path("git_repo"), rev, []}}, file: lockfile)
301+
Mix.ProjectStack.pop()
302+
303+
Mix.install(
304+
[
305+
{:install_test, path: Path.join(tmp_dir, "install_test")},
306+
{:git_repo, git: fixture_path("git_repo")}
307+
],
308+
lockfile: :install_test,
309+
verbose: true
310+
)
311+
312+
assert_received {:mix_shell, :info, ["* Getting git_repo " <> _]}
313+
assert_received {:mix_shell, :info, ["Mix.install/2 using " <> install_dir]}
314+
assert File.read!(Path.join(install_dir, "mix.lock")) =~ rev
315+
after
316+
purge([GitRepo, GitRepo.MixProject])
317+
end
318+
274319
test ":lockfile that does not exist" do
275320
assert_raise File.Error, ~r/bad": no such file or directory/, fn ->
276321
Mix.install([], lockfile: "bad")

0 commit comments

Comments
 (0)