summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGary Rennie <gazler@gmail.com>2019-08-09 11:33:36 +0100
committerFernando Tapia Rico <fertapric@gmail.com>2019-08-09 12:33:36 +0200
commita914197b521c58113b4ba893e1fb30eec4928cf2 (patch)
treef4b2531135a8577f0c86d1ef2fe0cb2a02ef4fc1
parentc5d5e7f462ff04c7baf13a27eb810fe903979b7d (diff)
downloadelixir-a914197b521c58113b4ba893e1fb30eec4928cf2.tar.gz
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.
-rw-r--r--lib/mix/lib/mix/release.ex23
-rw-r--r--lib/mix/lib/mix/tasks/release.ex6
-rw-r--r--lib/mix/test/mix/release_test.exs15
3 files changed, 40 insertions, 4 deletions
diff --git a/lib/mix/lib/mix/release.ex b/lib/mix/lib/mix/release.ex
index f6cc6d7fa..be982f698 100644
--- a/lib/mix/lib/mix/release.ex
+++ b/lib/mix/lib/mix/release.ex
@@ -7,7 +7,8 @@ defmodule Mix.Release do
The Mix.Release struct has the following read-only fields:
* `:name` - the name of the release as an atom
- * `:version` - the version of the release as a string
+ * `:version` - the version of the release as a string or
+ `{:from_app, app_name}
* `:path` - the path to the release root
* `:version_path` - the path to the release version inside the release
* `:applications` - a map of application with their definitions
@@ -47,7 +48,7 @@ defmodule Mix.Release do
name: atom(),
version: String.t(),
path: String.t(),
- version_path: String.t(),
+ version_path: String.t() | {:from_app, application()},
applications: %{application() => keyword()},
boot_scripts: %{atom() => [{application(), mode()}]},
erts_version: charlist(),
@@ -112,6 +113,24 @@ defmodule Mix.Release do
)
end)
+ version =
+ case version do
+ {:from_app, app} ->
+ Application.load(app)
+ version = Application.spec(app, :vsn)
+
+ if !version do
+ Mix.raise(
+ "Could not find version for #{inspect(app)}, please make sure the application exists"
+ )
+ end
+
+ to_string(version)
+
+ _ ->
+ version
+ end
+
{config_providers, opts} = Keyword.pop(opts, :config_providers, [])
{steps, opts} = Keyword.pop(opts, :steps, [:assemble])
validate_steps!(steps)
diff --git a/lib/mix/lib/mix/tasks/release.ex b/lib/mix/lib/mix/tasks/release.ex
index 453247be6..b555ee500 100644
--- a/lib/mix/lib/mix/tasks/release.ex
+++ b/lib/mix/lib/mix/tasks/release.ex
@@ -386,8 +386,10 @@ defmodule Mix.Tasks.Release do
* `:path` - the path the release should be installed to.
Defaults to `"_build/MIX_ENV/rel/RELEASE_NAME"`.
- * `:version` - the release version as a string. Defaults to the current
- application version.
+ * `:version` - the release version as a string or `{:from_app, app_name}`.
+ Defaults to the current application version. The `{:from_app, app_name}` format
+ can be used to easily reference the application version from another application.
+ This is particularly useful in umbrella applications.
* `:quiet` - a boolean that controls if releases should write steps to
the standard output. Defaults to `false`.
diff --git a/lib/mix/test/mix/release_test.exs b/lib/mix/test/mix/release_test.exs
index 6a07fa2b4..d9dfd6087 100644
--- a/lib/mix/test/mix/release_test.exs
+++ b/lib/mix/test/mix/release_test.exs
@@ -50,6 +50,21 @@ defmodule Mix.ReleaseTest do
assert release.options[:quiet]
end
+ test "allows specifying the version from an application" do
+ overrides = [version: {:from_app, :elixir}]
+ release = from_config!(nil, config(), overrides)
+
+ assert release.version == to_string(Application.spec(:elixir, :vsn))
+ end
+
+ test "raises when :from_app is used with an app that doesn't exist" do
+ overrides = [version: {:from_app, :not_valid}]
+
+ assert_raise Mix.Error,
+ ~r"Could not find version for :not_valid, please make sure the application exists",
+ fn -> from_config!(nil, config(), overrides) end
+ end
+
test "includes applications" do
release = from_config!(nil, config(), [])
assert release.applications.mix[:path] == to_charlist(Application.app_dir(:mix))