Skip to content

Commit 456b846

Browse files
author
José Valim
committed
mix run now properly sets System.argv
1 parent ac666a9 commit 456b846

File tree

10 files changed

+47
-27
lines changed

10 files changed

+47
-27
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
* [Mix] Allow coverage tool to be pluggable via the `:test_coverage` configuration
1919
* [Mix] Add `mix cmd` as a convenience to run a command recursively in child apps in an umbrella application
2020
* [Mix] Support `umbrella: true` in dependencies as a convenience for setting up umbrella path deps
21+
* [Mix] `mix run` now behaves closer to the `elixir` command and properly mangles the ARGV
2122
* [String] Add `String.reverse/1`
2223

2324
* bug fix

lib/elixir/lib/kernel/cli.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ defmodule Kernel.CLI do
1111
argv = lc arg inlist argv, do: :unicode.characters_to_binary(arg)
1212

1313
{ config, argv } = process_argv(argv, Kernel.CLI.Config.new)
14-
:elixir_code_server.cast({ :argv, argv })
14+
System.argv(argv)
1515

1616
run fn ->
1717
command_results = Enum.map(Enum.reverse(config.commands), process_command(&1, config))

lib/elixir/lib/option_parser.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ defmodule OptionParser do
100100
parse(argv, aliases, switches, [], [], all)
101101
end
102102

103-
defp parse(["-" <> option|t], aliases, switches, dict, args, all) do
103+
defp parse(["-" <> option|t], aliases, switches, dict, args, all) when option != "-" do
104104
{ option, kinds, value } = normalize_option(option, switches, aliases)
105105

106106
if nil?(value) do

lib/elixir/lib/system.ex

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,15 @@ defmodule System do
7878
:elixir_code_server.call :argv
7979
end
8080

