Skip to content

Commit 6440fb9

Browse files
committed
Ensure mix escript.install works with deps.partition, closes #14885
1 parent 8793c68 commit 6440fb9

File tree

3 files changed

+94
-83
lines changed

3 files changed

+94
-83
lines changed

lib/mix/lib/mix/cli.ex

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,18 +8,18 @@ defmodule Mix.CLI do
88
@doc """
99
Runs Mix according to the command line arguments.
1010
"""
11-
def main(args \\ System.argv()) do
11+
def main(args \\ System.argv(), mix_exs \\ System.get_env("MIX_EXS") || "mix.exs") do
1212
if env_variable_activated?("MIX_DEBUG") do
1313
IO.puts("-> Running mix CLI")
14-
{time, res} = :timer.tc(&main/2, [args, true])
14+
{time, res} = :timer.tc(&main/3, [args, mix_exs, true])
1515
IO.puts(["<- Ran mix CLI in ", Integer.to_string(div(time, 1000)), "ms"])
1616
res
1717
else
18-
main(args, false)
18+
main(args, mix_exs, false)
1919
end
2020
end
2121

22-
defp main(args, debug?) do
22+
defp main(args, mix_exs, debug?) do
2323
Mix.start()
2424

2525
if debug?, do: Mix.debug(true)
@@ -46,28 +46,26 @@ defmodule Mix.CLI do
4646
display_version()
4747

4848
nil ->
49-
proceed(args)
49+
proceed(args, mix_exs)
5050
end
5151
end
5252

53-
defp proceed(args) do
53+
defp proceed(args, mix_exs) do
5454
load_dot_config()
55-
load_mix_exs(args)
55+
load_mix_exs(args, mix_exs)
5656
project = Mix.Project.get()
5757
{task, args} = get_task(args, project)
5858
ensure_hex(task)
5959
maybe_change_env_and_target(task, project)
6060
run_task(task, args)
6161
end
6262

63-
defp load_mix_exs(args) do
64-
file = System.get_env("MIX_EXS") || "mix.exs"
65-
66-
if File.regular?(file) do
63+
defp load_mix_exs(args, mix_exs) do
64+
if is_binary(mix_exs) and File.regular?(mix_exs) do
6765
Mix.ProjectStack.post_config(state_loader: {:cli, List.first(args)})
6866
old_undefined = Code.get_compiler_option(:no_warn_undefined)
6967
Code.put_compiler_option(:no_warn_undefined, :all)
70-
Code.compile_file(file)
68+
Code.compile_file(mix_exs)
7169
Code.put_compiler_option(:no_warn_undefined, old_undefined)
7270
end
7371
end

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

Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ defmodule Mix.Tasks.Deps.Partition do
77

88
## Server
99

10-
@deps_partition_install_mix_exs ~c"deps.partition.mix.exs"
11-
1210
def server(deps, count, force?) do
1311
{:ok, socket} = :gen_tcp.listen(0, [:binary, packet: :line, active: false])
1412

@@ -29,41 +27,18 @@ defmodule Mix.Tasks.Deps.Partition do
2927
ansi_flag = if IO.ANSI.enabled?(), do: ~c"--color", else: ~c"--no-color"
3028
force_flag = if force?, do: ~c"--force", else: ~c"--no-force"
3129

32-
env_vars =
33-
if Mix.install?() do
34-
blob =
35-
Mix.Project.config()
36-
|> :erlang.term_to_binary()
37-
|> :binary.bin_to_list()
38-
|> Enum.join(",")
39-
40-
# We replicate the initialization logic from Mix.install/2 as part of mix.exs
41-
File.write!(@deps_partition_install_mix_exs, """
42-
config = <<#{blob}>>
43-
project = :erlang.binary_to_term(config)
44-
45-
if compile_config = project[:compile_config] do
46-
Application.put_all_env(compile_config, persistent: true)
47-
end
48-
49-
Mix.ProjectStack.push(Mix.InstallProject, project, "nofile")
50-
""")
51-
52-
[{~c"MIX_EXS", @deps_partition_install_mix_exs}]
53-
else
54-
[]
55-
end
56-
5730
args = [
5831
ansi_flag,
5932
~c"-e",
60-
~c"Mix.CLI.main",
61-
~c"deps.partition",
33+
~c"Mix.Tasks.Deps.Partition.client",
34+
~c"--",
6235
force_flag,
6336
~c"--port",
6437
Integer.to_charlist(port),
6538
~c"--host",
66-
~c"127.0.0.1"
39+
~c"127.0.0.1",
40+
~c"--config",
41+
Mix.ProjectStack.peek() |> :erlang.term_to_binary() |> Base.url_encode64()
6742
]
6843

6944
options = [
@@ -77,7 +52,6 @@ defmodule Mix.Tasks.Deps.Partition do
7752
{~c"MIX_OS_CONCURRENCY_LOCK", ~c"false"},
7853
{~c"MIX_ENV", Atom.to_charlist(Mix.env())},
7954
{~c"MIX_TARGET", Atom.to_charlist(Mix.target())}
80-
| env_vars
8155
]
8256
]
8357

@@ -241,16 +215,36 @@ defmodule Mix.Tasks.Deps.Partition do
241215

242216
## Client
243217

244-
@switches [port: :integer, host: :string, force: :boolean, index: :string]
218+
@switches [port: :integer, host: :string, force: :boolean, index: :string, config: :string]
245219

