Skip to content

Commit 280215c

Browse files
thalesmgjosevalim
authored andcommitted
Allow bypassing application mode validation in release spec (#11506)
Today, there is a mode validation check when doing a Mix Release that prevents a parent application that has an application mode of `:permanent`, for example, while a child application has mode `:load`, as it might be unsafe. However, some complex applications may need more control over the application load/start order. For such cases, the user would need a way to tell Mix.Release to don't be strict while constructing the `.rel` file. To allow for better control over the mode validation check instead of simply disabling the check completely, we introduce the `:skip_mode_validation_for` to allow users to specify a list of applications for which the strict application mode validations should not be enforced.
1 parent 0712854 commit 280215c

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

lib/mix/lib/mix/release.ex

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -609,13 +609,24 @@ defmodule Mix.Release do
609609
end
610610

611611
defp build_release_spec(release, modes) do
612-
%{name: name, version: version, erts_version: erts_version, applications: apps} = release
612+
%{
613+
name: name,
614+
version: version,
615+
erts_version: erts_version,
616+
applications: apps,
617+
options: options
618+
} = release
619+
620+
skip_mode_validation_for =
621+
options
622+
|> Keyword.get(:skip_mode_validation_for, [])
623+
|> MapSet.new()
613624

614625
rel_apps =
615626
for {app, mode} <- modes do
616627
properties = Map.get(apps, app) || throw({:error, "Unknown application #{inspect(app)}"})
617628
children = Keyword.get(properties, :applications, [])
618-
validate_mode!(app, mode, modes, children)
629+
app in skip_mode_validation_for || validate_mode!(app, mode, modes, children)
619630
build_app_for_release(app, mode, properties)
620631
end
621632

lib/mix/lib/mix/tasks/release.ex

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,14 @@ defmodule Mix.Tasks.Release do
455455
* `:steps` - a list of steps to execute when assembling the release. See
456456
the "Steps" section for more information.
457457
458+
* `:skip_mode_validation_for` - a list of application names
459+
(atoms) specifying applications to skip strict validation of
460+
"unsafe" modes. An "unsafe" case is when a parent application
461+
mode is `:permanent` but one of the applications it depends on
462+
is set to `:load`. Use this with care, as a release with
463+
invalid modes may no longer boot without additional tweaks.
464+
Defaults to `[]`.
465+
458466
Note each release definition can be given as an anonymous function. This
459467
is useful if some release attributes are expensive to compute:
460468

lib/mix/test/mix/release_test.exs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,13 @@ defmodule Mix.ReleaseTest do
479479
assert message =~
480480
"Application :mix has mode :permanent but it depends on :elixir which is set to :none"
481481
end
482+
483+
test "does not raise on child unsafe mode if parent is in `skip_mode_validation_for`" do
484+
# `:mix` is a parent that depends on `:elixir`
485+
release = release(applications: [elixir: :load], skip_mode_validation_for: [:mix])
486+
assert make_boot_script(release, @boot_script_path, release.boot_scripts.start) == :ok
487+
assert make_boot_script(release, @boot_script_path, release.boot_scripts.start_clean) == :ok
488+
end
482489
end
483490

484491
describe "make_cookie/1" do

0 commit comments

Comments
 (0)