@@ -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