From a2d89651d4258499b7eeef819f65bdc7b3581ab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Thu, 29 Feb 2024 23:21:10 +0700 Subject: [PATCH 1/7] Add environment variable for reusing Mix.install/2 installation --- lib/iex/lib/iex/helpers.ex | 8 +++ lib/mix/lib/mix.ex | 58 +++++++++++++++++++ lib/mix/test/mix_test.exs | 115 ++++++++++++++++++++++++++++++++----- 3 files changed, 166 insertions(+), 15 deletions(-) diff --git a/lib/iex/lib/iex/helpers.ex b/lib/iex/lib/iex/helpers.ex index 6dd7720c9d..2d922e0321 100644 --- a/lib/iex/lib/iex/helpers.ex +++ b/lib/iex/lib/iex/helpers.ex @@ -105,6 +105,14 @@ defmodule IEx.Helpers do Mix.installed?() -> Mix.in_install_project(fn -> + # TODO: remove this once Mix requires Hex with the fix from + # https://github.com/hexpm/hex/pull/1015 + # Context: Mix.install/1 starts :hex if necessary and stops + # it afterwards. Calling compile here may require hex to be + # started and that should happen automatically, but because + # of a bug it is not (fixed in the linked PR). + _ = Application.ensure_all_started(:hex) + do_recompile(options) # Just as with Mix.install/2 we clear all task invocations, # so that we can recompile the dependencies again next time diff --git a/lib/mix/lib/mix.ex b/lib/mix/lib/mix.ex index dfd7e244c3..70dc28ff39 100644 --- a/lib/mix/lib/mix.ex +++ b/lib/mix/lib/mix.ex @@ -661,6 +661,13 @@ defmodule Mix do This function can only be called outside of a Mix project and only with the same dependencies in the given VM. + The `MIX_INSTALL_RESTORE_PROJECT_DIR` environment variable may be specified. + It should point to a previous installation directory, which can be obtained + with `Mix.install_project_dir/0` (after calling `Mix.install/2`). Using a + restore dir may speed up the installation, since matching dependencies do + not need be refetched nor recompiled. This environment variable is ignored + if `:force` is enabled. + ## Options * `:force` - if `true`, runs with empty install cache. This is useful when you want @@ -870,6 +877,13 @@ defmodule Mix do try do first_build? = not File.dir?(build_dir) + + restore_dir = System.get_env("MIX_INSTALL_RESTORE_PROJECT_DIR") + + if first_build? and restore_dir != nil and not force? do + File.cp_r!(restore_dir, install_dir) + end + File.mkdir_p!(install_dir) File.cd!(install_dir, fn -> @@ -928,6 +942,10 @@ defmodule Mix do end end + if restore_dir do + remove_leftover_deps!(install_dir) + end + Mix.State.put(:installed, {id, dynamic_config}) :ok after @@ -965,6 +983,31 @@ defmodule Mix do Path.join(app_dir, relative_path) end + defp remove_leftover_deps!(install_dir) do + build_lib_dir = Path.join([install_dir, "_build", "dev", "lib"]) + deps_dir = Path.join(install_dir, "deps") + + deps = build_lib_dir |> File.ls!() |> MapSet.new() + + loaded_deps = + for {app, _description, _version} <- Application.loaded_applications(), + into: MapSet.new(), + do: Atom.to_string(app) + + leftover_deps = + deps + |> MapSet.difference(loaded_deps) + # We want to keep :mix_install, but it has no application + |> MapSet.delete("mix_install") + + for dep <- leftover_deps do + build_path = Path.join(build_lib_dir, dep) + File.rm_rf!(build_path) + dep_path = Path.join(deps_dir, dep) + File.rm_rf!(dep_path) + end + end + defp install_dir(cache_id) do install_root = System.get_env("MIX_INSTALL_DIR") || @@ -1013,6 +1056,21 @@ defmodule Mix do end end + @doc """ + Returns the directory where the current `Mix.install/2` project + resides. + """ + @spec install_project_dir() :: Path.t() + def install_project_dir() do + case Mix.State.get(:installed) do + {id, _dynamic_config} -> + install_dir(id) + + nil -> + Mix.raise("trying to call Mix.install_project_dir/0, but Mix.install/2 was never called") + end + end + @doc """ Returns whether `Mix.install/2` was called in the current node. """ diff --git a/lib/mix/test/mix_test.exs b/lib/mix/test/mix_test.exs index 618d4cba67..f1f0b814d8 100644 --- a/lib/mix/test/mix_test.exs +++ b/lib/mix/test/mix_test.exs @@ -270,8 +270,6 @@ defmodule MixTest do assert_received {:mix_shell, :info, ["* Getting git_repo " <> _]} assert_received {:mix_shell, :info, ["Mix.install/2 using " <> install_dir]} assert File.read!(Path.join(install_dir, "mix.lock")) =~ rev - after - purge([GitRepo, GitRepo.MixProject]) end test ":lockfile merging", %{tmp_dir: tmp_dir} do @@ -301,8 +299,6 @@ defmodule MixTest do ) assert File.read!(Path.join(install_dir, "mix.lock")) =~ rev1 - after - purge([GitRepo, GitRepo.MixProject]) end test ":lockfile with application name", %{tmp_dir: tmp_dir} do @@ -325,8 +321,6 @@ defmodule MixTest do assert_received {:mix_shell, :info, ["* Getting git_repo " <> _]} assert_received {:mix_shell, :info, ["Mix.install/2 using " <> install_dir]} assert File.read!(Path.join(install_dir, "mix.lock")) =~ rev - after - purge([GitRepo, GitRepo.MixProject]) end test ":lockfile that does not exist" do @@ -335,6 +329,73 @@ defmodule MixTest do end end + test "restore dir", %{tmp_dir: tmp_dir} do + with_cleanup(fn -> + Mix.install([ + {:git_repo, git: fixture_path("git_repo")} + ]) + + assert_received {:mix_shell, :info, ["* Getting git_repo " <> _]} + assert_received {:mix_shell, :info, ["==> git_repo"]} + assert_received {:mix_shell, :info, ["Compiling 1 file (.ex)"]} + assert_received {:mix_shell, :info, ["Generated git_repo app"]} + refute_received _ + + install_dir = Mix.install_project_dir() + build_lib_path = Path.join([install_dir, "_build", "dev", "lib"]) + deps_path = Path.join([install_dir, "deps"]) + + assert File.ls!(build_lib_path) |> Enum.sort() == ["git_repo", "mix_install"] + assert File.ls!(deps_path) == ["git_repo"] + + System.put_env("MIX_INSTALL_RESTORE_PROJECT_DIR", install_dir) + end) + + # Adding a dependency + + with_cleanup(fn -> + Mix.install([ + {:git_repo, git: fixture_path("git_repo")}, + {:install_test, path: Path.join(tmp_dir, "install_test")} + ]) + + assert_received {:mix_shell, :info, ["==> install_test"]} + assert_received {:mix_shell, :info, ["Compiling 2 files (.ex)"]} + assert_received {:mix_shell, :info, ["Generated install_test app"]} + refute_received _ + + install_dir = Mix.install_project_dir() + build_lib_path = Path.join([install_dir, "_build", "dev", "lib"]) + deps_path = Path.join([install_dir, "deps"]) + + assert File.ls!(build_lib_path) |> Enum.sort() == + ["git_repo", "install_test", "mix_install"] + + assert File.ls!(deps_path) == ["git_repo"] + + System.put_env("MIX_INSTALL_RESTORE_PROJECT_DIR", install_dir) + end) + + # Removing a dependency + + with_cleanup(fn -> + Mix.install([ + {:install_test, path: Path.join(tmp_dir, "install_test")} + ]) + + refute_received _ + + install_dir = Mix.install_project_dir() + build_lib_path = Path.join([install_dir, "_build", "dev", "lib"]) + deps_path = Path.join([install_dir, "deps"]) + + assert File.ls!(build_lib_path) |> Enum.sort() == ["install_test", "mix_install"] + assert File.ls!(deps_path) == [] + end) + after + System.delete_env("MIX_INSTALL_RESTORE_PROJECT_DIR") + end + test "installed?", %{tmp_dir: tmp_dir} do refute Mix.installed?() @@ -380,15 +441,7 @@ defmodule MixTest do on_exit(fn -> :code.set_path(path) - purge([InstallTest, InstallTest.MixProject, InstallTest.Protocol]) - - ExUnit.CaptureLog.capture_log(fn -> - Application.stop(:git_repo) - Application.unload(:git_repo) - - Application.stop(:install_test) - Application.unload(:install_test) - end) + cleanup_deps() end) Mix.State.put(:installed, nil) @@ -424,5 +477,37 @@ defmodule MixTest do [tmp_dir: tmp_dir] end + + defp with_cleanup(fun) do + path = :code.get_path() + + try do + fun.() + after + :code.set_path(path) + cleanup_deps() + + Mix.State.clear_cache() + Mix.State.put(:installed, nil) + end + end + + defp cleanup_deps() do + purge([ + GitRepo, + GitRepo.MixProject, + InstallTest, + InstallTest.MixProject, + InstallTest.Protocol + ]) + + ExUnit.CaptureLog.capture_log(fn -> + Application.stop(:git_repo) + Application.unload(:git_repo) + + Application.stop(:install_test) + Application.unload(:install_test) + end) + end end end From 72e0269bf5c301bbf7fa68866011ba1b1346c3d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Thu, 29 Feb 2024 18:51:14 +0100 Subject: [PATCH 2/7] Update lib/mix/lib/mix.ex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: José Valim --- lib/mix/lib/mix.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/mix/lib/mix.ex b/lib/mix/lib/mix.ex index 70dc28ff39..45d19b7537 100644 --- a/lib/mix/lib/mix.ex +++ b/lib/mix/lib/mix.ex @@ -1067,7 +1067,7 @@ defmodule Mix do install_dir(id) nil -> - Mix.raise("trying to call Mix.install_project_dir/0, but Mix.install/2 was never called") + nil end end From 8a3f375ff599ac10c58d9af0fce9048660ad5129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Thu, 29 Feb 2024 18:52:53 +0100 Subject: [PATCH 3/7] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: José Valim --- lib/mix/lib/mix.ex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/mix/lib/mix.ex b/lib/mix/lib/mix.ex index 45d19b7537..2be6979a68 100644 --- a/lib/mix/lib/mix.ex +++ b/lib/mix/lib/mix.ex @@ -881,7 +881,7 @@ defmodule Mix do restore_dir = System.get_env("MIX_INSTALL_RESTORE_PROJECT_DIR") if first_build? and restore_dir != nil and not force? do - File.cp_r!(restore_dir, install_dir) + File.cp_r(restore_dir, install_dir) end File.mkdir_p!(install_dir) @@ -1002,9 +1002,9 @@ defmodule Mix do for dep <- leftover_deps do build_path = Path.join(build_lib_dir, dep) - File.rm_rf!(build_path) + File.rm_rf(build_path) dep_path = Path.join(deps_dir, dep) - File.rm_rf!(dep_path) + File.rm_rf(dep_path) end end From 2dca0a3e7f9ca946db4497fc49cf360155f46b6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Thu, 29 Feb 2024 23:54:54 +0700 Subject: [PATCH 4/7] Simplify tests to use Mix.install_project_dir/0 --- lib/mix/test/mix_test.exs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/lib/mix/test/mix_test.exs b/lib/mix/test/mix_test.exs index f1f0b814d8..58bbda40f3 100644 --- a/lib/mix/test/mix_test.exs +++ b/lib/mix/test/mix_test.exs @@ -263,27 +263,25 @@ defmodule MixTest do [ {:git_repo, git: fixture_path("git_repo")} ], - lockfile: lockfile, - verbose: true + lockfile: lockfile ) assert_received {:mix_shell, :info, ["* Getting git_repo " <> _]} - assert_received {:mix_shell, :info, ["Mix.install/2 using " <> install_dir]} + + install_dir = Mix.install_project_dir() assert File.read!(Path.join(install_dir, "mix.lock")) =~ rev end test ":lockfile merging", %{tmp_dir: tmp_dir} do [rev1, rev2 | _] = get_git_repo_revs("git_repo") - Mix.install( - [ - {:git_repo, git: fixture_path("git_repo")} - ], - verbose: true - ) + Mix.install([ + {:git_repo, git: fixture_path("git_repo")} + ]) assert_received {:mix_shell, :info, ["* Getting git_repo " <> _]} - assert_received {:mix_shell, :info, ["Mix.install/2 using " <> install_dir]} + + install_dir = Mix.install_project_dir() assert File.read!(Path.join(install_dir, "mix.lock")) =~ rev1 Mix.Project.push(GitApp) @@ -314,12 +312,11 @@ defmodule MixTest do {:install_test, path: Path.join(tmp_dir, "install_test")}, {:git_repo, git: fixture_path("git_repo")} ], - lockfile: :install_test, - verbose: true + lockfile: :install_test ) assert_received {:mix_shell, :info, ["* Getting git_repo " <> _]} - assert_received {:mix_shell, :info, ["Mix.install/2 using " <> install_dir]} + install_dir = Mix.install_project_dir() assert File.read!(Path.join(install_dir, "mix.lock")) =~ rev end From e361ccd8563251d612cd568c389fd1ebb6352f32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Fri, 1 Mar 2024 00:55:24 +0700 Subject: [PATCH 5/7] Up --- lib/mix/lib/mix.ex | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/lib/mix/lib/mix.ex b/lib/mix/lib/mix.ex index 2be6979a68..817d752650 100644 --- a/lib/mix/lib/mix.ex +++ b/lib/mix/lib/mix.ex @@ -943,7 +943,7 @@ defmodule Mix do end if restore_dir do - remove_leftover_deps!(install_dir) + remove_leftover_deps(install_dir) end Mix.State.put(:installed, {id, dynamic_config}) @@ -983,24 +983,21 @@ defmodule Mix do Path.join(app_dir, relative_path) end - defp remove_leftover_deps!(install_dir) do + defp remove_leftover_deps(install_dir) do build_lib_dir = Path.join([install_dir, "_build", "dev", "lib"]) deps_dir = Path.join(install_dir, "deps") - deps = build_lib_dir |> File.ls!() |> MapSet.new() + deps = File.ls!(build_lib_dir) loaded_deps = for {app, _description, _version} <- Application.loaded_applications(), into: MapSet.new(), do: Atom.to_string(app) - leftover_deps = - deps - |> MapSet.difference(loaded_deps) - # We want to keep :mix_install, but it has no application - |> MapSet.delete("mix_install") + # We want to keep :mix_install, but it has no application + loaded_deps = MapSet.put(loaded_deps, "mix_install") - for dep <- leftover_deps do + for dep <- deps, not MapSet.member?(loaded_deps, dep) do build_path = Path.join(build_lib_dir, dep) File.rm_rf(build_path) dep_path = Path.join(deps_dir, dep) From 5e9637aaad3173b229e7b54b9d5d986eb53db551 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Thu, 29 Feb 2024 18:59:22 +0100 Subject: [PATCH 6/7] Update lib/mix/lib/mix.ex --- lib/mix/lib/mix.ex | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/mix/lib/mix.ex b/lib/mix/lib/mix.ex index 817d752650..fa87464586 100644 --- a/lib/mix/lib/mix.ex +++ b/lib/mix/lib/mix.ex @@ -1060,11 +1060,8 @@ defmodule Mix do @spec install_project_dir() :: Path.t() def install_project_dir() do case Mix.State.get(:installed) do - {id, _dynamic_config} -> - install_dir(id) - - nil -> - nil + {id, _dynamic_config} -> install_dir(id) + nil -> nil end end From becbb98ef62884654edcca00cdd14c4186d4b81d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonatan=20K=C5=82osko?= Date: Fri, 1 Mar 2024 01:07:30 +0700 Subject: [PATCH 7/7] Up --- lib/mix/lib/mix.ex | 34 +++++++++++++++++----------------- lib/mix/test/mix_test.exs | 36 ++++++++++++++++++------------------ 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/lib/mix/lib/mix.ex b/lib/mix/lib/mix.ex index fa87464586..ff2563334f 100644 --- a/lib/mix/lib/mix.ex +++ b/lib/mix/lib/mix.ex @@ -852,14 +852,14 @@ defmodule Mix do Application.put_all_env(config, persistent: true) System.put_env(system_env) - install_dir = install_dir(id) + install_project_dir = install_project_dir(id) if Keyword.fetch!(opts, :verbose) do - Mix.shell().info("Mix.install/2 using #{install_dir}") + Mix.shell().info("Mix.install/2 using #{install_project_dir}") end if force? do - File.rm_rf!(install_dir) + File.rm_rf!(install_project_dir) end dynamic_config = [ @@ -872,7 +872,7 @@ defmodule Mix do started_apps = Application.started_applications() :ok = Mix.ProjectStack.push(@mix_install_project, config, "nofile") - build_dir = Path.join(install_dir, "_build") + build_dir = Path.join(install_project_dir, "_build") external_lockfile = expand_path(opts[:lockfile], deps, :lockfile, "mix.lock") try do @@ -881,19 +881,19 @@ defmodule Mix do restore_dir = System.get_env("MIX_INSTALL_RESTORE_PROJECT_DIR") if first_build? and restore_dir != nil and not force? do - File.cp_r(restore_dir, install_dir) + File.cp_r(restore_dir, install_project_dir) end - File.mkdir_p!(install_dir) + File.mkdir_p!(install_project_dir) - File.cd!(install_dir, fn -> + File.cd!(install_project_dir, fn -> if config_path do Mix.Task.rerun("loadconfig") end cond do external_lockfile -> - md5_path = Path.join(install_dir, "merge.lock.md5") + md5_path = Path.join(install_project_dir, "merge.lock.md5") old_md5 = case File.read(md5_path) do @@ -904,7 +904,7 @@ defmodule Mix do new_md5 = external_lockfile |> File.read!() |> :erlang.md5() if old_md5 != new_md5 do - lockfile = Path.join(install_dir, "mix.lock") + lockfile = Path.join(install_project_dir, "mix.lock") old_lock = Mix.Dep.Lock.read(lockfile) new_lock = Mix.Dep.Lock.read(external_lockfile) Mix.Dep.Lock.write(Map.merge(old_lock, new_lock), file: lockfile) @@ -943,7 +943,7 @@ defmodule Mix do end if restore_dir do - remove_leftover_deps(install_dir) + remove_leftover_deps(install_project_dir) end Mix.State.put(:installed, {id, dynamic_config}) @@ -983,9 +983,9 @@ defmodule Mix do Path.join(app_dir, relative_path) end - defp remove_leftover_deps(install_dir) do - build_lib_dir = Path.join([install_dir, "_build", "dev", "lib"]) - deps_dir = Path.join(install_dir, "deps") + defp remove_leftover_deps(install_project_dir) do + build_lib_dir = Path.join([install_project_dir, "_build", "dev", "lib"]) + deps_dir = Path.join(install_project_dir, "deps") deps = File.ls!(build_lib_dir) @@ -1005,7 +1005,7 @@ defmodule Mix do end end - defp install_dir(cache_id) do + defp install_project_dir(cache_id) do install_root = System.get_env("MIX_INSTALL_DIR") || Path.join(Mix.Utils.mix_cache(), "installs") @@ -1036,9 +1036,9 @@ defmodule Mix do {id, dynamic_config} -> config = install_project_config(dynamic_config) - install_dir = install_dir(id) + install_project_dir = install_project_dir(id) - File.cd!(install_dir, fn -> + File.cd!(install_project_dir, fn -> :ok = Mix.ProjectStack.push(@mix_install_project, config, "nofile") try do @@ -1060,7 +1060,7 @@ defmodule Mix do @spec install_project_dir() :: Path.t() def install_project_dir() do case Mix.State.get(:installed) do - {id, _dynamic_config} -> install_dir(id) + {id, _dynamic_config} -> install_project_dir(id) nil -> nil end end diff --git a/lib/mix/test/mix_test.exs b/lib/mix/test/mix_test.exs index 58bbda40f3..266533fcdb 100644 --- a/lib/mix/test/mix_test.exs +++ b/lib/mix/test/mix_test.exs @@ -268,8 +268,8 @@ defmodule MixTest do assert_received {:mix_shell, :info, ["* Getting git_repo " <> _]} - install_dir = Mix.install_project_dir() - assert File.read!(Path.join(install_dir, "mix.lock")) =~ rev + install_project_dir = Mix.install_project_dir() + assert File.read!(Path.join(install_project_dir, "mix.lock")) =~ rev end test ":lockfile merging", %{tmp_dir: tmp_dir} do @@ -281,8 +281,8 @@ defmodule MixTest do assert_received {:mix_shell, :info, ["* Getting git_repo " <> _]} - install_dir = Mix.install_project_dir() - assert File.read!(Path.join(install_dir, "mix.lock")) =~ rev1 + install_project_dir = Mix.install_project_dir() + assert File.read!(Path.join(install_project_dir, "mix.lock")) =~ rev1 Mix.Project.push(GitApp) lockfile = Path.join(tmp_dir, "lock") @@ -296,7 +296,7 @@ defmodule MixTest do lockfile: lockfile ) - assert File.read!(Path.join(install_dir, "mix.lock")) =~ rev1 + assert File.read!(Path.join(install_project_dir, "mix.lock")) =~ rev1 end test ":lockfile with application name", %{tmp_dir: tmp_dir} do @@ -316,8 +316,8 @@ defmodule MixTest do ) assert_received {:mix_shell, :info, ["* Getting git_repo " <> _]} - install_dir = Mix.install_project_dir() - assert File.read!(Path.join(install_dir, "mix.lock")) =~ rev + install_project_dir = Mix.install_project_dir() + assert File.read!(Path.join(install_project_dir, "mix.lock")) =~ rev end test ":lockfile that does not exist" do @@ -338,14 +338,14 @@ defmodule MixTest do assert_received {:mix_shell, :info, ["Generated git_repo app"]} refute_received _ - install_dir = Mix.install_project_dir() - build_lib_path = Path.join([install_dir, "_build", "dev", "lib"]) - deps_path = Path.join([install_dir, "deps"]) + install_project_dir = Mix.install_project_dir() + build_lib_path = Path.join([install_project_dir, "_build", "dev", "lib"]) + deps_path = Path.join([install_project_dir, "deps"]) assert File.ls!(build_lib_path) |> Enum.sort() == ["git_repo", "mix_install"] assert File.ls!(deps_path) == ["git_repo"] - System.put_env("MIX_INSTALL_RESTORE_PROJECT_DIR", install_dir) + System.put_env("MIX_INSTALL_RESTORE_PROJECT_DIR", install_project_dir) end) # Adding a dependency @@ -361,16 +361,16 @@ defmodule MixTest do assert_received {:mix_shell, :info, ["Generated install_test app"]} refute_received _ - install_dir = Mix.install_project_dir() - build_lib_path = Path.join([install_dir, "_build", "dev", "lib"]) - deps_path = Path.join([install_dir, "deps"]) + install_project_dir = Mix.install_project_dir() + build_lib_path = Path.join([install_project_dir, "_build", "dev", "lib"]) + deps_path = Path.join([install_project_dir, "deps"]) assert File.ls!(build_lib_path) |> Enum.sort() == ["git_repo", "install_test", "mix_install"] assert File.ls!(deps_path) == ["git_repo"] - System.put_env("MIX_INSTALL_RESTORE_PROJECT_DIR", install_dir) + System.put_env("MIX_INSTALL_RESTORE_PROJECT_DIR", install_project_dir) end) # Removing a dependency @@ -382,9 +382,9 @@ defmodule MixTest do refute_received _ - install_dir = Mix.install_project_dir() - build_lib_path = Path.join([install_dir, "_build", "dev", "lib"]) - deps_path = Path.join([install_dir, "deps"]) + install_project_dir = Mix.install_project_dir() + build_lib_path = Path.join([install_project_dir, "_build", "dev", "lib"]) + deps_path = Path.join([install_project_dir, "deps"]) assert File.ls!(build_lib_path) |> Enum.sort() == ["install_test", "mix_install"] assert File.ls!(deps_path) == []