Skip to content

Commit c4e8ad0

Browse files
author
José Valim
committed
Support start_permanent
1 parent ce77fa5 commit c4e8ad0

File tree

3 files changed

+69
-27
lines changed

3 files changed

+69
-27
lines changed

lib/mix/lib/mix/project.ex

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,8 @@ defmodule Mix.Project do
400400
erlc_include_path: "include",
401401
erlc_options: [:debug_info],
402402
lockfile: "mix.lock",
403-
preferred_cli_env: []]
403+
preferred_cli_env: [],
404+
start_permanent: false]
404405
end
405406

406407
defp get_project_config(nil), do: []

lib/mix/lib/mix/tasks/app.start.ex

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,23 @@
11
defmodule Mix.Tasks.App.Start do
22
use Mix.Task
33

4+
@shortdoc "Start all registered apps"
45
@recursive true
56

67
@moduledoc """
7-
Starts all registered apps. If no apps key exists,
8-
it starts the current application.
8+
Starts all registered apps.
9+
10+
The application is started by default as temporary. In case
11+
`:start_permanent` is set to true in your prject configuration
12+
or the `--permanent` flag is given, it is started as permanent,
13+
which guarantee the node will shutdown in case the application
14+
crashes permanently.
915
1016
## Command line options
1117
1218
* `--force` - force compilation regardless of compilation times
19+
* `--temporary` - start the application as temporary
20+
* `--permanent` - start the application as permanent
1321
* `--no-compile` - do not compile even if files require compilation
1422
* `--no-protocols` - do not load consolidated protocols
1523
* `--no-deps-check` - do not check dependencies
@@ -20,6 +28,8 @@ defmodule Mix.Tasks.App.Start do
2028
@spec run(OptionParser.argv) :: :ok
2129
def run(args) do
2230
Mix.Project.get!
31+
32+
{opts, _, _} = OptionParser.parse args, switches: [permanent: :boolean, temporary: :boolean]
2333
Mix.Task.run "loadpaths", args
2434

2535
unless "--no-compile" in args do
@@ -47,14 +57,14 @@ defmodule Mix.Tasks.App.Start do
4757
#
4858
# Mix should not depend directly on Logger so check that it's loaded.
4959
if Code.ensure_loaded?(Logger), do: Logger.App.stop()
50-
start(Mix.Project.config[:app])
60+
start(Mix.Project.config, opts)
5161
end
5262
end
5363

5464
@doc false
55-
def start(app) do
56-
if app do
57-
case Application.ensure_all_started(app) do
65+
def start(config, opts) do
66+
if app = config[:app] do
67+
case Application.ensure_all_started(app, type(config, opts)) do
5868
{:ok, _} -> :ok
5969
{:error, {app, reason}} ->
6070
Mix.raise "Could not start application #{app}: " <>
@@ -64,4 +74,14 @@ defmodule Mix.Tasks.App.Start do
6474
:error
6575
end
6676
end
77+
78+
@doc false
79+
def type(config, opts) do
80+
cond do
81+
opts[:temporary] -> :temporary
82+
opts[:permanent] -> :permanent
83+
config[:start_permanent] -> :permanent
84+
true -> :temporary
85+
end
86+
end
6787
end

lib/mix/test/mix/tasks/app.start_test.exs

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ defmodule Mix.Tasks.App.StartTest do
55

66
defmodule AppStartSample do
77
def project do
8-
[app: :app_start_sample, version: "0.1.0"]
8+
[app: :app_start_sample, version: "0.1.0", start_permanent: true]
99
end
1010

1111
def application do
@@ -89,7 +89,14 @@ defmodule Mix.Tasks.App.StartTest do
8989
end
9090

9191
test "start does nothing if app is nil" do
92-
assert Mix.Tasks.App.Start.start(nil) == :error
92+
assert Mix.Tasks.App.Start.start([app: nil], []) == :error
93+
end
94+
95+
test "allows type to be configured" do
96+
assert Mix.Tasks.App.Start.type([], [permanent: true]) == :permanent
97+
assert Mix.Tasks.App.Start.type([], [temporary: true]) == :temporary
98+
assert Mix.Tasks.App.Start.type([start_permanent: true], []) == :permanent
99+
assert Mix.Tasks.App.Start.type([], []) == :temporary
93100
end
94101

95102
defmodule ReturnSample do
@@ -115,9 +122,12 @@ defmodule Mix.Tasks.App.StartTest do
115122
Process.put(:application_definition, mod: {ReturnApp, {:error, :bye}})
116123
Mix.Tasks.Compile.run []
117124

118-
assert_raise Mix.Error, "Could not start application return_sample: Mix.Tasks.App.StartTest.ReturnApp.start(:normal, {:error, :bye}) returned an error: :bye",
119-
fn ->
120-
Mix.Tasks.App.Start.start(:return_sample)
125+
message = "Could not start application return_sample: " <>
126+
"Mix.Tasks.App.StartTest.ReturnApp.start(:normal, {:error, :bye}) " <>
127+
"returned an error: :bye"
128+
129+
assert_raise Mix.Error, message, fn ->
130+
Mix.Tasks.App.Start.start([app: :return_sample], [])
121131
end
122132
end
123133
end
@@ -130,10 +140,14 @@ defmodule Mix.Tasks.App.StartTest do
130140
{:badarg, [{ReturnApp, :start, 2, []}] }}})
131141
Mix.Tasks.Compile.run []
132142

133-
assert_raise Mix.Error, "Could not start application return_sample: Mix.Tasks.App.StartTest.ReturnApp.start(:normal, {:error, {:badarg, [{Mix.Tasks.App.StartTest.ReturnApp, :start, 2, []}]}}) returned an error: an exception was raised:\n" <>
134-
" ** (ArgumentError) argument error\n" <>
135-
" Mix.Tasks.App.StartTest.ReturnApp.start/2", fn ->
136-
Mix.Tasks.App.Start.start(:return_sample)
143+
message = "Could not start application return_sample: " <>
144+
"Mix.Tasks.App.StartTest.ReturnApp.start(:normal, {:error, {:badarg, [{Mix.Tasks.App.StartTest.ReturnApp, :start, 2, []}]}}) " <>
145+
"returned an error: an exception was raised:\n" <>
146+
" ** (ArgumentError) argument error\n" <>
147+
" Mix.Tasks.App.StartTest.ReturnApp.start/2"
148+
149+
assert_raise Mix.Error, message, fn ->
150+
Mix.Tasks.App.Start.start([app: :return_sample], [])
137151
end
138152
end
139153
end
@@ -145,9 +159,12 @@ defmodule Mix.Tasks.App.StartTest do
145159
Process.put(:application_definition, mod: {ReturnApp, :bad})
146160
Mix.Tasks.Compile.run []
147161

148-
assert_raise Mix.Error, "Could not start application return_sample: Mix.Tasks.App.StartTest.ReturnApp.start(:normal, :bad) returned a bad value: :bad",
149-
fn ->
150-
Mix.Tasks.App.Start.start(:return_sample)
162+
message = "Could not start application return_sample: " <>
163+
"Mix.Tasks.App.StartTest.ReturnApp.start(:normal, :bad) " <>
164+
"returned a bad value: :bad"
165+
166+
assert_raise Mix.Error, message, fn ->
167+
Mix.Tasks.App.Start.start([app: :return_sample], [])
151168
end
152169
end
153170
end
@@ -175,10 +192,12 @@ defmodule Mix.Tasks.App.StartTest do
175192
Process.put(:application_definition, mod: {ExitApp, :bye})
176193
Mix.Tasks.Compile.run []
177194

178-
assert_raise Mix.Error, "Could not start application exit_sample: exited in: Mix.Tasks.App.StartTest.ExitApp.start(:normal, :bye)\n" <>
179-
" ** (EXIT) :bye",
180-
fn ->
181-
Mix.Tasks.App.Start.start(:exit_sample)
195+
message = "Could not start application exit_sample: exited in: " <>
196+
"Mix.Tasks.App.StartTest.ExitApp.start(:normal, :bye)\n" <>
197+
" ** (EXIT) :bye"
198+
199+
assert_raise Mix.Error, message, fn ->
200+
Mix.Tasks.App.Start.start([app: :exit_sample], [])
182201
end
183202
end
184203
end
@@ -190,10 +209,12 @@ defmodule Mix.Tasks.App.StartTest do
190209
Process.put(:application_definition, mod: {ExitApp, :normal})
191210
Mix.Tasks.Compile.run []
192211

193-
assert_raise Mix.Error, "Could not start application exit_sample: exited in: Mix.Tasks.App.StartTest.ExitApp.start(:normal, :normal)\n" <>
194-
" ** (EXIT) normal",
195-
fn ->
196-
Mix.Tasks.App.Start.start(:exit_sample)
212+
message = "Could not start application exit_sample: exited in: " <>
213+
"Mix.Tasks.App.StartTest.ExitApp.start(:normal, :normal)\n" <>
214+
" ** (EXIT) normal"
215+
216+
assert_raise Mix.Error, message, fn ->
217+
Mix.Tasks.App.Start.start([app: :exit_sample], [])
197218
end
198219
end
199220
end

0 commit comments

Comments
 (0)