aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTristan Sloughter <[email protected]>2019-05-20 09:17:29 -0600
committerGitHub <[email protected]>2019-05-20 09:17:29 -0600
commitcca2a6cade4d97b5b36ca7c055d25677860bdc5d (patch)
tree6d56227c213afccd11b850e4f6e445630f7f13b2
parent3420d80940eec374739d465c2f533d4917f83f42 (diff)
parentfc2170f006485b5f9705a8ff5e90b92d431c7c2c (diff)
downloadrelx-cca2a6cade4d97b5b36ca7c055d25677860bdc5d.tar.gz
relx-cca2a6cade4d97b5b36ca7c055d25677860bdc5d.tar.bz2
relx-cca2a6cade4d97b5b36ca7c055d25677860bdc5d.zip
Merge pull request #676 from velimir/providers-api
allow specify additional providers via api and cli calls
-rw-r--r--README.md1
-rw-r--r--src/relx.erl3
-rw-r--r--src/rlx_cmd_args.erl13
-rw-r--r--test/rlx_command_SUITE.erl14
-rw-r--r--test/rlx_prv_release_alias.erl27
-rw-r--r--test/rlx_release_SUITE.erl117
6 files changed, 160 insertions, 15 deletions
diff --git a/README.md b/README.md
index ce04617..2cd3b42 100644
--- a/README.md
+++ b/README.md
@@ -81,6 +81,7 @@ Options
| | --sys_config | string | | Path to a file to use for sys.config |
| -d | --dev-mode | boolean | false | Symlink all applications and configuration into the release instead of copying|
| -i | --include-erts | boolean/string | true | If true include a copy of erts used to build with, if a path include erts at that path. If false, do not include erts |
+| | --provider | string | | Specify an additional relx provider |
Wiki
----
diff --git a/src/relx.erl b/src/relx.erl
index 8027fd4..b5c3ec5 100644
--- a/src/relx.erl
+++ b/src/relx.erl
@@ -214,7 +214,8 @@ opt_spec_list() ->
{sys_config, undefined, "sys_config", string, "Path to a file to use for sys.config"},
{system_libs, undefined, "system_libs", string, "Path to dir of Erlang system libs"},
{version, undefined, "version", undefined, "Print relx version"},
- {root_dir, $r, "root", string, "The project root directory"}].
+ {root_dir, $r, "root", string, "The project root directory"},
+ {provider, undefined, "provider", atom, "Specify an additional relx provider"}].
-spec format_error(Reason::term()) -> string().
format_error({invalid_return_value, Provider, Value}) ->
diff --git a/src/rlx_cmd_args.erl b/src/rlx_cmd_args.erl
index b20344c..4f5e9da 100644
--- a/src/rlx_cmd_args.erl
+++ b/src/rlx_cmd_args.erl
@@ -285,6 +285,19 @@ create(include_erts, Opts) ->
create(warnings_as_errors, Opts) ->
WarningsAsErrors = proplists:get_value(warnings_as_errors, Opts, false),
{warnings_as_errors, WarningsAsErrors};
+create(provider, Opts) ->
+ case proplists:get_all_values(provider, Opts) of
+ [] ->
+ [];
+ Providers ->
+ {add_providers, Providers}
+ end;
+create(add_providers, Opts) ->
+ Providers = proplists:get_value(add_providers, Opts, []),
+ {add_providers, Providers};
+create(providers, Opts) ->
+ Providers = proplists:get_value(providers, Opts, []),
+ {providers, Providers};
create(_, _) ->
[].
diff --git a/test/rlx_command_SUITE.erl b/test/rlx_command_SUITE.erl
index 46664ab..8dd2da8 100644
--- a/test/rlx_command_SUITE.erl
+++ b/test/rlx_command_SUITE.erl
@@ -27,7 +27,8 @@
lib_expansion_case/1,
lib_fail_case/1,
spec_parse_fail_case/1,
- config_fail_case/1]).
+ config_fail_case/1,
+ provider_case/1]).
-include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl").
@@ -42,7 +43,7 @@ end_per_suite(_Config) ->
ok.
all() ->
- [normal_passing_case, lib_expansion_case, lib_fail_case, config_fail_case].
+ [normal_passing_case, lib_expansion_case, lib_fail_case, config_fail_case, provider_case].
normal_passing_case(Config) ->
DataDir = filename:join(proplists:get_value(priv_dir, Config), ?MODULE),
@@ -111,3 +112,12 @@ config_fail_case(_Config) ->
{ok, {Opts, Targets}} = getopt:parse(relx:opt_spec_list(), CmdLine),
?assertMatch({error, {_, {invalid_config_file, ConfigFile}}},
rlx_cmd_args:args2state(Opts, Targets)).
+
+provider_case(_Config) ->
+ CmdLine = ["--provider", "relx_provider_1",
+ "--provider", "relx_provider_2"],
+ {ok, {Opts, Targets}} = getopt:parse(relx:opt_spec_list(), CmdLine),
+ {ok, State} = rlx_cmd_args:args2state(Opts, Targets),
+ ?assertEqual(
+ [relx_provider_1, relx_provider_2],
+ proplists:get_value(add_providers, rlx_state:cli_args(State))).
diff --git a/test/rlx_prv_release_alias.erl b/test/rlx_prv_release_alias.erl
new file mode 100644
index 0000000..523940c
--- /dev/null
+++ b/test/rlx_prv_release_alias.erl
@@ -0,0 +1,27 @@
+-module(rlx_prv_release_alias).
+
+-behaviour(provider).
+
+-export([init/1, do/1, format_error/1]).
+
+-define(PROVIDER, test_release_alias).
+-define(DEPS, [app_discover]).
+
+%%============================================================================
+%% API
+%%============================================================================
+
+-spec init(rlx_state:t()) -> {ok, rlx_state:t()}.
+init(State) ->
+ State1 = rlx_state:add_provider(State, providers:create([{name, ?PROVIDER},
+ {module, ?MODULE},
+ {deps, ?DEPS}])),
+ {ok, State1}.
+
+-spec do(rlx_state:t()) -> {ok, rlx_state:t()} | relx:error().
+do(State) ->
+ rlx_prv_release:do(State).
+
+-spec format_error(ErrorDetail::term()) -> iolist().
+format_error(ErrorDetail) ->
+ rlx_prv_release:format_error(ErrorDetail).
diff --git a/test/rlx_release_SUITE.erl b/test/rlx_release_SUITE.erl
index d4a86be..d9685ea 100644
--- a/test/rlx_release_SUITE.erl
+++ b/test/rlx_release_SUITE.erl
@@ -25,7 +25,9 @@
init_per_testcase/2,
all/0,
providers/1,
+ providers_via_api_options/1,
add_providers/1,
+ add_providers_via_api_options/1,
make_release/1,
make_config_release/1,
make_extend_release/1,
@@ -82,19 +84,18 @@ init_per_testcase(_, Config) ->
{state, State1} | Config].
all() ->
- [providers, add_providers, make_release, make_config_release,
- make_extend_release, make_extend_config_release, make_scriptless_release,
- make_overridden_release, make_auto_skip_empty_app_release,
+ [providers, providers_via_api_options, add_providers, add_providers_via_api_options,
+ make_release, make_config_release, make_extend_release, make_extend_config_release,
+ make_scriptless_release, make_overridden_release, make_auto_skip_empty_app_release,
make_skip_app_release, make_exclude_app_release, make_app_type_none_release,
- make_implicit_config_release, make_rerun_overridden_release,
- overlay_release, make_goalless_release, make_depfree_release,
- make_invalid_config_release, make_relup_release, make_relup_release2,
- make_one_app_top_level_release, make_dev_mode_release, make_dev_mode_template_release,
- make_config_script_release, make_release_twice, make_release_twice_dev_mode,
- make_erts_release, make_erts_config_release,
- make_included_nodetool_release, make_not_included_nodetool_release,
- make_src_release, make_excluded_src_release, make_exclude_modules_release,
- make_release_with_sys_config_vm_args_src].
+ make_implicit_config_release, make_rerun_overridden_release, overlay_release,
+ make_goalless_release, make_depfree_release, make_invalid_config_release,
+ make_relup_release, make_relup_release2, make_one_app_top_level_release,
+ make_dev_mode_release, make_dev_mode_template_release, make_config_script_release,
+ make_release_twice, make_release_twice_dev_mode, make_erts_release,
+ make_erts_config_release, make_included_nodetool_release,
+ make_not_included_nodetool_release, make_src_release, make_excluded_src_release,
+ make_exclude_modules_release, make_release_with_sys_config_vm_args_src].
add_providers(Config) ->
LibDir1 = proplists:get_value(lib1, Config),
@@ -133,6 +134,52 @@ add_providers(Config) ->
?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)),
?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)).
+add_providers_via_api_options(Config) ->
+ LibDir1 = proplists:get_value(lib1, Config),
+
+ [(fun({Name, Vsn}) ->
+ rlx_test_utils:create_app(LibDir1, Name, Vsn, [kernel, stdlib], [])
+ end)(App)
+ ||
+ App <-
+ [{rlx_test_utils:create_random_name("lib_app1_"), rlx_test_utils:create_random_vsn()}
+ || _ <- lists:seq(1, 100)]],
+
+ rlx_test_utils:create_app(LibDir1, "goal_app_1", "0.0.1", [stdlib,kernel,non_goal_1], []),
+ rlx_test_utils:create_app(LibDir1, "lib_dep_1", "0.0.1", [stdlib,kernel], []),
+ rlx_test_utils:create_app(LibDir1, "goal_app_2", "0.0.1", [stdlib,kernel,goal_app_1,non_goal_2], []),
+ rlx_test_utils:create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]),
+ rlx_test_utils:create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []),
+
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
+ rlx_test_utils:write_config(ConfigFile,
+ [{release, {foo, "0.0.1"},
+ [goal_app_1,
+ goal_app_2]}]),
+ OutputDir = filename:join([proplists:get_value(priv_dir, Config),
+ rlx_test_utils:create_random_name("relx-output")]),
+ {ok, Cwd} = file:get_cwd(),
+ Opts = [{relname, undefined},
+ {relvsn, undefined},
+ {goals, []},
+ {overrides, []},
+ {output_dir, OutputDir},
+ {lib_dirs, [LibDir1]},
+ {root_dir, Cwd},
+ {log_level, 3},
+ {config, ConfigFile},
+ {add_providers, [rlx_prv_release_alias]}],
+ {ok, State} = relx:do(Opts, ["test_release_alias"]),
+ [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
+ AppSpecs = rlx_release:applications(Release),
+ ?assert(lists:keymember(stdlib, 1, AppSpecs)),
+ ?assert(lists:keymember(kernel, 1, AppSpecs)),
+ ?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({non_goal_2, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({goal_app_1, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)).
+
providers(Config) ->
LibDir1 = proplists:get_value(lib1, Config),
@@ -170,6 +217,52 @@ providers(Config) ->
?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)),
?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)).
+providers_via_api_options(Config) ->
+ LibDir1 = proplists:get_value(lib1, Config),
+
+ [(fun({Name, Vsn}) ->
+ rlx_test_utils:create_app(LibDir1, Name, Vsn, [kernel, stdlib], [])
+ end)(App)
+ ||
+ App <-
+ [{rlx_test_utils:create_random_name("lib_app1_"), rlx_test_utils:create_random_vsn()}
+ || _ <- lists:seq(1, 100)]],
+
+ rlx_test_utils:create_app(LibDir1, "goal_app_1", "0.0.1", [stdlib,kernel,non_goal_1], []),
+ rlx_test_utils:create_app(LibDir1, "lib_dep_1", "0.0.1", [stdlib,kernel], []),
+ rlx_test_utils:create_app(LibDir1, "goal_app_2", "0.0.1", [stdlib,kernel,goal_app_1,non_goal_2], []),
+ rlx_test_utils:create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]),
+ rlx_test_utils:create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []),
+
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
+ rlx_test_utils:write_config(ConfigFile,
+ [{release, {foo, "0.0.1"},
+ [goal_app_1,
+ goal_app_2]}]),
+ OutputDir = filename:join([proplists:get_value(priv_dir, Config),
+ rlx_test_utils:create_random_name("relx-output")]),
+ {ok, Cwd} = file:get_cwd(),
+ Opts = [{relname, undefined},
+ {relvsn, undefined},
+ {goals, []},
+ {overrides, []},
+ {output_dir, OutputDir},
+ {lib_dirs, [LibDir1]},
+ {root_dir, Cwd},
+ {log_level, 3},
+ {config, ConfigFile},
+ {providers, [rlx_prv_release_alias]}],
+ {ok, State} = relx:do(Opts, ["test_release_alias"]),
+ [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
+ AppSpecs = rlx_release:applications(Release),
+ ?assert(lists:keymember(stdlib, 1, AppSpecs)),
+ ?assert(lists:keymember(kernel, 1, AppSpecs)),
+ ?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({non_goal_2, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({goal_app_1, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({goal_app_2, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)).
+
make_release(Config) ->
LibDir1 = proplists:get_value(lib1, Config),