Skip to content

Commit b43a6a9

Browse files
GazlerJosé Valim
authored andcommitted
Allow {:from_app, app_name} as a version for releases (#9280)
Sometimes it is desireable to lookup the version from another application to use as the version for a release. This is true in the case of umbrella applications, where a particular app may be targetted for a release. Using `{:from_app, :my_app}` will allow the version returned from `Application.spec(:my_app, :vsn)` to be used as the version.
1 parent e60fe36 commit b43a6a9

File tree

3 files changed

+40
-4
lines changed

3 files changed

+40
-4
lines changed

lib/mix/lib/mix/release.ex

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ defmodule Mix.Release do
77
The Mix.Release struct has the following read-only fields:
88
99
* `:name` - the name of the release as an atom
10-
* `:version` - the version of the release as a string
10+
* `:version` - the version of the release as a string or
11+
`{:from_app, app_name}
1112
* `:path` - the path to the release root
1213
* `:version_path` - the path to the release version inside the release
1314
* `:applications` - a map of application with their definitions
@@ -47,7 +48,7 @@ defmodule Mix.Release do
4748
name: atom(),
4849
version: String.t(),
4950
path: String.t(),
50-
version_path: String.t(),
51+
version_path: String.t() | {:from_app, application()},
5152
applications: %{application() => keyword()},
5253
boot_scripts: %{atom() => [{application(), mode()}]},
5354
erts_version: charlist(),
@@ -112,6 +113,24 @@ defmodule Mix.Release do
112113
)
113114
end)
114115

116+
version =
117+
case version do
118+
{:from_app, app} ->
119+
Application.load(app)
120+
version = Application.spec(app, :vsn)
121+
122+
if !version do
123+
Mix.raise(
124+
"Could not find version for #{inspect(app)}, please make sure the application exists"
125+
)
126+
end
127+
128+
to_string(version)
129+
130+
_ ->
131+
version
132+
end
133+
115134
{config_providers, opts} = Keyword.pop(opts, :config_providers, [])
116135
{steps, opts} = Keyword.pop(opts, :steps, [:assemble])
117136
validate_steps!(steps)

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,8 +386,10 @@ defmodule Mix.Tasks.Release do
386386
* `:path` - the path the release should be installed to.
387387
Defaults to `"_build/MIX_ENV/rel/RELEASE_NAME"`.
388388
389-
* `:version` - the release version as a string. Defaults to the current
390-
application version.
389+
* `:version` - the release version as a string or `{:from_app, app_name}`.
390+
Defaults to the current application version. The `{:from_app, app_name}` format
391+
can be used to easily reference the application version from another application.
392+
This is particularly useful in umbrella applications.
391393
392394
* `:quiet` - a boolean that controls if releases should write to the standard
393395
output its steps. Defaults to `false`.

lib/mix/test/mix/release_test.exs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ defmodule Mix.ReleaseTest do
5050
assert release.options[:quiet]
5151
end
5252

53+
test "allows specifying the version from an application" do
54+
overrides = [version: {:from_app, :elixir}]
55+
release = from_config!(nil, config(), overrides)
56+
57+
assert release.version == to_string(Application.spec(:elixir, :vsn))
58+
end
59+
60+
test "raises when :from_app is used with an app that doesn't exist" do
61+
overrides = [version: {:from_app, :not_valid}]
62+
63+
assert_raise Mix.Error,
64+
~r"Could not find version for :not_valid, please make sure the application exists",
65+
fn -> from_config!(nil, config(), overrides) end
66+
end
67+
5368
test "includes applications" do
5469
release = from_config!(nil, config(), [])
5570
assert release.applications.mix[:path] == to_charlist(Application.app_dir(:mix))

0 commit comments

Comments
 (0)