81+
@doc """
82+
Changes the list of command-line arguments. Use it with caution,
83+
as it destory any previous argv information.
84+
"""
85+
@spec argv([String.t]) :: :ok
86+
def argv(argv) do
87+
:elixir_code_server.cast({ :argv, argv })
88+
end
89+
8190
@doc """
8291
Returns the current working directory or `nil` if one
8392
is not available.

lib/elixir/test/elixir/option_parser_test.exs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@ defmodule OptionParserTest do
101101
assert options == { [source: "from_docs/"], ["test/enum_test.exs", "--verbose"] }
102102
end
103103

104+
test "stops on --" do
105+
options = OptionParser.parse_head(["--source", "from_docs/", "--", "1", "2", "3"])
106+
assert options == { [source: "from_docs/"], ["--", "1", "2", "3"] }
107+
end
108+
104109
test "goes beyond the first non option arguments" do
105110
options = OptionParser.parse(["--source", "from_docs/", "test/enum_test.exs", "--verbose"])
106111
assert options == { [source: "from_docs/", verbose: true], ["test/enum_test.exs"] }

lib/mix/lib/mix/tasks/run.ex

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,21 @@ defmodule Mix.Tasks.Run do
44
@shortdoc "Run the given file or expression"
55

66
@moduledoc """
7-
Runs the given file or expession in the context of the application.
7+
Runs the given file or expression in the context of the application.
88
9-
Before running the code, it invokes the app.start task
10-
which defaults to compile and load your project.
9+
Before running the code, it invokes the `app.start` task which compiles
10+
and loads your project.
11+
12+
It is the goal of this task to provide a subset of the functionality
13+
existent in the `elixir` executable, including setting up the `System.argv`:
14+
15+
mix run -e Hello.world
16+
mix run my_script.exs arg1 arg2 arg3
17+
18+
Many command line options need to be passed to the `elixir` executable
19+
directly, which can be done as follows:
20+
21+
elixir --sname hello -S mix run -e "My.code"
1122
1223
## Command line options
1324
@@ -18,16 +29,6 @@ defmodule Mix.Tasks.Run do
1829
* `--no-compile` - Does not compile even if files require compilation
1930
* `--no-start` - Does not start applications after compilation
2031
21-
## Examples
22-
23-
mix run -e Hello.world
24-
mix run -e "Some.function with_args"
25-
mix run -r some_file.exs
26-
27-
Command line options given to the `elixir` executable can be passed as:
28-
29-
elixir --sname hello -S mix run -e "My.code"
30-
3132
"""
3233
def run(args) do
3334
{ opts, head } = OptionParser.parse_head(args,
@@ -36,6 +37,13 @@ defmodule Mix.Tasks.Run do
3637

3738
Mix.Task.run "app.start", args
3839

40+
file =
41+
case head do
42+
["--"|t] -> System.argv(t); nil
43+
[h|t] -> System.argv(t); h
44+
[] -> System.argv([]); nil
45+
end
46+
3947
Enum.each opts, fn({ key, value }) ->
4048
case key do
4149
:parallel_require ->
@@ -49,10 +57,7 @@ defmodule Mix.Tasks.Run do
4957
end
5058
end
5159

52-
if head != [] do
53-
Mix.shell.error "[WARNING] mix run EXPR is deprecated, please use mix run -e EXPR instead"
54-
Code.eval_string Enum.join(head, " ")
55-
end
60+
if file, do: Code.require_file(h)
5661
if opts[:no_halt], do: :timer.sleep(:infinity)
5762
end
5863

lib/mix/test/mix/cli_test.exs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ defmodule Mix.CLITest do
77
in_fixture "only_mixfile", fn ->
88
if match? { :win32, _ }, :os.type do
99
temp_env = "set MIX_ENV=prod &"
10-
else # ie. linux
10+
else
1111
temp_env = "MIX_ENV=prod"
1212
end
1313

14-
env = System.cmd %b(#{temp_env} #{elixir_executable} #{mix_executable} run -e "IO.puts Mix.env")
15-
assert env =~ "prod"
14+
env = System.cmd %b(#{temp_env} #{elixir_executable} #{mix_executable} run -e "IO.inspect { Mix.env, System.argv }" -- 1 2 3)
15+
assert env =~ %b({:prod, ["1", "2", "3"]})
1616
end
1717
end
1818

lib/mix/test/mix/tasks/deps.git_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ defmodule Mix.Tasks.DepsGitTest do
106106

107107
# We can compile just fine
108108
Mix.Task.clear
109-
Mix.Tasks.Run.run ["1+2"]
109+
Mix.Tasks.Run.run ["-e", "1+2"]
110110

111111
# Now let's add a submodules option
112112
Mix.Project.pop

lib/mix/test/mix/tasks/deps.path_test.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ defmodule Mix.Tasks.DepsPathTest do
3939
in_fixture "deps_status", fn ->
4040
Mix.Deps.Lock.write [raw_repo: "abcdef"]
4141
Mix.Tasks.Deps.Compile.run ["raw_repo"]
42-
Mix.Tasks.Run.run ["Mix.shell.info", "RawRepo.hello"]
42+
Mix.Tasks.Run.run ["-e", "Mix.shell.info RawRepo.hello"]
4343
assert_received { :mix_shell, :info, ["world"] }
4444
end
4545
after

lib/mix/test/mix/tasks/run_test.exs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ defmodule Mix.Tasks.RunTest do
1818

1919
in_fixture "no_mixfile", fn ->
2020
Mix.Tasks.Deps.Get.run []
21-
Mix.Tasks.Run.run ["Mix.shell.info", "GitRepo.hello"]
21+
Mix.Tasks.Run.run ["-e", "Mix.shell.info GitRepo.hello"]
2222
assert_received { :mix_shell, :info, ["World"] }
2323
end
2424
after
@@ -30,10 +30,10 @@ defmodule Mix.Tasks.RunTest do
3030
git_repo = fixture_path("git_repo/lib/git_repo.ex")
3131

3232
in_fixture "no_mixfile", fn ->
33-
Mix.Tasks.Run.run ["-r", git_repo, "Mix.shell.info", "GitRepo.hello"]
33+
Mix.Tasks.Run.run ["-r", git_repo, "-e", "Mix.shell.info GitRepo.hello"]
3434
assert_received { :mix_shell, :info, ["World"] }
3535

36-
Mix.Tasks.Run.run ["-pr", git_repo, "Mix.shell.info", "GitRepo.hello"]
36+
Mix.Tasks.Run.run ["-pr", git_repo, "-e", "Mix.shell.info GitRepo.hello"]
3737
assert_received { :mix_shell, :info, ["World"] }
3838
end
3939
end

0 commit comments

Comments
 (0)