Skip to content

Commit 1af347d

Browse files
author
José Valim
committed
Add Mix recompilation from IEx
1 parent 73b64cb commit 1af347d

File tree

1 file changed

+64
-4
lines changed

1 file changed

+64
-4
lines changed

lib/iex/lib/iex/helpers.ex

Lines changed: 64 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:
@@ -50,8 +51,67 @@ defmodule IEx.Helpers do
5051
To learn more about IEx as a whole, just type `h(IEx)`.
5152
"""
5253

54+
require Logger
5355
import IEx, only: [dont_display_result: 0]
5456

57+
@doc """
58+
Recompiles the current Mix application.
59+
60+
This helper only works when IEx is started with a Mix
61+
project, for example, `iex -S mix`. Before compiling
62+
the code, it will stop the current application, and
63+
start it again afterwards. Stopping applications are
64+
required so processes in the supervision tree won't
65+
crash when code is upgraded multiple times without
66+
going through the proper hot-code swapping mechanism.
67+
68+
Changes to `mix.exs` or configuration files won't be
69+
picked up by this helper, only changes to sources.
70+
Restarting the shell and Mix is required in such cases.
71+
72+
If you want to reload a single module, consider using
73+
`r ModuleName` instead.
74+
75+
NOTE: This feature is experimental and may be removed
76+
in upcoming releases.
77+
"""
78+
def recompile do
79+
if mix_started? do
80+
config = Mix.Project.config
81+
reenable_tasks(config)
82+
stop_apps(config)
83+
Mix.Task.run("app.start")
84+
else
85+
IO.puts IEx.color(:eval_error, "Mix is not running. Please start IEx with: iex -S mix")
86+
dont_display_result
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+
Enum.each apps, &Application.stop/1
113+
end
114+
55115
@doc """
56116
Compiles the given files.
57117
@@ -532,7 +592,7 @@ defmodule IEx.Helpers do
532592
defp history, do: Process.get(:iex_history)
533593

534594
@doc """
535-
Creates a PID with 3 non negative integers passed as arguments
595+
Creates a PID with 3 non negative integers passed as arguments
536596
to the function.
537597
538598
## Examples

0 commit comments

Comments
 (0)