Skip to content

Commit a05a1a4

Browse files
committed
Merge pull request #4108 from tuvistavie/add-mix-debug
Add mix debug mode. Close #4106.
2 parents 2783742 + 4f2f92c commit a05a1a4

File tree

7 files changed

+81
-3
lines changed

7 files changed

+81
-3
lines changed

lib/mix/lib/mix.ex

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,24 @@ defmodule Mix do
152152
with extra clean up logic.
153153
154154
Note aliases do not show up on `mix help`.
155+
156+
## Environment variables
157+
158+
Environment variables can be used to modify Mix behaviour.
159+
160+
Mix responds to the following variables:
161+
162+
* `MIX_ARCHIVE` - allows specifying the directory into which the archives should be installed
163+
* `MIX_DEBUG` - outputs debug information about each task before running it
164+
* `MIX_ENV` - allows specifying which environment should be used. see Environments
165+
* `MIX_EXS` - allows changing the full path to the `mix.exs` file
166+
* `MIX_HOME` - stores configuration files and scripts shared by multiple implementations
167+
* `MIX_PATH` - allows expanding the code path
168+
* `MIX_QUIET` - does not print information messages to the terminal
169+
170+
Variables which do not take a value should be set to either `1` or `true`, for example:
171+
172+
$ MIX_DEBUG=1 mix compile
155173
"""
156174

157175
use Application
@@ -234,6 +252,20 @@ defmodule Mix do
234252
Mix.State.put(:shell, shell)
235253
end
236254

255+
@doc """
256+
Returns true if Mix is in debug mode.
257+
"""
258+
def debug? do
259+
Mix.State.get(:debug, false)
260+
end
261+
262+
@doc """
263+
Sets Mix debug mode.
264+
"""
265+
def debug(debug) when is_boolean(debug) do
266+
Mix.State.put(:debug, debug)
267+
end
268+
237269
@doc """
238270
Raises a Mix error that is nicely formatted.
239271
"""

lib/mix/lib/mix/cli.ex

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ defmodule Mix.CLI do
88
Mix.Local.append_archives
99
Mix.Local.append_paths
1010

11-
if System.get_env("MIX_QUIET"), do: Mix.shell(Mix.Shell.Quiet)
11+
if env_variable_activated?("MIX_QUIET"), do: Mix.shell(Mix.Shell.Quiet)
12+
if env_variable_activated?("MIX_DEBUG"), do: Mix.debug(true)
1213

1314
case check_for_shortcuts(args) do
1415
:help ->
@@ -71,6 +72,10 @@ defmodule Mix.CLI do
7172
end
7273
end
7374

75+
defp env_variable_activated?(name) do
76+
System.get_env(name) in ~w(1 true)
77+
end
78+
7479
defp ensure_hex("local.hex"),
7580
do: :ok
7681
defp ensure_hex(_task),

lib/mix/lib/mix/task.ex

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,8 @@ defmodule Mix.Task do
250250
end
251251

252252
defp run_task(proj, task, args) do
253+
if Mix.debug?, do: output_task_debug_info(task, args, proj)
254+
253255
# 1. If the task is available, we run it.
254256
# 2. Otherwise we look for it in dependencies.
255257
# 3. Finally, we compile the current project in hope it is available.
@@ -275,6 +277,16 @@ defmodule Mix.Task do
275277
end
276278
end
277279

280+
defp output_task_debug_info(task, args, proj) do
281+
Mix.shell.info("** Running mix " <> task_to_string(task, args) <> project_to_string(proj))
282+
end
283+
284+
defp project_to_string(nil), do: ""
285+
defp project_to_string(proj), do: " (inside #{inspect proj})"
286+
287+
defp task_to_string(task, []), do: task
288+
defp task_to_string(task, args), do: task <> " " <> Enum.join(args, " ")
289+
278290
defp deps_loadpaths do
279291
Mix.Task.run "deps.check"
280292
Mix.Task.run "deps.loadpaths"

lib/mix/test/mix/cli_test.exs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ defmodule Mix.CLITest do
5252

5353
assert contents =~ "Hello from MyProject!\n"
5454
refute contents =~ "This won't appear"
55+
56+
contents = mix ~w[my_hello], [{"MIX_QUIET", "0"}]
57+
assert contents =~ "This won't appear"
58+
59+
contents = mix ~w[my_hello], [{"MIX_DEBUG", "1"}]
60+
assert contents =~ "** Running mix my_hello (inside MyProject)"
61+
62+
contents = mix ~w[my_hello], [{"MIX_DEBUG", "0"}]
63+
refute contents =~ "** Running mix my_hello (inside MyProject)"
5564
end
5665
end
5766

@@ -132,7 +141,7 @@ defmodule Mix.CLITest do
132141
defp mix(args, envs \\ []) when is_list(args) do
133142
System.cmd(elixir_executable,
134143
["-r", mix_executable, "--"|args],
135-
stderr_to_stdout: true,
144+
stderr_to_stdout: true,
136145
env: envs) |> elem(0)
137146
end
138147

lib/mix/test/mix/task_test.exs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,17 @@ defmodule Mix.TaskTest do
2626
end
2727
end
2828

29+
test "output task debug info if Mix.debug? is true" do
30+
Mix.shell Mix.Shell.IO
31+
Mix.debug(true)
32+
33+
assert ExUnit.CaptureIO.capture_io(fn -> Mix.Task.run("hello") end) =~
34+
"** Running mix hello"
35+
after
36+
Mix.shell(Mix.Shell.Process)
37+
Mix.debug(false)
38+
end
39+
2940
test "try to deps.loadpaths if task is missing", context do
3041
in_tmp context.test, fn ->
3142
Mix.Project.push(SampleProject, "sample")

lib/mix/test/mix_test.exs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,11 @@ defmodule MixTest do
1212
Mix.env(:prod)
1313
assert Mix.env == :prod
1414
end
15-
end
15+
16+
test "debug" do
17+
refute Mix.debug?
18+
Mix.debug(true)
19+
assert Mix.debug?
20+
Mix.debug(false)
21+
end
22+
end

man/mix.1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ Allows specifying the directory into which the archives should be installed
6565
The
6666
.Em ~/.mix/archives
6767
directory is used for this purpose by default.
68+
.It Ev MIX_DEBUG
69+
When set, outputs debug information about each task before running it.
6870
.It Ev MIX_ENV
6971
Allows specifying which environment should be used. The
7072
.Em dev

0 commit comments

Comments
 (0)