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