246-
@impl true
247-
def run(args) do
220+
def client do
248221
# If stdin closes, we shutdown the VM
249222
spawn(fn ->
250223
_ = IO.gets("")
251224
System.halt(0)
252225
end)
253226

227+
args = System.argv()
228+
{opts, []} = OptionParser.parse!(args, strict: @switches)
229+
peek = Keyword.fetch!(opts, :config) |> Base.url_decode64!() |> :erlang.binary_to_term()
230+
231+
# This is specific to Mix.install/2 and how it handles compile-time config
232+
if compile_config = peek.config[:compile_config] do
233+
Application.put_all_env(compile_config, persistent: true)
234+
end
235+
236+
partition_args =
237+
opts
238+
|> Keyword.take([:host, :port, :index, :force])
239+
|> OptionParser.to_argv()
240+
241+
Mix.start()
242+
Mix.ProjectStack.push(peek.name, peek.config, peek.file)
243+
Mix.CLI.main(["deps.partition" | partition_args], nil)
244+
end
245+
246+
@impl true
247+
def run(args) do
254248
{opts, []} = OptionParser.parse!(args, strict: @switches)
255249
host = Keyword.fetch!(opts, :host)
256250
port = Keyword.fetch!(opts, :port)

lib/mix/test/mix/tasks/escript_test.exs

Lines changed: 56 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -341,48 +341,67 @@ defmodule Mix.Tasks.EscriptTest do
341341
end)
342342
end
343343

344-
test "escript.install from Git" do
345-
in_fixture("git_repo", fn ->
346-
File.mkdir_p!("config")
347-
348-
File.write!("config/config.exs", """
349-
import Config
350-
config :git_repo, :escript_config, true
351-
""")
352-
353-
File.write!("lib/git_repo.ex", """
354-
require Application
355-
true = Application.compile_env!(:git_repo, :escript_config)
356-
357-
defmodule GitRepo.Escript do
358-
def main(_argv) do
359-
IO.puts("TEST")
344+
for count <- [1, 2] do
345+
test "escript.install from Git (with MIX_OS_DEPS_COMPILE_PARTITION_COUNT=#{count})" do
346+
System.put_env("MIX_OS_DEPS_COMPILE_PARTITION_COUNT", "#{unquote(count)}")
347+
348+
in_fixture("deps_status", fn ->
349+
File.mkdir_p!("config")
350+
File.mkdir_p!("lib")
351+
352+
File.write!("config/config.exs", """
353+
import Config
354+
config :source_repo, :escript_config, true
355+
""")
356+
357+
File.write!("lib/source_repo.ex", """
358+
require Application
359+
true = Application.compile_env!(:source_repo, :escript_config)
360+
361+
defmodule SourceRepo.Escript do
362+
def main(_argv) do
363+
IO.puts("TEST")
364+
end
360365
end
361-
end
362-
""")
363-
364-
File.write!("mix.exs", """
365-
defmodule GitRepo.MixProject do
366-
use Mix.Project
367-
368-
def project do
369-
[app: :git_repo, version: "0.1.0", escript: [main_module: GitRepo.Escript]]
366+
""")
367+
368+
File.write!("mix.exs", """
369+
defmodule SourceRepo.MixProject do
370+
use Mix.Project
371+
372+
def project do
373+
[
374+
app: :source_repo,
375+
version: "0.1.0",
376+
escript: [main_module: SourceRepo.Escript],
377+
deps: [
378+
{:git_repo, path: "#{MixTest.Case.fixture_path("git_repo")}"},
379+
{:git_rebar, path: "#{MixTest.Case.fixture_path("git_rebar")}", manager: :rebar3},
380+
{:ok, path: "deps/ok"},
381+
]
382+
]
383+
end
370384
end
371-
end
372-
""")
385+
""")
373386

374-
System.cmd("git", ~w[add .])
375-
System.cmd("git", ~w[commit -m "ok"])
387+
System.cmd("git", ~w[init])
388+
System.cmd("git", ~w[add .])
389+
System.cmd("git", ~w[commit -m "ok"])
376390

377-
send(self(), {:mix_shell_input, :yes?, true})
378-
Mix.Tasks.Escript.Install.run(["git", File.cwd!()])
379-
assert_received {:mix_shell, :info, ["Generated escript git_repo with MIX_ENV=prod"]}
391+
ExUnit.CaptureIO.capture_io(fn ->
392+
send(self(), {:mix_shell_input, :yes?, true})
393+
Mix.Tasks.Escript.Install.run(["git", File.cwd!()])
394+
end)
380395

381-
escript_path = Path.join([tmp_path(".mix"), "escripts", "git_repo"])
382-
assert System.cmd("escript", [escript_path]) == {"TEST\n", 0}
383-
end)
384-
after
385-
purge([GitRepo.Escript, GitRepo.MixProject, Mix.Local.Installer.MixProject])
396+
assert_received {:mix_shell, :info, ["Generated escript source_repo with MIX_ENV=prod"]}
397+
398+
escript_path = Path.join([tmp_path(".mix"), "escripts", "source_repo"])
399+
assert System.cmd("escript", [escript_path]) == {"TEST\n", 0}
400+
end)
401+
after
402+
System.delete_env("MIX_OS_DEPS_COMPILE_PARTITION_COUNT")
403+
purge([SourceRepo.Escript, SourceRepo.MixProject, Mix.Local.Installer.MixProject])
404+
end
386405
end
387406

388407
defp push_project_with_config(module, config \\ []) do

0 commit comments

Comments
 (0)