Skip to content

Commit b108847

Browse files
committed
Merge pull request #3745 from elixir-lang/jv-reiex
Add Mix recompilation from IEx
2 parents 3b323e1 + abc6d72 commit b108847

File tree

1 file changed

+65
-4
lines changed

1 file changed

+65
-4
lines changed

lib/iex/lib/iex/helpers.ex

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,19 @@ defmodule IEx.Helpers do
1818
* `flush/0` - flushes all messages sent to the shell
1919
* `h/0` - prints this help message
2020
* `h/1` - prints help for the given module, function or macro
21+
* `import_file/1` - evaluates the given file in the shell's context
2122
* `l/1` - loads the given module's beam code
2223
* `ls/0` - lists the contents of the current directory
2324
* `ls/1` - lists the contents of the specified directory
2425
* `pid/3` - creates a PID with the 3 integer arguments passed
2526
* `pwd/0` - prints the current working directory
26-
* `r/1` - recompiles and reloads the given module's source file
27-
* `respawn/0` - respawns the current shell
27+
* `r/1` - recompiles and reloads the given module
28+
* `recompile/0` - recompiles the current Mix project (requires iex -S mix)
29+
* `respawn/0` - respawns a new IEx shell
2830
* `s/1` - prints spec information
2931
* `t/1` - prints type information
3032
* `v/0` - retrieves the last value from the history
3133
* `v/1` - retrieves the nth value from the history
32-
* `import_file/1` - evaluates the given file in the shell's context
3334
3435
Help for functions in this module can be consulted
3536
directly from the command line, as an example, try:
@@ -52,6 +53,66 @@ defmodule IEx.Helpers do
5253

5354
import IEx, only: [dont_display_result: 0]
5455

56+
@doc """
57+
Recompiles the current Mix application.
58+
59+
This helper only works when IEx is started with a Mix
60+
project, for example, `iex -S mix`. Before compiling
61+
the code, it will stop the current application, and
62+
start it again afterwards. Stopping applications are
63+
required so processes in the supervision tree won't
64+
crash when code is upgraded multiple times without
65+
going through the proper hot-code swapping mechanism.
66+
67+
Changes to `mix.exs` or configuration files won't be
68+
picked up by this helper, only changes to sources.
69+
Restarting the shell and Mix is required in such cases.
70+
71+
If you want to reload a single module, consider using
72+
`r ModuleName` instead.
73+
74+
NOTE: This feature is experimental and may be removed
75+
in upcoming releases.
76+
"""
77+
def recompile do
78+
if mix_started? do
79+
config = Mix.Project.config
80+
reenable_tasks(config)
81+
apps = stop_apps(config)
82+
Mix.Task.run("app.start")
83+
{:restarted, apps}
84+
else
85+
IO.puts IEx.color(:eval_error, "Mix is not running. Please start IEx with: iex -S mix")
86+
:error
87+
end
88+
end
89+
90+
defp mix_started? do
91+
List.keyfind(Application.started_applications, :mix, 0) != nil
92+
end
93+
94+
defp reenable_tasks(config) do
95+
Mix.Task.reenable("app.start")
96+
Mix.Task.reenable("compile")
97+
Mix.Task.reenable("compile.all")
98+
compilers = config[:compilers] || Mix.compilers
99+
Enum.each compilers, &Mix.Task.reenable("compile.#{&1}")
100+
end
101+
102+
defp stop_apps(config) do
103+
apps =
104+
cond do
105+
Mix.Project.umbrella?(config) ->
106+
for %Mix.Dep{app: app} <- Mix.Dep.Umbrella.loaded, do: app
107+
app = config[:app] ->
108+
[app]
109+
true ->
110+
[]
111+
end
112+
apps |> Enum.reverse |> Enum.each(&Application.stop/1)
113+
apps
114+
end
115+
55116
@doc """
56117
Compiles the given files.
57118
@@ -532,7 +593,7 @@ defmodule IEx.Helpers do
532593
defp history, do: Process.get(:iex_history)
533594

534595
@doc """
535-
Creates a PID with 3 non negative integers passed as arguments
596+
Creates a PID with 3 non negative integers passed as arguments
536597
to the function.
537598
538599
## Examples

0 commit comments

Comments
 (0)