aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/relx.app.src (renamed from src/relcool.app.src)2
-rw-r--r--src/relx.erl (renamed from src/relcool.erl)165
-rw-r--r--src/rlx_app_discovery.erl (renamed from src/rcl_app_discovery.erl)44
-rw-r--r--src/rlx_app_info.erl (renamed from src/rcl_app_info.erl)26
-rw-r--r--src/rlx_cmd_args.erl (renamed from src/rcl_cmd_args.erl)172
-rw-r--r--src/rlx_depsolver.erl (renamed from src/rcl_depsolver.erl)36
-rw-r--r--src/rlx_depsolver_culprit.erl (renamed from src/rcl_depsolver_culprit.erl)96
-rw-r--r--src/rlx_dscv_util.erl (renamed from src/rcl_dscv_util.erl)6
-rw-r--r--src/rlx_goal.erl263
-rw-r--r--src/rlx_goal.peg (renamed from src/rcl_goal.peg)10
-rw-r--r--src/rlx_goal_utils.erl (renamed from src/rcl_goal_utils.erl)6
-rw-r--r--src/rlx_log.erl (renamed from src/rcl_log.erl)48
-rw-r--r--src/rlx_provider.erl (renamed from src/rcl_provider.erl)18
-rw-r--r--src/rlx_prv_assembler.erl (renamed from src/rcl_prv_assembler.erl)261
-rw-r--r--src/rlx_prv_config.erl (renamed from src/rcl_prv_config.erl)64
-rw-r--r--src/rlx_prv_discover.erl (renamed from src/rcl_prv_discover.erl)46
-rw-r--r--src/rlx_prv_overlay.erl (renamed from src/rcl_prv_overlay.erl)182
-rw-r--r--src/rlx_prv_release.erl (renamed from src/rcl_prv_release.erl)84
-rw-r--r--src/rlx_rel_discovery.erl (renamed from src/rcl_rel_discovery.erl)48
-rw-r--r--src/rlx_release.erl (renamed from src/rcl_release.erl)124
-rw-r--r--src/rlx_state.erl (renamed from src/rcl_state.erl)177
-rw-r--r--src/rlx_topo.erl (renamed from src/rcl_topo.erl)58
-rw-r--r--src/rlx_util.erl (renamed from src/rcl_util.erl)13
23 files changed, 1253 insertions, 696 deletions
diff --git a/src/relcool.app.src b/src/relx.app.src
index 0c1c45a..3f655cf 100644
--- a/src/relcool.app.src
+++ b/src/relx.app.src
@@ -18,7 +18,7 @@
%% under the License.
%%
-{application, relcool,
+{application, relx,
[{description, "Release assembler for Erlang/OTP Releases"},
{vsn, "0.0.5"},
{modules, []},
diff --git a/src/relcool.erl b/src/relx.erl
index 7750efa..30ee77f 100644
--- a/src/relcool.erl
+++ b/src/relx.erl
@@ -18,9 +18,10 @@
%%% @author Eric Merritt <[email protected]>
%%% @copyright (C) 2012 Erlware, LLC.
%%% @doc
--module(relcool).
+-module(relx).
-export([main/1,
+ do/2,
do/7,
do/8,
do/9,
@@ -29,104 +30,148 @@
-export_type([error/0]).
--include_lib("relcool/include/relcool.hrl").
+-include_lib("relx/include/relx.hrl").
%%============================================================================
%% types
%%============================================================================
-type error() :: {error, {Module::module(), Reason::term()}}.
--type goal() :: string() | binary() | rcl_depsolver:constraint().
+-type goal() :: string() | binary() | rlx_depsolver:constraint().
%%============================================================================
%% API
%%============================================================================
--spec main([string()]) -> ok | error() | {ok, rcl_state:t()}.
+-spec main([string()]) -> ok | error() | {ok, rlx_state:t()}.
main(Args) ->
OptSpecList = opt_spec_list(),
- Result =
- case rcl_cmd_args:args2state(getopt:parse(OptSpecList, Args)) of
- {ok, State} ->
- run_relcool_process(rcl_state:caller(State, command_line));
- Error={error, _} ->
- Error
- end,
+ Result = case getopt:parse(OptSpecList, Args) of
+ {ok, {Options, NonOptions}} ->
+ do([{caller, command_line} | Options], NonOptions);
+ {error, Detail} ->
+ ?RLX_ERROR({opt_parse, Detail})
+ end,
case Result of
{error, _} ->
- report_error(rcl_state:caller(rcl_state:new([], undefined),
+ report_error(rlx_state:caller(rlx_state:new([], undefined),
command_line),
Result);
_ ->
Result
end.
-%% @doc provides an API to run the Relcool process from erlang applications
+%% @doc provides an API to run the Relx process from erlang applications
%%
%% @param RelName - The release name to build (maybe `undefined`)
%% @param RelVsn - The release version to build (maybe `undefined`)
-%% @param Goals - The release goals for the system in depsolver or Relcool goal
+%% @param Goals - The release goals for the system in depsolver or Relx goal
%% format
%% @param LibDirs - The library dirs that should be used for the system
%% @param OutputDir - The directory where the release should be built to
%% @param Configs - The list of config files for the system
--spec do(atom(), string(), [goal()], [file:name()], rcl_log:log_level(),
+-spec do(atom(), string(), [goal()], [file:name()], rlx_log:log_level(),
[file:name()], file:name() | undefined) ->
- ok | error() | {ok, rcl_state:t()}.
+ ok | error() | {ok, rlx_state:t()}.
do(RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Config) ->
{ok, Cwd} = file:get_cwd(),
do(Cwd, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, [], Config).
-%% @doc provides an API to run the Relcool process from erlang applications
+%% @doc provides an API to run the Relx process from erlang applications
%%
%% @param RootDir - The root directory for the project
%% @param RelName - The release name to build (maybe `undefined`)
%% @param RelVsn - The release version to build (maybe `undefined`)
-%% @param Goals - The release goals for the system in depsolver or Relcool goal
+%% @param Goals - The release goals for the system in depsolver or Relx goal
%% format
%% @param LibDirs - The library dirs that should be used for the system
%% @param OutputDir - The directory where the release should be built to
%% @param Configs - The list of config files for the system
-spec do(file:name(), atom(), string(), [goal()], [file:name()],
- rcl_log:log_level(), [file:name()], file:name() | undefined) ->
- ok | error() | {ok, rcl_state:t()}.
+ rlx_log:log_level(), [file:name()], file:name() | undefined) ->
+ ok | error() | {ok, rlx_state:t()}.
do(RootDir, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Configs) ->
do(RootDir, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, [], Configs).
-%% @doc provides an API to run the Relcool process from erlang applications
+%% @doc provides an API to run the Relx process from erlang applications
%%
%% @param RootDir - The root directory for the system
%% @param RelName - The release name to build (maybe `undefined`)
%% @param RelVsn - The release version to build (maybe `undefined`)
-%% @param Goals - The release goals for the system in depsolver or Relcool goal
+%% @param Goals - The release goals for the system in depsolver or Relx goal
%% format
%% @param LibDirs - The library dirs that should be used for the system
%% @param OutputDir - The directory where the release should be built to
%% @param Overrides - A list of overrides for the system
%% @param Configs - The list of config files for the system
-spec do(file:name(), atom(), string(), [goal()], [file:name()],
- rcl_log:log_level(), [file:name()], [{atom(), file:name()}], file:name() | undefined) ->
- ok | error() | {ok, rcl_state:t()}.
+ rlx_log:log_level(), [file:name()], [{atom(), file:name()}], file:name() | undefined) ->
+ ok | error() | {ok, rlx_state:t()}.
do(RootDir, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Overrides, Config) ->
- State = rcl_state:new([{relname, RelName},
- {relvsn, RelVsn},
- {goals, Goals},
- {overrides, Overrides},
- {output_dir, OutputDir},
- {lib_dirs, LibDirs},
- {root_dir, RootDir},
- {log, rcl_log:new(LogLevel)},
- {config, Config}],
- release),
- run_relcool_process(rcl_state:caller(State, api)).
+ do([{relname, RelName},
+ {relvsn, RelVsn},
+ {goals, Goals},
+ {overrides, Overrides},
+ {output_dir, OutputDir},
+ {lib_dirs, LibDirs},
+ {root_dir, RootDir},
+ {log_level, LogLevel},
+ {config, Config}],
+ ["release"]).
+%% @doc provides an API to run the Relx process from erlang applications
+%%
+%% @param Opts - A proplist of options. There are good defaults for each of
+%% these entries, so any or all may be omitted. Individual options may be:
+%%
+%% <dl>
+%% <dt><pre>{relname, RelName}</pre></dt>
+%% <dd>The release name to build </dd>
+%% <dt><pre>{relvsn, RelVsn}</pre></dt>
+%% <dd>The release version to build</dd>
+%% <dt><pre>{goals, Goals}</pre></dt>
+%% <dd>The release goals for the system in depsolver or Relx goal
+%% format (@see goals())</dd>
+%% <dt><pre>{lib_dirs, LibDirs}</pre></dt>
+%% <dd>A list of library dirs that should be used for the system</dd>
+%% <dt><pre>{lib_dir, LibDir}</pre></dt>
+%% <dd>A single lib dir that should be used for the system, may appear any
+%% number of times and may be used in conjunction with lib_dirs</dd>
+%% <dt><pre>{output_dir, OutputDir}</pre></dt>
+%% <dd>The directory where the release should be built to</dd>
+%% <dt><pre>{root_dir, RootDir}</pre></dt>
+%% <dd>The base directory for this run of relx. </dd>
+%% <dt><pre>{config, Config}</pre></dt>
+%% <dd>The path to a relx config file</dd>
+%% <dt><pre>{log_level, LogLevel}</pre></dt>
+%% <dd>Defines the verbosity of output. Maybe a number between 0 and 2, with
+%% with higher values being more verbose</dd>
+%% <dt><pre>{overrides, Overrides}</pre></dt>
+%% <dd>A list of app overrides for the system in the form of [{AppName:atom(),
+%% Dir:string() | binary()} | string() | binary()] where the string or binary
+%% is in the form "AppName:AppDir"</dd>
+%% <dt><pre>{override, Override}</pre></dt>
+%% <dd>A single of app override for the system in the same form as entries for
+%% Overrides</dd>
+%% </dl>
+-spec do(proplists:proplist(), [string()]) ->
+ ok | error() | {ok, rlx_state:t()}.
+do(Opts, NonOpts) ->
+ case rlx_cmd_args:args2state(Opts, NonOpts) of
+ {ok, State} ->
+ run_relx_process(State);
+ Error={error, _} ->
+ Error
+ end.
-spec opt_spec_list() -> [getopt:option_spec()].
opt_spec_list() ->
[{relname, $n, "relname", string,
"Specify the name for the release that will be generated"},
{relvsn, $v, "relvsn", string, "Specify the version for the release"},
- {goals, $g, "goal", string,
+ {goal, $g, "goal", string,
"Specify a target constraint on the system. These are usually the OTP"},
+ {upfrom, $u, "upfrom", string,
+ "Only valid with relup target, specify the release to upgrade from"},
{output_dir, $o, "output-dir", string,
"The output directory for the release. This is `./` by default."},
{lib_dir, $l, "lib-dir", string,
@@ -136,24 +181,30 @@ opt_spec_list() ->
"Disable the default system added lib dirs (means you must add them all manually"},
{log_level, $V, "verbose", {integer, 1},
"Verbosity level, maybe between 0 and 2"},
+ {override_app, $a, "override_app", string,
+ "Provide an app name and a directory to override in the form <appname>:<app directory>"},
{config, $c, "config", {string, ""}, "The path to a config file"},
{root_dir, $r, "root", string, "The project root directory"}].
-spec format_error(Reason::term()) -> iolist().
format_error({invalid_return_value, Provider, Value}) ->
- [rcl_provider:format(Provider), " returned an invalid value ",
+ [rlx_provider:format(Provider), " returned an invalid value ",
io_lib:format("~p", [Value])];
+format_error({opt_parse, {invalid_option, Opt}}) ->
+ io_lib:format("invalid option ~s~n", [Opt]);
+format_error({opt_parse, Arg}) ->
+ io_lib:format("~p~n", [Arg]);
format_error({error, {Module, Reason}}) ->
io_lib:format("~s~n", [Module:format_error(Reason)]).
%%============================================================================
%% internal api
%%============================================================================
-run_relcool_process(State) ->
- rcl_log:info(rcl_state:log(State), "Starting relcool build process ..."),
- rcl_log:debug(rcl_state:log(State),
+run_relx_process(State) ->
+ rlx_log:info(rlx_state:log(State), "Starting relx build process ..."),
+ rlx_log:debug(rlx_state:log(State),
fun() ->
- rcl_state:format(State)
+ rlx_state:format(State)
end),
run_providers(State).
@@ -163,16 +214,16 @@ run_relcool_process(State) ->
%% providers again and run the rest of them (because they could have been
%% updated by the config process).
run_providers(State0) ->
- [ConfigProvider | _] = rcl_state:providers(State0),
+ [ConfigProvider | _] = rlx_state:providers(State0),
case run_provider(ConfigProvider, {ok, State0}) of
Err = {error, _} ->
Err;
{ok, State1} ->
- RootDir = rcl_state:root_dir(State1),
+ RootDir = rlx_state:root_dir(State1),
ok = file:set_cwd(RootDir),
- Providers = rcl_state:providers(State1),
+ Providers = rlx_state:providers(State1),
Result = run_providers(ConfigProvider, Providers, State1),
- handle_output(State1, rcl_state:caller(State1), Result)
+ handle_output(State1, rlx_state:caller(State1), Result)
end.
handle_output(State, command_line, E={error, _}) ->
@@ -193,33 +244,33 @@ run_providers(ConfigProvider, Providers, State0) ->
lists:foldl(fun run_provider/2, {ok, State0}, Providers)
end.
--spec run_provider(rcl_provider:t(), {ok, rcl_state:t()} | error()) ->
- {ok, rcl_state:t()} | error().
+-spec run_provider(rlx_provider:t(), {ok, rlx_state:t()} | error()) ->
+ {ok, rlx_state:t()} | error().
run_provider(_Provider, Error = {error, _}) ->
Error;
run_provider(Provider, {ok, State0}) ->
- rcl_log:debug(rcl_state:log(State0), "Running provider ~p~n",
- [rcl_provider:impl(Provider)]),
- case rcl_provider:do(Provider, State0) of
+ rlx_log:debug(rlx_state:log(State0), "Running provider ~p~n",
+ [rlx_provider:impl(Provider)]),
+ case rlx_provider:do(Provider, State0) of
{ok, State1} ->
- rcl_log:debug(rcl_state:log(State0), "Provider successfully run: ~p~n",
- [rcl_provider:impl(Provider)]),
+ rlx_log:debug(rlx_state:log(State0), "Provider successfully run: ~p~n",
+ [rlx_provider:impl(Provider)]),
{ok, State1};
E={error, _} ->
- rcl_log:debug(rcl_state:log(State0), "Provider (~p) failed with: ~p~n",
- [rcl_provider:impl(Provider), E]),
+ rlx_log:debug(rlx_state:log(State0), "Provider (~p) failed with: ~p~n",
+ [rlx_provider:impl(Provider), E]),
E
end.
-spec usage() -> ok.
usage() ->
- getopt:usage(opt_spec_list(), "relcool", "[*release-specification-file*]").
+ getopt:usage(opt_spec_list(), "relx", "[*release-specification-file*]").
--spec report_error(rcl_state:t(), error()) -> none() | error().
+-spec report_error(rlx_state:t(), error()) -> none() | error().
report_error(State, Error) ->
io:format(format_error(Error)),
usage(),
- case rcl_state:caller(State) of
+ case rlx_state:caller(State) of
command_line ->
erlang:halt(127);
api ->
diff --git a/src/rcl_app_discovery.erl b/src/rlx_app_discovery.erl
index 7b04b19..e6b6e2c 100644
--- a/src/rcl_app_discovery.erl
+++ b/src/rlx_app_discovery.erl
@@ -21,13 +21,13 @@
%%% @doc This provider uses the lib_dir setting of the state. It searches the
%%% Lib Dirs looking for all OTP Applications that are available. When it finds
%%% those OTP Applications it loads the information about them and adds them to
-%%% the state of available apps. This implements the rcl_provider behaviour.
--module(rcl_app_discovery).
+%%% the state of available apps. This implements the rlx_provider behaviour.
+-module(rlx_app_discovery).
-export([do/2,
format_error/1]).
--include_lib("relcool/include/relcool.hrl").
+-include_lib("relx/include/relx.hrl").
%%============================================================================
%% API
@@ -35,12 +35,12 @@
%% @doc recursively dig down into the library directories specified in the state
%% looking for OTP Applications
--spec do(rcl_state:t(), [filename:name()]) -> {ok, [rcl_app_info:t()]} | relcool:error().
+-spec do(rlx_state:t(), [filename:name()]) -> {ok, [rlx_app_info:t()]} | relx:error().
do(State, LibDirs) ->
- rcl_log:info(rcl_state:log(State),
+ rlx_log:info(rlx_state:log(State),
fun() ->
["Resolving OTP Applications from directories:\n",
- [[rcl_util:indent(1), LibDir, "\n"] || LibDir <- LibDirs]]
+ [[rlx_util:indent(1), LibDir, "\n"] || LibDir <- LibDirs]]
end),
resolve_app_metadata(State, LibDirs).
@@ -53,7 +53,7 @@ format_error(ErrorDetails)
%%% Internal Functions
%%%===================================================================
resolve_app_metadata(State, LibDirs) ->
- AppMeta0 = lists:flatten(rcl_dscv_util:do(fun discover_dir/2, LibDirs)),
+ AppMeta0 = lists:flatten(rlx_dscv_util:do(fun discover_dir/2, LibDirs)),
case [case Err of
{error, Ret} ->
Ret
@@ -66,26 +66,26 @@ resolve_app_metadata(State, LibDirs) ->
false
end] of
[] ->
- SkipApps = rcl_state:skip_apps(State),
+ SkipApps = rlx_state:skip_apps(State),
AppMeta1 = [App || {ok, App} <- setup_overrides(State, AppMeta0),
- not lists:keymember(rcl_app_info:name(App), 1, SkipApps)],
- rcl_log:debug(rcl_state:log(State),
+ not lists:keymember(rlx_app_info:name(App), 1, SkipApps)],
+ rlx_log:debug(rlx_state:log(State),
fun() ->
["Resolved the following OTP Applications from the system: \n",
- [[rcl_app_info:format(1, App), "\n"] || App <- AppMeta1]]
+ [[rlx_app_info:format(1, App), "\n"] || App <- AppMeta1]]
end),
{ok, AppMeta1};
Errors ->
- ?RCL_ERROR(Errors)
+ ?RLX_ERROR(Errors)
end.
app_name({error, _}) ->
undefined;
app_name({ok, AppMeta}) ->
- rcl_app_info:name(AppMeta).
+ rlx_app_info:name(AppMeta).
setup_overrides(State, AppMetas0) ->
- Overrides = rcl_state:overrides(State),
+ Overrides = rlx_state:overrides(State),
AppMetas1 = [AppMeta || AppMeta <- AppMetas0,
not lists:keymember(app_name(AppMeta), 1, Overrides)],
[case is_valid_otp_app(filename:join([FileName, <<"ebin">>,
@@ -95,7 +95,7 @@ setup_overrides(State, AppMetas0) ->
Error = {error, _} ->
Error;
{ok, App} ->
- {ok, rcl_app_info:link(App, true)}
+ {ok, rlx_app_info:link(App, true)}
end || {AppName, FileName} <- Overrides] ++ AppMetas1.
@@ -123,13 +123,13 @@ format_detail({app_info_error, {Module, Detail}}) ->
Module:format_error(Detail).
-spec discover_dir([file:name()], directory | file) ->
- {ok, rcl_app_info:t()} | {error, Reason::term()}.
+ {ok, rlx_app_info:t()} | {error, Reason::term()}.
discover_dir(_File, directory) ->
{noresult, true};
discover_dir(File, file) ->
is_valid_otp_app(File).
--spec is_valid_otp_app(file:name()) -> {ok, rcl_app_info:t()} | {error, Reason::term()} |
+-spec is_valid_otp_app(file:name()) -> {ok, rlx_app_info:t()} | {error, Reason::term()} |
{noresult, false}.
is_valid_otp_app(File) ->
@@ -148,7 +148,7 @@ is_valid_otp_app(File) ->
end.
-spec has_at_least_one_beam(file:name(), file:filename()) ->
- {ok, rcl_app_info:t()} | {error, Reason::term()}.
+ {ok, rlx_app_info:t()} | {error, Reason::term()}.
has_at_least_one_beam(EbinDir, File) ->
case file:list_dir(EbinDir) of
{ok, List} ->
@@ -163,7 +163,7 @@ has_at_least_one_beam(EbinDir, File) ->
end.
-spec gather_application_info(file:name(), file:filename()) ->
- {ok, rcl_app_info:t()} | {error, Reason::term()}.
+ {ok, rlx_app_info:t()} | {error, Reason::term()}.
gather_application_info(EbinDir, File) ->
AppDir = filename:dirname(EbinDir),
case file:consult(File) of
@@ -176,7 +176,7 @@ gather_application_info(EbinDir, File) ->
end.
-spec get_vsn(file:name(), atom(), proplists:proplist()) ->
- {ok, rcl_app_info:t()} | {error, Reason::term()}.
+ {ok, rlx_app_info:t()} | {error, Reason::term()}.
get_vsn(AppDir, AppName, AppDetail) ->
case proplists:get_value(vsn, AppDetail) of
undefined ->
@@ -191,11 +191,11 @@ get_vsn(AppDir, AppName, AppDetail) ->
end.
-spec get_deps(file:name(), atom(), string(), proplists:proplist()) ->
- {ok, rcl_app_info:t()} | {error, Reason::term()}.
+ {ok, rlx_app_info:t()} | {error, Reason::term()}.
get_deps(AppDir, AppName, AppVsn, AppDetail) ->
ActiveApps = proplists:get_value(applications, AppDetail, []),
LibraryApps = proplists:get_value(included_applications, AppDetail, []),
- rcl_app_info:new(AppName, AppVsn, AppDir, ActiveApps, LibraryApps).
+ rlx_app_info:new(AppName, AppVsn, AppDir, ActiveApps, LibraryApps).
%%%===================================================================
%%% Test Functions
diff --git a/src/rcl_app_info.erl b/src/rlx_app_info.erl
index dadc579..de6ed7d 100644
--- a/src/rcl_app_info.erl
+++ b/src/rlx_app_info.erl
@@ -34,7 +34,7 @@
%%% application metadata.
%%% </ul>
%%%
--module(rcl_app_info).
+-module(rlx_app_info).
-export([new/0,
new/5,
@@ -57,7 +57,7 @@
-export_type([t/0]).
--include_lib("relcool/include/relcool.hrl").
+-include_lib("relx/include/relx.hrl").
-record(app_info_t, {name :: atom(),
vsn :: ec_semver:semver(),
@@ -82,20 +82,20 @@ new() ->
%% @doc build a complete version of the app info with all fields set.
-spec new(atom(), string(), file:name(), [atom()], [atom()]) ->
- {ok, t()} | relcool:error().
+ {ok, t()} | relx:error().
new(AppName, Vsn, Dir, ActiveDeps, LibraryDeps) ->
new(AppName, Vsn, Dir, ActiveDeps, LibraryDeps, false).
%% @doc build a complete version of the app info with all fields set.
-spec new(atom(), string(), file:name(), [atom()], [atom()], boolean()) ->
- {ok, t()} | relcool:error().
+ {ok, t()} | relx:error().
new(AppName, Vsn, Dir, ActiveDeps, LibraryDeps, Link)
when erlang:is_atom(AppName),
erlang:is_list(ActiveDeps),
erlang:is_list(LibraryDeps) ->
case parse_version(Vsn) of
{fail, _} ->
- ?RCL_ERROR({vsn_parse, AppName});
+ ?RLX_ERROR({vsn_parse, AppName});
ParsedVsn ->
{ok, #app_info_t{name=AppName, vsn=ParsedVsn, dir=Dir,
active_deps=ActiveDeps,
@@ -120,12 +120,12 @@ vsn(#app_info_t{vsn=Vsn}) ->
vsn_as_string(#app_info_t{vsn=Vsn}) ->
erlang:binary_to_list(erlang:iolist_to_binary(ec_semver:format(Vsn))).
--spec vsn(t(), string()) -> {ok, t()} | relcool:error().
+-spec vsn(t(), string()) -> {ok, t()} | relx:error().
vsn(AppInfo=#app_info_t{name=AppName}, AppVsn)
when erlang:is_list(AppVsn) ->
case parse_version(AppVsn) of
{fail, _} ->
- ?RCL_ERROR({vsn_parse, AppName});
+ ?RLX_ERROR({vsn_parse, AppName});
ParsedVsn ->
{ok, AppInfo#app_info_t{vsn=ParsedVsn}}
end.
@@ -175,13 +175,13 @@ format(AppInfo) ->
format(Indent, #app_info_t{name=Name, vsn=Vsn, dir=Dir,
active_deps=Deps, library_deps=LibDeps,
link=Link}) ->
- [rcl_util:indent(Indent), erlang:atom_to_list(Name), "-", ec_semver:format(Vsn),
+ [rlx_util:indent(Indent), erlang:atom_to_list(Name), "-", ec_semver:format(Vsn),
": ", Dir, "\n",
- rcl_util:indent(Indent + 1), "Symlink: ", erlang:atom_to_list(Link), "\n",
- rcl_util:indent(Indent + 1), "Active Dependencies:\n",
- [[rcl_util:indent(Indent + 2), erlang:atom_to_list(Dep), ",\n"] || Dep <- Deps],
- rcl_util:indent(Indent + 1), "Library Dependencies:\n",
- [[rcl_util:indent(Indent + 2), erlang:atom_to_list(LibDep), ",\n"] || LibDep <- LibDeps]].
+ rlx_util:indent(Indent + 1), "Symlink: ", erlang:atom_to_list(Link), "\n",
+ rlx_util:indent(Indent + 1), "Active Dependencies:\n",
+ [[rlx_util:indent(Indent + 2), erlang:atom_to_list(Dep), ",\n"] || Dep <- Deps],
+ rlx_util:indent(Indent + 1), "Library Dependencies:\n",
+ [[rlx_util:indent(Indent + 2), erlang:atom_to_list(LibDep), ",\n"] || LibDep <- LibDeps]].
%%%===================================================================
%%% Internal Functions
diff --git a/src/rcl_cmd_args.erl b/src/rlx_cmd_args.erl
index bfb63b7..b5fe8a7 100644
--- a/src/rcl_cmd_args.erl
+++ b/src/rlx_cmd_args.erl
@@ -19,22 +19,20 @@
%%% @copyright (C) 2012 Erlware, LLC.
%%%
%%% @doc Trivial utility file to help handle common tasks
--module(rcl_cmd_args).
+-module(rlx_cmd_args).
--export([args2state/1,
+-export([args2state/2,
format_error/1]).
--include_lib("relcool/include/relcool.hrl").
+-include_lib("relx/include/relx.hrl").
%%============================================================================
%% API
%%============================================================================
--spec args2state({error, Reason::term()} | {[getopt:option()], [string()]}) ->
- {ok, {rcl_state:t(), [string()]}} |
- relcool:error().
-args2state({error, Detail}) ->
- ?RCL_ERROR({opt_parse, Detail});
-args2state({ok, {Opts, Target}})
+-spec args2state([getopt:option()], [string()]) ->
+ {ok, {rlx_state:t(), [string()]}} |
+ relx:error().
+args2state(Opts, Target)
when erlang:length(Target) == 0; erlang:length(Target) == 1 ->
RelName = proplists:get_value(relname, Opts, undefined),
RelVsn = proplists:get_value(relvsn, Opts, undefined),
@@ -50,16 +48,12 @@ args2state({ok, {Opts, Target}})
Error ->
Error
end;
-args2state({ok, {_Opts, Targets}}) ->
- ?RCL_ERROR({invalid_targets, Targets}).
+args2state(_Opts, Targets) ->
+ ?RLX_ERROR({invalid_targets, Targets}).
-spec format_error(Reason::term()) -> iolist().
format_error({invalid_targets, Targets}) ->
io_lib:format("One config must be specified! not ~p~n", [Targets]);
-format_error({opt_parse, {invalid_option, Opt}}) ->
- io_lib:format("invalid option ~s~n", [Opt]);
-format_error({opt_parse, Arg}) ->
- io_lib:format("~p~n", [Arg]);
format_error({invalid_option_arg, Arg}) ->
case Arg of
{goals, Goal} ->
@@ -77,8 +71,12 @@ format_error({invalid_option_arg, Arg}) ->
end;
format_error({invalid_config_file, Config}) ->
io_lib:format("Invalid configuration file specified: ~s", [Config]);
+format_error({invalid_caller, Caller}) ->
+ io_lib:format("Invalid caller specified: ~s", [Caller]);
format_error({failed_to_parse, Spec}) ->
io_lib:format("Unable to parse spec ~s", [Spec]);
+format_error({failed_to_parse_override, QA}) ->
+ io_lib:format("Failed to parse app override ~s", [QA]);
format_error({not_directory, Dir}) ->
io_lib:format("Library directory does not exist: ~s", [Dir]);
format_error({invalid_log_level, LogLevel}) ->
@@ -87,22 +85,21 @@ format_error({invalid_log_level, LogLevel}) ->
format_error({invalid_target, Target}) ->
io_lib:format("Invalid action specified: ~s", [Target]).
-
%%%===================================================================
%%% Internal Functions
%%%===================================================================
-spec handle_config([getopt:option()], atom(), proplists:proplist()) ->
- {ok, {rcl_state:t(), [string()]}} |
- relcool:error().
+ {ok, {rlx_state:t(), [string()]}} |
+ relx:error().
handle_config(Opts, Target, CommandLineConfig) ->
case validate_config(proplists:get_value(config, Opts, [])) of
Error = {error, _} ->
Error;
{ok, Config} ->
- {ok, rcl_state:new([{config, Config} | CommandLineConfig], Target)}
+ {ok, rlx_state:new([{config, Config} | CommandLineConfig], Target)}
end.
--spec convert_target([string()]) -> {ok, release | relup} | relcool:error().
+-spec convert_target([string()]) -> {ok, release | relup} | relx:error().
convert_target([]) ->
{ok, release};
convert_target(["release"]) ->
@@ -110,10 +107,10 @@ convert_target(["release"]) ->
convert_target(["relup"]) ->
{ok, relup};
convert_target(Target) ->
- ?RCL_ERROR({invalid_target, Target}).
+ ?RLX_ERROR({invalid_target, Target}).
-spec validate_config(file:filename() | undefined) ->
- {ok, file:filename() | undefined} | relcool:error().
+ {ok, file:filename() | undefined} | relx:error().
validate_config(undefined) ->
{ok, undefined};
validate_config("") ->
@@ -123,53 +120,101 @@ validate_config(Config) ->
true ->
{ok, filename:absname(Config)};
false ->
- ?RCL_ERROR({invalid_config_file, Config})
+ ?RLX_ERROR({invalid_config_file, Config})
end.
--spec create_log([getopt:option()], rcl_state:cmd_args()) ->
- {ok, rcl_state:cmd_args()} | relcool:error().
+-spec create_log([getopt:option()], rlx_state:cmd_args()) ->
+ {ok, rlx_state:cmd_args()} | relx:error().
create_log(Opts, Acc) ->
LogLevel = proplists:get_value(log_level, Opts, 0),
if
LogLevel >= 0, LogLevel =< 2 ->
- create_goals(Opts, [{log, rcl_log:new(LogLevel)} | Acc]);
+ create_goals(Opts, [{log, rlx_log:new(LogLevel)} | Acc]);
true ->
- ?RCL_ERROR({invalid_log_level, LogLevel})
+ ?RLX_ERROR({invalid_log_level, LogLevel})
end.
--spec create_goals([getopt:option()], rcl_state:cmd_args()) ->
- {ok, rcl_state:cmd_args()} | relcool:error().
+-spec create_goals([getopt:option()], rlx_state:cmd_args()) ->
+ {ok, rlx_state:cmd_args()} | relx:error().
create_goals(Opts, Acc) ->
- case convert_goals(proplists:get_all_values(goals, Opts), []) of
+ Goals = proplists:get_value(goals, Opts, []) ++
+ proplists:get_all_values(goal, Opts),
+ case convert_goals(Goals, []) of
Error={error, _} ->
Error;
{ok, Specs} ->
- create_output_dir(Opts, [{goals, Specs} | Acc])
+ create_overrides(Opts, [{goals, Specs} | Acc])
end.
--spec convert_goals([string()], [rcl_depsolver:constraint()]) ->
- {ok,[rcl_depsolver:constraint()]} |
- relcool:error().
+-spec create_overrides([getopt:option()], rlx_state:cmd_args()) ->
+ {ok, rlx_state:cmd_args()} | relx:error().
+create_overrides(Opts, Acc) ->
+ Overrides = proplists:get_all_values(override, Opts) ++
+ proplists:get_value(overrides, Opts, []),
+ case convert_overrides(Overrides, []) of
+ {ok, Overrides} ->
+ create_output_dir(Opts, [{overrides, Overrides} | Acc]);
+ Error ->
+ Error
+ end.
+
+-spec convert_overrides([{atom(), string() | binary()} |
+ string() | binary()], [{atom(), string() | binary()}]) ->
+ {ok, [string() | binary()]} | relx:error().
+convert_overrides([], Acc) ->
+ {ok, Acc};
+convert_overrides([QA = {OverrideApp, _} | Rest], Acc)
+ when erlang:is_atom(OverrideApp) ->
+ convert_overrides(Rest, [QA | Acc]);
+convert_overrides([Override | Rest], Acc)
+ when erlang:is_list(Override); erlang:is_binary(Override) ->
+ case re:split(Override, ":") of
+ [AppName, AppDir] ->
+ convert_overrides(Rest, [{erlang:iolist_to_binary(AppName), AppDir} | Acc]);
+ _ ->
+ ?RLX_ERROR({failed_to_parse_override, Override})
+ end;
+convert_overrides([QA | _], _) ->
+ ?RLX_ERROR({failed_to_parse_override, QA}).
+
+-spec convert_goals([string()], [rlx_depsolver:constraint()]) ->
+ {ok,[rlx_depsolver:constraint()]} |
+ relx:error().
convert_goals([], Specs) ->
- %% Reverse the specs because order matters to rcl_depsolver
+ %% Reverse the specs because order matters to rlx_depsolver
{ok, lists:reverse(Specs)};
convert_goals([RawSpec | Rest], Acc) ->
- case rcl_goal:parse(RawSpec) of
+ parse_goal(RawSpec, Rest, Acc).
+
+-spec parse_goal(string() | binary() | rlx_depsolver:constraint(),
+ [string() | binary() | rlx_depsolver:constraint()],
+ rlx_depsolver:constraints()) ->
+ {ok, rlx_depsolver:constraints()} | relx:error().
+parse_goal(Spec, Rest, Acc)
+ when erlang:is_atom(Spec) ->
+ convert_goals(Rest, [Spec | Acc]);
+parse_goal(Spec, Rest, Acc)
+ when erlang:is_tuple(Spec) ->
+ convert_goals(Rest, [Spec | Acc]);
+parse_goal(RawSpec, Rest, Acc) ->
+ case rlx_goal:parse(RawSpec) of
{ok, Spec} ->
convert_goals(Rest, [Spec | Acc]);
{fail, _} ->
- ?RCL_ERROR({failed_to_parse, RawSpec})
+ ?RLX_ERROR({failed_to_parse, RawSpec})
end.
--spec create_output_dir([getopt:option()], rcl_state:cmd_args()) ->
- {ok, rcl_state:cmd_args()} | relcool:error().
+
+-spec create_output_dir([getopt:option()], rlx_state:cmd_args()) ->
+ {ok, rlx_state:cmd_args()} | relx:error().
create_output_dir(Opts, Acc) ->
OutputDir = proplists:get_value(output_dir, Opts, "./_rel"),
create_lib_dirs(Opts, [{output_dir, filename:absname(OutputDir)} | Acc]).
--spec create_lib_dirs([getopt:option()], rcl_state:cmd_args()) ->
- {ok, rcl_state:cmd_args()} | relcool:error().
+-spec create_lib_dirs([getopt:option()], rlx_state:cmd_args()) ->
+ {ok, rlx_state:cmd_args()} | relx:error().
create_lib_dirs(Opts, Acc) ->
- Dirs = proplists:get_all_values(lib_dir, Opts),
+ Dirs = proplists:get_all_values(lib_dir, Opts) ++
+ proplists:get_value(lib_dirs, Opts, []),
case check_lib_dirs(Dirs) of
Error = {error, _} ->
Error;
@@ -177,8 +222,8 @@ create_lib_dirs(Opts, Acc) ->
create_root_dir(Opts, [{lib_dirs, [filename:absname(Dir) || Dir <- Dirs]} | Acc])
end.
--spec create_root_dir([getopt:option()], rcl_state:cmd_args()) ->
- {ok, rcl_state:cmd_args()} | relcool:error().
+-spec create_root_dir([getopt:option()], rlx_state:cmd_args()) ->
+ {ok, rlx_state:cmd_args()} | relx:error().
create_root_dir(Opts, Acc) ->
Dir = proplists:get_value(root_dir, Opts, undefined),
case Dir of
@@ -189,19 +234,48 @@ create_root_dir(Opts, Acc) ->
create_disable_default_libs(Opts, [{root_dir, Dir} | Acc])
end.
--spec create_disable_default_libs([getopt:option()], rcl_state:cmd_args()) ->
- {ok, rcl_state:cmd_args()} | relcool:error().
+-spec create_disable_default_libs([getopt:option()], rlx_state:cmd_args()) ->
+ {ok, rlx_state:cmd_args()} | relx:error().
create_disable_default_libs(Opts, Acc) ->
Def = proplists:get_value(disable_default_libs, Opts, false),
- {ok, [{disable_default_libs, Def} | Acc]}.
+ create_upfrom(Opts, [{disable_default_libs, Def} | Acc]).
--spec check_lib_dirs([string()]) -> ok | relcool:error().
+-spec create_upfrom([getopt:option()], rcl:cmd_args()) ->
+ {ok, rlx_state:cmd_args()} | relx:error().
+create_upfrom(Opts, Acc) ->
+ case proplists:get_value(upfrom, Opts, undefined) of
+ undefined ->
+ create_caller(Opts, Acc);
+ UpFrom ->
+ create_caller(Opts, [{upfrom, UpFrom} | Acc])
+ end.
+
+-spec create_caller([getopt:option()], rlx_state:cmd_args()) ->
+ {ok, rlx_state:cmd_args()} | relx:error().
+create_caller(Opts, Acc) ->
+ case proplists:get_value(caller, Opts, api) of
+ "command_line" ->
+ {ok, [{caller, command_line} | Acc]};
+ "commandline" ->
+ {ok, [{caller, command_line} | Acc]};
+ "api" ->
+ {ok, [{caller, api} | Acc]};
+ api ->
+ {ok, [{caller, api} | Acc]};
+ commandline ->
+ {ok, [{caller, command_line} | Acc]};
+ command_line ->
+ {ok, [{caller, command_line} | Acc]};
+ Caller ->
+ ?RLX_ERROR({invalid_caller, Caller})
+ end.
+-spec check_lib_dirs([string()]) -> ok | relx:error().
check_lib_dirs([]) ->
ok;
check_lib_dirs([Dir | Rest]) ->
case filelib:is_dir(Dir) of
false ->
- ?RCL_ERROR({not_directory, Dir});
+ ?RLX_ERROR({not_directory, Dir});
true ->
check_lib_dirs(Rest)
end.
diff --git a/src/rcl_depsolver.erl b/src/rlx_depsolver.erl
index 0cf8c88..2b6e420 100644
--- a/src/rcl_depsolver.erl
+++ b/src/rlx_depsolver.erl
@@ -41,8 +41,8 @@
%%%
%%% we can add this world to the system all at once as follows
%%%
-%%% Graph0 = rcl_depsolver:new_graph(),
-%%% Graph1 = rcl_depsolver:add_packages(
+%%% Graph0 = rlx_depsolver:new_graph(),
+%%% Graph1 = rlx_depsolver:add_packages(
%%% [{app1, [{"0.1", [{app2, "0.2"},
%%% {app3, "0.2", '>='}]},
%%% {"0.2", []},
@@ -57,23 +57,23 @@
%%% We can also build it up incrementally using the other add_package and
%%% add_package_version functions.
%%%
-%%% Finally, once we have built up the graph we can ask rcl_depsolver to solve the
+%%% Finally, once we have built up the graph we can ask rlx_depsolver to solve the
%%% dependency constraints. That is to give us a list of valid dependencies by
%%% using the solve function. Lets say we want the app3 version "0.3" and all of
%%% its resolved dependencies. We could call solve as follows.
%%%
-%%% rcl_depsolver:solve(Graph1, [{app3, "0.3"}]).
+%%% rlx_depsolver:solve(Graph1, [{app3, "0.3"}]).
%%%
%%% That will give us the completely resolved dependencies including app3
%%% itself. Lets be a little more flexible. Lets ask for a graph that is rooted
%%% in anything greater then or equal to app3 "0.3". We could do that by
%%%
-%%% rcl_depsolver:solve(Graph1, [{app3, "0.3", '>='}]).
+%%% rlx_depsolver:solve(Graph1, [{app3, "0.3", '>='}]).
%%%
%%% Of course, you can specify any number of goals at the top level.
%%% @end
%%%-------------------------------------------------------------------
--module(rcl_depsolver).
+-module(rlx_depsolver).
%% Public Api
-export([format_error/1,
@@ -91,7 +91,7 @@
is_valid_constraint/1,
filter_packages/2]).
-%% Internally Exported API. This should *not* be used outside of the rcl_depsolver
+%% Internally Exported API. This should *not* be used outside of the rlx_depsolver
%% application. You have been warned.
-export([dep_pkg/1,
filter_package/2,
@@ -156,7 +156,7 @@ new_graph() ->
%% @doc add a complete set of list of packages to the graph. Where the package
%% consists of the name and a list of versions and dependencies.
%%
-%% ``` rcl_depsolver:add_packages(Graph,
+%% ``` rlx_depsolver:add_packages(Graph,
%% [{app1, [{"0.1", [{app2, "0.2"},
%% {app3, "0.2", '>='}]},
%% {"0.2", []},
@@ -177,7 +177,7 @@ add_packages(Dom0, Info)
%% @doc add a single package to the graph, where it consists of a package name
%% and its versions and thier dependencies.
-%% ```rcl_depsolver:add_package(Graph, app1, [{"0.1", [{app2, "0.2"},
+%% ```rlx_depsolver:add_package(Graph, app1, [{"0.1", [{app2, "0.2"},
%% {app3, "0.2", '>='}]},
%% {"0.2", []},
%% {"0.3", []}]}]).
@@ -193,7 +193,7 @@ add_package(State, Pkg, Versions)
%% @doc add a set of dependencies to a specific package and version.
%% and its versions and thier dependencies.
-%% ```rcl_depsolver:add_package(Graph, app1, "0.1", [{app2, "0.2"},
+%% ```rlx_depsolver:add_package(Graph, app1, "0.1", [{app2, "0.2"},
%% {app3, "0.2", '>='}]},
%% {"0.2", []},
%% {"0.3", []}]).
@@ -225,7 +225,7 @@ add_package_version({?MODULE, Dom0}, RawPkg, RawVsn, RawPkgConstraints) ->
%% @doc add a package and version to the dependency graph with no dependency
%% constraints, dependency constraints can always be added after the fact.
%%
-%% ```rcl_depsolver:add_package_version(Graph, app1, "0.1").'''
+%% ```rlx_depsolver:add_package_version(Graph, app1, "0.1").'''
-spec add_package_version(t(),pkg_name(),raw_vsn()) -> t().
add_package_version(State, Pkg, Vsn) ->
add_package_version(State, Pkg, Vsn, []).
@@ -233,7 +233,7 @@ add_package_version(State, Pkg, Vsn) ->
%% @doc Given a set of goals (in the form of constrains) find a set of packages
%% and versions that satisfy all constraints. If no solution can be found then
%% an exception is thrown.
-%% ``` rcl_depsolver:solve(State, [{app1, "0.1", '>='}]).'''
+%% ``` rlx_depsolver:solve(State, [{app1, "0.1", '>='}]).'''
-spec solve(t(),[constraint()]) -> {ok, [pkg()]} | {error, term()}.
solve({?MODULE, DepGraph0}, RawGoals)
when erlang:length(RawGoals) > 0 ->
@@ -245,7 +245,7 @@ solve({?MODULE, DepGraph0}, RawGoals)
case primitive_solve(DepGraph1, Goals, no_path) of
{fail, _} ->
[FirstCons | Rest] = Goals,
- {error, rcl_depsolver_culprit:search(DepGraph1, [FirstCons], Rest)};
+ {error, rlx_depsolver_culprit:search(DepGraph1, [FirstCons], Rest)};
Solution ->
{ok, Solution}
end
@@ -317,7 +317,7 @@ filter_packages(PVPairs, RawConstraints) ->
{invalid_constraints, [constraint()]} |
list()}) -> iolist().
format_error(Error) ->
- rcl_depsolver_culprit:format_error(Error).
+ rlx_depsolver_culprit:format_error(Error).
%% @doc Return a formatted list of roots of the dependency trees which
%% could not be satisified. These may also have versions attached.
@@ -327,7 +327,7 @@ format_error(Error) ->
%%
-spec format_roots([constraints()]) -> iolist().
format_roots(Roots) ->
- rcl_depsolver_culprit:format_roots(Roots).
+ rlx_depsolver_culprit:format_roots(Roots).
%% @doc Return a formatted list of the culprit depenedencies which led to
@@ -336,17 +336,17 @@ format_roots(Roots) ->
%% ```(foo = 1.2.0) -> (bar > 2.0.0)```
-spec format_culprits([{[constraint()], [constraint()]}]) -> iolist().
format_culprits(Culprits) ->
- rcl_depsolver_culprit:format_culprits(Culprits).
+ rlx_depsolver_culprit:format_culprits(Culprits).
%% @doc A formatted version tuple
-spec format_version(vsn()) -> iolist().
format_version(Version) ->
- rcl_depsolver_culprit:format_version(Version).
+ rlx_depsolver_culprit:format_version(Version).
%% @doc A formatted constraint tuple
-spec format_constraint(constraint()) -> iolist().
format_constraint(Constraint) ->
- rcl_depsolver_culprit:format_constraint(Constraint).
+ rlx_depsolver_culprit:format_constraint(Constraint).
%%====================================================================
%% Internal Functions
diff --git a/src/rcl_depsolver_culprit.erl b/src/rlx_depsolver_culprit.erl
index f2115c7..cf6dcb2 100644
--- a/src/rcl_depsolver_culprit.erl
+++ b/src/rlx_depsolver_culprit.erl
@@ -28,7 +28,7 @@
%%% goal, and the good apps (those not immediately constrained from
%%% the goals).
%%% @end
--module(rcl_depsolver_culprit).
+-module(rlx_depsolver_culprit).
-export([search/3,
format_error/1,
@@ -46,10 +46,10 @@
%%============================================================================
%% @doc start running the solver, with each run reduce the number of constraints
%% set as goals. At some point the solver should succeed.
--spec search(rcl_depsolver:dep_graph(), [rcl_depsolver:constraint()], [rcl_depsolver:constraint()])
+-spec search(rlx_depsolver:dep_graph(), [rlx_depsolver:constraint()], [rlx_depsolver:constraint()])
-> term().
search(State, ActiveCons, []) ->
- case rcl_depsolver:primitive_solve(State, ActiveCons, keep_paths) of
+ case rlx_depsolver:primitive_solve(State, ActiveCons, keep_paths) of
{fail, FailPaths} ->
extract_culprit_information0(ActiveCons, lists:flatten(FailPaths));
_Success ->
@@ -59,7 +59,7 @@ search(State, ActiveCons, []) ->
inconsistant_graph_state
end;
search(State, ActiveCons, [NewCon | Constraints]) ->
- case rcl_depsolver:primitive_solve(State, ActiveCons, keep_paths) of
+ case rlx_depsolver:primitive_solve(State, ActiveCons, keep_paths) of
{fail, FailPaths} ->
extract_culprit_information0(ActiveCons, lists:flatten(FailPaths));
_Success ->
@@ -84,7 +84,7 @@ format_error(Details) when erlang:is_list(Details) ->
["Unable to solve constraints, the following solutions were attempted \n\n",
[[format_error_path(" ", Detail)] || Detail <- Details]].
--spec format_roots([rcl_depsolver:constraints()]) -> iolist().
+-spec format_roots([rlx_depsolver:constraints()]) -> iolist().
format_roots(Roots) ->
lists:foldl(fun(Root, Acc0) ->
lists:foldl(
@@ -95,9 +95,9 @@ format_roots(Roots) ->
end, Acc0, Root)
end, [], Roots).
--spec format_culprits([{[rcl_depsolver:constraint()], [rcl_depsolver:constraint()]}]) -> iolist().
+-spec format_culprits([{[rlx_depsolver:constraint()], [rlx_depsolver:constraint()]}]) -> iolist().
format_culprits(FailingDeps) ->
- Deps = sets:to_list(sets:from_list(lists:flatten([[rcl_depsolver:dep_pkg(Con) || Con <- Cons]
+ Deps = sets:to_list(sets:from_list(lists:flatten([[rlx_depsolver:dep_pkg(Con) || Con <- Cons]
|| {_, Cons} <- FailingDeps]))),
lists:foldl(fun(Con, "") ->
[format_constraint(Con)];
@@ -106,11 +106,11 @@ format_culprits(FailingDeps) ->
", " | Acc1]
end, [], Deps).
--spec format_version(rcl_depsolver:vsn()) -> iolist().
+-spec format_version(rlx_depsolver:vsn()) -> iolist().
format_version(Vsn) ->
ec_semver:format(Vsn).
--spec format_constraint(rcl_depsolver:constraint()) -> list().
+-spec format_constraint(rlx_depsolver:constraint()) -> list().
format_constraint(Pkg) when is_atom(Pkg) ->
erlang:atom_to_list(Pkg);
format_constraint(Pkg) when is_binary(Pkg) ->
@@ -170,8 +170,8 @@ append_value(Key, Value, PropList) ->
proplists:delete(Key, PropList)]
end.
--spec strip_goal([[rcl_depsolver:pkg()] | rcl_depsolver:pkg()]) ->
- [[rcl_depsolver:pkg()] | rcl_depsolver:pkg()].
+-spec strip_goal([[rlx_depsolver:pkg()] | rlx_depsolver:pkg()]) ->
+ [[rlx_depsolver:pkg()] | rlx_depsolver:pkg()].
strip_goal([{'_GOAL_', 'NO_VSN'}, Children]) ->
Children;
strip_goal(All = [Val | _])
@@ -180,25 +180,25 @@ strip_goal(All = [Val | _])
strip_goal(Else) ->
Else.
--spec extract_culprit_information0(rcl_depsolver:constraints(),
- [rcl_depsolver:fail_info()]) ->
+-spec extract_culprit_information0(rlx_depsolver:constraints(),
+ [rlx_depsolver:fail_info()]) ->
[term()].
extract_culprit_information0(ActiveCons, FailInfo)
when is_list(FailInfo) ->
[extract_culprit_information1(ActiveCons, FI) || FI <- FailInfo].
--spec extract_root(rcl_depsolver:constraints(), [rcl_depsolver:pkg()]) ->
- {[rcl_depsolver:constraint()], [rcl_depsolver:pkg()]}.
+-spec extract_root(rlx_depsolver:constraints(), [rlx_depsolver:pkg()]) ->
+ {[rlx_depsolver:constraint()], [rlx_depsolver:pkg()]}.
extract_root(ActiveCons, TPath = [PRoot | _]) ->
- RootName = rcl_depsolver:dep_pkg(PRoot),
+ RootName = rlx_depsolver:dep_pkg(PRoot),
Roots = lists:filter(fun(El) ->
- RootName =:= rcl_depsolver:dep_pkg(El)
+ RootName =:= rlx_depsolver:dep_pkg(El)
end, ActiveCons),
{Roots, TPath}.
--spec extract_culprit_information1(rcl_depsolver:constraints(),
- rcl_depsolver:fail_info()) ->
+-spec extract_culprit_information1(rlx_depsolver:constraints(),
+ rlx_depsolver:fail_info()) ->
term().
extract_culprit_information1(_ActiveCons, {[], RawConstraints}) ->
%% In this case where there was no realized versions, the GOAL
@@ -226,9 +226,9 @@ extract_culprit_information1(ActiveCons, {Path, RawConstraints}) ->
RunListItems = [extract_root(ActiveCons, TPath) || TPath <- TreedPath],
{RunListItems, FailCons}.
--spec follow_chain(rcl_depsolver:pkg_name(), rcl_depsolver:vsn(),
- {rcl_depsolver:constraint(), rcl_depsolver:pkg()}) ->
- false | {ok, rcl_depsolver:constraint()}.
+-spec follow_chain(rlx_depsolver:pkg_name(), rlx_depsolver:vsn(),
+ {rlx_depsolver:constraint(), rlx_depsolver:pkg()}) ->
+ false | {ok, rlx_depsolver:constraint()}.
follow_chain(Pkg, Vsn, {{Pkg, Vsn}, {Pkg, Vsn}}) ->
%% When the package version is the same as the source we dont want to try to follow it at all
false;
@@ -237,9 +237,9 @@ follow_chain(Pkg, Vsn, {Con, {Pkg, Vsn}}) ->
follow_chain(_Pkg, _Vsn, _) ->
false.
--spec find_chain(rcl_depsolver:pkg_name(), rcl_depsolver:vsn(),
- [{rcl_depsolver:constraint(), rcl_depsolver:pkg()}]) ->
- rcl_depsolver:constraints().
+-spec find_chain(rlx_depsolver:pkg_name(), rlx_depsolver:vsn(),
+ [{rlx_depsolver:constraint(), rlx_depsolver:pkg()}]) ->
+ rlx_depsolver:constraints().
find_chain(Pkg, Vsn, Constraints) ->
lists:foldl(fun(NCon, Acc) ->
case follow_chain(Pkg, Vsn, NCon) of
@@ -250,46 +250,46 @@ find_chain(Pkg, Vsn, Constraints) ->
end
end, [], Constraints).
--spec get_constraints(rcl_depsolver:pkg_name(), rcl_depsolver:vsn(), [rcl_depsolver:pkg()],
- [{rcl_depsolver:constraint(), rcl_depsolver:pkg()}]) ->
- rcl_depsolver:constraints().
+-spec get_constraints(rlx_depsolver:pkg_name(), rlx_depsolver:vsn(), [rlx_depsolver:pkg()],
+ [{rlx_depsolver:constraint(), rlx_depsolver:pkg()}]) ->
+ rlx_depsolver:constraints().
get_constraints(FailedPkg, FailedVsn, Path, Constraints) ->
Chain = find_chain(FailedPkg, FailedVsn, Constraints),
lists:filter(fun(Con) ->
- PkgName = rcl_depsolver:dep_pkg(Con),
+ PkgName = rlx_depsolver:dep_pkg(Con),
(lists:any(fun(PathEl) ->
- not rcl_depsolver:filter_package(PathEl, Con)
+ not rlx_depsolver:filter_package(PathEl, Con)
end, Path) orelse
not lists:keymember(PkgName, 1, Path))
end, Chain).
--spec pkg_vsn(rcl_depsolver:constraint(), [{rcl_depsolver:constraint(),
- rcl_depsolver:pkg()}]) ->
- [rcl_depsolver:pkg()].
+-spec pkg_vsn(rlx_depsolver:constraint(), [{rlx_depsolver:constraint(),
+ rlx_depsolver:pkg()}]) ->
+ [rlx_depsolver:pkg()].
pkg_vsn(PkgCon, Constraints) ->
- PkgName = rcl_depsolver:dep_pkg(PkgCon),
+ PkgName = rlx_depsolver:dep_pkg(PkgCon),
[DepPkg || Con = {DepPkg, _} <- Constraints,
case Con of
{Pkg = {PkgName, PkgVsn}, {PkgName, PkgVsn}} ->
- rcl_depsolver:filter_package(Pkg, PkgCon);
+ rlx_depsolver:filter_package(Pkg, PkgCon);
_ ->
false
end].
--spec depends(rcl_depsolver:pkg(), [{rcl_depsolver:constraint(),
- rcl_depsolver:pkg()}],
- [rcl_depsolver:pkg()]) ->
- [rcl_depsolver:pkg()].
+-spec depends(rlx_depsolver:pkg(), [{rlx_depsolver:constraint(),
+ rlx_depsolver:pkg()}],
+ [rlx_depsolver:pkg()]) ->
+ [rlx_depsolver:pkg()].
depends(SrcPkg, Constraints, Seen) ->
lists:flatten([pkg_vsn(Pkg, Constraints) || {Pkg, Source} <- Constraints,
Source =:= SrcPkg andalso
Pkg =/= SrcPkg andalso
not lists:member(Pkg, Seen)]).
--spec treeize_path(rcl_depsolver:pkg(), [{rcl_depsolver:constraint(),
- rcl_depsolver:pkg()}],
- [rcl_depsolver:pkg()]) ->
- [rcl_depsolver:pkg() | [rcl_depsolver:pkg()]].
+-spec treeize_path(rlx_depsolver:pkg(), [{rlx_depsolver:constraint(),
+ rlx_depsolver:pkg()}],
+ [rlx_depsolver:pkg()]) ->
+ [rlx_depsolver:pkg() | [rlx_depsolver:pkg()]].
treeize_path(Pkg, Constraints, Seen0) ->
Seen1 = [Pkg | Seen0],
case depends(Pkg, Constraints, Seen1) of
@@ -310,7 +310,7 @@ add_s(Roots) ->
""
end.
--spec format_path(string(), [rcl_depsolver:pkg()]) -> iolist().
+-spec format_path(string(), [rlx_depsolver:pkg()]) -> iolist().
format_path(CurrentIdent, Path) ->
[CurrentIdent, " ",
lists:foldl(fun(Con, "") ->
@@ -320,8 +320,8 @@ format_path(CurrentIdent, Path) ->
end, "", Path),
"\n"].
--spec format_dependency_paths(string(), [[rcl_depsolver:pkg()] | rcl_depsolver:pkg()],
- [{rcl_depsolver:pkg(), [rcl_depsolver:constraint()]}], [rcl_depsolver:pkg()]) -> iolist().
+-spec format_dependency_paths(string(), [[rlx_depsolver:pkg()] | rlx_depsolver:pkg()],
+ [{rlx_depsolver:pkg(), [rlx_depsolver:constraint()]}], [rlx_depsolver:pkg()]) -> iolist().
format_dependency_paths(CurrentIndent, [SubPath | Rest], FailingDeps, Acc)
when erlang:is_list(SubPath) ->
[format_dependency_paths(CurrentIndent, lists:sort(SubPath), FailingDeps, Acc),
@@ -348,8 +348,8 @@ format_dependency_paths(CurrentIndent, [Con | Rest], FailingDeps, Acc) ->
format_dependency_paths(_CurrentIndent, [], _FailingDeps, _Acc) ->
[].
--spec format_error_path(string(), {[{[rcl_depsolver:constraint()], [rcl_depsolver:pkg()]}],
- [rcl_depsolver:constraint()]}) -> iolist().
+-spec format_error_path(string(), {[{[rlx_depsolver:constraint()], [rlx_depsolver:pkg()]}],
+ [rlx_depsolver:constraint()]}) -> iolist().
format_error_path(CurrentIndent, {RawPaths, FailingDeps}) ->
Roots = [RootSet || {RootSet, _} <- RawPaths],
Paths = [Path || {_, Path} <- RawPaths],
diff --git a/src/rcl_dscv_util.erl b/src/rlx_dscv_util.erl
index 68dcb68..3d90b08 100644
--- a/src/rcl_dscv_util.erl
+++ b/src/rlx_dscv_util.erl
@@ -21,13 +21,13 @@
%%% @doc This provider uses the lib_dir setting of the state. It searches the
%%% Lib Dirs looking for all OTP Applications that are available. When it finds
%%% those OTP Applications it loads the information about them and adds them to
-%%% the state of available apps. This implements the rcl_provider behaviour.
--module(rcl_dscv_util).
+%%% the state of available apps. This implements the rlx_provider behaviour.
+-module(rlx_dscv_util).
-export([do/2,
format_error/1]).
--include_lib("relcool/include/relcool.hrl").
+-include_lib("relx/include/relx.hrl").
%%============================================================================
%% Types
diff --git a/src/rlx_goal.erl b/src/rlx_goal.erl
new file mode 100644
index 0000000..7226525
--- /dev/null
+++ b/src/rlx_goal.erl
@@ -0,0 +1,263 @@
+-module(rlx_goal).
+-export([parse/1,file/1]).
+-compile({nowarn_unused_function,[p/4, p/5, p_eof/0, p_optional/1, p_not/1, p_assert/1, p_seq/1, p_and/1, p_choose/1, p_zero_or_more/1, p_one_or_more/1, p_label/2, p_string/1, p_anything/0, p_charclass/1, p_regexp/1, p_attempt/4, line/1, column/1]}).
+
+
+-compile(export_all).
+-spec file(file:name()) -> any().
+file(Filename) -> {ok, Bin} = file:read_file(Filename), parse(Bin).
+
+-spec parse(binary() | list()) -> any().
+parse(List) when is_list(List) -> parse(list_to_binary(List));
+parse(Input) when is_binary(Input) ->
+ setup_memo(),
+ Result = case 'constraint'(Input,{{line,1},{column,1}}) of
+ {AST, <<>>, _Index} -> AST;
+ Any -> Any
+ end,
+ release_memo(), Result.
+
+'constraint'(Input, Index) ->
+ p(Input, Index, 'constraint', fun(I,D) -> (p_choose([p_seq([p_optional(fun 'ws'/2), fun 'app_name'/2, p_optional(fun 'ws'/2), fun 'between_op'/2, p_optional(fun 'ws'/2), fun 'version'/2, p_optional(fun 'ws'/2), p_string(<<",">>), p_optional(fun 'ws'/2), fun 'version'/2, p_optional(fun 'ws'/2), p_not(p_anything())]), p_seq([p_optional(fun 'ws'/2), fun 'app_name'/2, p_optional(fun 'ws'/2), fun 'constraint_op'/2, p_optional(fun 'ws'/2), fun 'version'/2, p_optional(fun 'ws'/2), p_not(p_anything())]), p_seq([p_optional(fun 'ws'/2), fun 'app_name'/2, p_optional(fun 'ws'/2), p_not(p_anything())])]))(I,D) end, fun(Node, _Idx) ->
+ case Node of
+ [_,AppName,_, _] ->
+ {ok, AppName};
+ [_,AppName,_,Op,_,Vsn,_, _] ->
+ {ok,
+ {AppName,
+ rlx_goal_utils:to_vsn(Vsn),
+ rlx_goal_utils:to_op(Op)}};
+ [_,AppName,_,Op,_,Vsn1,_,_,_,Vsn2,_,_] ->
+ {ok,
+ {AppName,
+ rlx_goal_utils:to_vsn(Vsn1),
+ rlx_goal_utils:to_vsn(Vsn2),
+ rlx_goal_utils:to_op(Op)}};
+ _ ->
+ io:format("~p~n", [Node])
+ end
+ end).
+
+'ws'(Input, Index) ->
+ p(Input, Index, 'ws', fun(I,D) -> (p_charclass(<<"[\s\t\n\s\r]">>))(I,D) end, fun(Node, Idx) -> transform('ws', Node, Idx) end).
+
+'app_name'(Input, Index) ->
+ p(Input, Index, 'app_name', fun(I,D) -> (p_one_or_more(p_charclass(<<"[a-zA-Z0-9_]">>)))(I,D) end, fun(Node, _Idx) -> erlang:list_to_atom(erlang:binary_to_list(erlang:iolist_to_binary(Node))) end).
+
+'between_op'(Input, Index) ->
+ p(Input, Index, 'between_op', fun(I,D) -> (p_seq([p_string(<<":">>), p_optional(fun 'ws'/2), p_choose([p_string(<<"btwn">>), p_string(<<"between">>)]), p_optional(fun 'ws'/2), p_string(<<":">>)]))(I,D) end, fun(Node, _Idx) -> case Node of
+ [C,_,Op,_,C] -> erlang:iolist_to_binary([C,Op,C]);
+ _ -> Node
+ end
+ end).
+
+'constraint_op'(Input, Index) ->
+ p(Input, Index, 'constraint_op', fun(I,D) -> (p_choose([p_string(<<"=">>), p_string(<<"-">>), p_string(<<"<=">>), p_string(<<"<">>), p_string(<<"~>">>), p_string(<<">=">>), p_string(<<">">>), fun 'word_constraint_op'/2, p_string(<<":">>)]))(I,D) end, fun(Node, Idx) -> transform('constraint_op', Node, Idx) end).
+
+'word_constraint_op'(Input, Index) ->
+ p(Input, Index, 'word_constraint_op', fun(I,D) -> (p_seq([p_string(<<":">>), p_optional(fun 'ws'/2), p_choose([p_string(<<"gte">>), p_string(<<"lte">>), p_string(<<"gt">>), p_string(<<"lt">>), p_string(<<"pes">>)]), p_optional(fun 'ws'/2), p_string(<<":">>)]))(I,D) end, fun(Node, _Idx) -> case Node of
+ [C,_,Op,_,C] -> erlang:iolist_to_binary([C,Op,C]);
+ _ -> Node
+ end
+ end).
+
+'version'(Input, Index) ->
+ p(Input, Index, 'version', fun(I,D) -> (p_one_or_more(p_charclass(<<"[0-9a-zA-Z-+.]">>)))(I,D) end, fun(Node, Idx) -> transform('version', Node, Idx) end).
+
+
+transform(_,Node,_Index) -> Node.
+
+p(Inp, Index, Name, ParseFun) ->
+ p(Inp, Index, Name, ParseFun, fun(N, _Idx) -> N end).
+
+p(Inp, StartIndex, Name, ParseFun, TransformFun) ->
+ case get_memo(StartIndex, Name) of % See if the current reduction is memoized
+ {ok, Memo} -> %Memo; % If it is, return the stored result
+ Memo;
+ _ -> % If not, attempt to parse
+ Result = case ParseFun(Inp, StartIndex) of
+ {fail,_} = Failure -> % If it fails, memoize the failure
+ Failure;
+ {Match, InpRem, NewIndex} -> % If it passes, transform and memoize the result.
+ Transformed = TransformFun(Match, StartIndex),
+ {Transformed, InpRem, NewIndex}
+ end,
+ memoize(StartIndex, Name, Result),
+ Result
+ end.
+
+setup_memo() ->
+ put({parse_memo_table, ?MODULE}, ets:new(?MODULE, [set])).
+
+release_memo() ->
+ ets:delete(memo_table_name()).
+
+memoize(Index, Name, Result) ->
+ Memo = case ets:lookup(memo_table_name(), Index) of
+ [] -> [];
+ [{Index, Plist}] -> Plist
+ end,
+ ets:insert(memo_table_name(), {Index, [{Name, Result}|Memo]}).
+
+get_memo(Index, Name) ->
+ case ets:lookup(memo_table_name(), Index) of
+ [] -> {error, not_found};
+ [{Index, Plist}] ->
+ case proplists:lookup(Name, Plist) of
+ {Name, Result} -> {ok, Result};
+ _ -> {error, not_found}
+ end
+ end.
+
+memo_table_name() ->
+ get({parse_memo_table, ?MODULE}).
+
+p_eof() ->
+ fun(<<>>, Index) -> {eof, [], Index};
+ (_, Index) -> {fail, {expected, eof, Index}} end.
+
+p_optional(P) ->
+ fun(Input, Index) ->
+ case P(Input, Index) of
+ {fail,_} -> {[], Input, Index};
+ {_, _, _} = Success -> Success
+ end
+ end.
+
+p_not(P) ->
+ fun(Input, Index)->
+ case P(Input,Index) of
+ {fail,_} ->
+ {[], Input, Index};
+ {Result, _, _} -> {fail, {expected, {no_match, Result},Index}}
+ end
+ end.
+
+p_assert(P) ->
+ fun(Input,Index) ->
+ case P(Input,Index) of
+ {fail,_} = Failure-> Failure;
+ _ -> {[], Input, Index}
+ end
+ end.
+
+p_and(P) ->
+ p_seq(P).
+
+p_seq(P) ->
+ fun(Input, Index) ->
+ p_all(P, Input, Index, [])
+ end.
+
+p_all([], Inp, Index, Accum ) -> {lists:reverse( Accum ), Inp, Index};
+p_all([P|Parsers], Inp, Index, Accum) ->
+ case P(Inp, Index) of
+ {fail, _} = Failure -> Failure;
+ {Result, InpRem, NewIndex} -> p_all(Parsers, InpRem, NewIndex, [Result|Accum])
+ end.
+
+p_choose(Parsers) ->
+ fun(Input, Index) ->
+ p_attempt(Parsers, Input, Index, none)
+ end.
+
+p_attempt([], _Input, _Index, Failure) -> Failure;
+p_attempt([P|Parsers], Input, Index, FirstFailure)->
+ case P(Input, Index) of
+ {fail, _} = Failure ->
+ case FirstFailure of
+ none -> p_attempt(Parsers, Input, Index, Failure);
+ _ -> p_attempt(Parsers, Input, Index, FirstFailure)
+ end;
+ Result -> Result
+ end.
+
+p_zero_or_more(P) ->
+ fun(Input, Index) ->
+ p_scan(P, Input, Index, [])
+ end.
+
+p_one_or_more(P) ->
+ fun(Input, Index)->
+ Result = p_scan(P, Input, Index, []),
+ case Result of
+ {[_|_], _, _} ->
+ Result;
+ _ ->
+ {fail, {expected, Failure, _}} = P(Input,Index),
+ {fail, {expected, {at_least_one, Failure}, Index}}
+ end
+ end.
+
+p_label(Tag, P) ->
+ fun(Input, Index) ->
+ case P(Input, Index) of
+ {fail,_} = Failure ->
+ Failure;
+ {Result, InpRem, NewIndex} ->
+ {{Tag, Result}, InpRem, NewIndex}
+ end
+ end.
+
+p_scan(_, [], Index, Accum) -> {lists:reverse( Accum ), [], Index};
+p_scan(P, Inp, Index, Accum) ->
+ case P(Inp, Index) of
+ {fail,_} -> {lists:reverse(Accum), Inp, Index};
+ {Result, InpRem, NewIndex} -> p_scan(P, InpRem, NewIndex, [Result | Accum])
+ end.
+
+p_string(S) when is_list(S) -> p_string(list_to_binary(S));
+p_string(S) ->
+ Length = erlang:byte_size(S),
+ fun(Input, Index) ->
+ try
+ <<S:Length/binary, Rest/binary>> = Input,
+ {S, Rest, p_advance_index(S, Index)}
+ catch
+ error:{badmatch,_} -> {fail, {expected, {string, S}, Index}}
+ end
+ end.
+
+p_anything() ->
+ fun(<<>>, Index) -> {fail, {expected, any_character, Index}};
+ (Input, Index) when is_binary(Input) ->
+ <<C/utf8, Rest/binary>> = Input,
+ {<<C/utf8>>, Rest, p_advance_index(<<C/utf8>>, Index)}
+ end.
+
+p_charclass(Class) ->
+ {ok, RE} = re:compile(Class, [unicode, dotall]),
+ fun(Inp, Index) ->
+ case re:run(Inp, RE, [anchored]) of
+ {match, [{0, Length}|_]} ->
+ {Head, Tail} = erlang:split_binary(Inp, Length),
+ {Head, Tail, p_advance_index(Head, Index)};
+ _ -> {fail, {expected, {character_class, binary_to_list(Class)}, Index}}
+ end
+ end.
+
+p_regexp(Regexp) ->
+ {ok, RE} = re:compile(Regexp, [unicode, dotall, anchored]),
+ fun(Inp, Index) ->
+ case re:run(Inp, RE) of
+ {match, [{0, Length}|_]} ->
+ {Head, Tail} = erlang:split_binary(Inp, Length),
+ {Head, Tail, p_advance_index(Head, Index)};
+ _ -> {fail, {expected, {regexp, binary_to_list(Regexp)}, Index}}
+ end
+ end.
+
+line({{line,L},_}) -> L;
+line(_) -> undefined.
+
+column({_,{column,C}}) -> C;
+column(_) -> undefined.
+
+p_advance_index(MatchedInput, Index) when is_list(MatchedInput) orelse is_binary(MatchedInput)-> % strings
+ lists:foldl(fun p_advance_index/2, Index, unicode:characters_to_list(MatchedInput));
+p_advance_index(MatchedInput, Index) when is_integer(MatchedInput) -> % single characters
+ {{line, Line}, {column, Col}} = Index,
+ case MatchedInput of
+ $\n -> {{line, Line+1}, {column, 1}};
+ _ -> {{line, Line}, {column, Col+1}}
+ end.
diff --git a/src/rcl_goal.peg b/src/rlx_goal.peg
index bfac607..08a3726 100644
--- a/src/rcl_goal.peg
+++ b/src/rlx_goal.peg
@@ -10,14 +10,14 @@ constraint <- ws? app_name ws? between_op ws? version ws? "," ws? version ws?
[_,AppName,_,Op,_,Vsn,_, _] ->
{ok,
{AppName,
- rcl_goal_utils:to_vsn(Vsn),
- rcl_goal_utils:to_op(Op)}};
+ rlx_goal_utils:to_vsn(Vsn),
+ rlx_goal_utils:to_op(Op)}};
[_,AppName,_,Op,_,Vsn1,_,_,_,Vsn2,_,_] ->
{ok,
{AppName,
- rcl_goal_utils:to_vsn(Vsn1),
- rcl_goal_utils:to_vsn(Vsn2),
- rcl_goal_utils:to_op(Op)}};
+ rlx_goal_utils:to_vsn(Vsn1),
+ rlx_goal_utils:to_vsn(Vsn2),
+ rlx_goal_utils:to_op(Op)}};
_ ->
io:format("~p~n", [Node])
end
diff --git a/src/rcl_goal_utils.erl b/src/rlx_goal_utils.erl
index 6065e5c..764fab6 100644
--- a/src/rcl_goal_utils.erl
+++ b/src/rlx_goal_utils.erl
@@ -20,7 +20,7 @@
%%%
%%% @doc
%%% Utilities to help with parsing of target specs
--module(rcl_goal_utils).
+-module(rlx_goal_utils).
-export([to_op/1,
to_vsn/1]).
@@ -32,7 +32,7 @@
%%============================================================================
%% API
%%============================================================================
--spec to_op(iolist()) -> rcl_depsolver:constraint_op().
+-spec to_op(iolist()) -> rlx_depsolver:constraint_op().
to_op(List)
when erlang:is_list(List) ->
to_op(erlang:iolist_to_binary(List));
@@ -70,7 +70,7 @@ to_op(<<":between:">>) ->
to_vsn(Version) when erlang:is_list(Version) ->
to_vsn(erlang:iolist_to_binary(Version));
to_vsn(Vsn) ->
- rcl_depsolver:parse_version(Vsn).
+ rlx_depsolver:parse_version(Vsn).
%%%===================================================================
%%% Test Functions
diff --git a/src/rcl_log.erl b/src/rlx_log.erl
index 71c0b5d..901ae7c 100644
--- a/src/rcl_log.erl
+++ b/src/rlx_log.erl
@@ -18,9 +18,9 @@
%%% @author Eric Merritt <[email protected]>
%%% @copyright (C) 2012 Erlware, LLC.
%%%
-%%% @doc This provides simple output functions for relcool. You should use this
+%%% @doc This provides simple output functions for relx. You should use this
%%% to talk to the users if you are wrting code for the system
--module(rcl_log).
+-module(rlx_log).
-export([new/1,
log/4,
@@ -41,7 +41,7 @@
log_fun/0,
t/0]).
--include_lib("relcool/include/relcool.hrl").
+-include_lib("relx/include/relx.hrl").
%%============================================================================
%% types
@@ -83,7 +83,7 @@ new(AtomLogLevel)
-spec debug(t(), string() | log_fun()) -> ok.
debug(LogState, Fun)
when erlang:is_function(Fun) ->
- log(LogState, ?RCL_DEBUG, Fun);
+ log(LogState, ?RLX_DEBUG, Fun);
debug(LogState, String) ->
debug(LogState, "~s~n", [String]).
@@ -91,14 +91,14 @@ debug(LogState, String) ->
%% and argements @see io:format/2
-spec debug(t(), string(), [any()]) -> ok.
debug(LogState, FormatString, Args) ->
- log(LogState, ?RCL_DEBUG, FormatString, Args).
+ log(LogState, ?RLX_DEBUG, FormatString, Args).
%% @doc log at the info level given the current log state with a string or
%% function that returns a string
-spec info(t(), string() | log_fun()) -> ok.
info(LogState, Fun)
when erlang:is_function(Fun) ->
- log(LogState, ?RCL_INFO, Fun);
+ log(LogState, ?RLX_INFO, Fun);
info(LogState, String) ->
info(LogState, "~s~n", [String]).
@@ -106,14 +106,14 @@ info(LogState, String) ->
%% and argements @see io:format/2
-spec info(t(), string(), [any()]) -> ok.
info(LogState, FormatString, Args) ->
- log(LogState, ?RCL_INFO, FormatString, Args).
+ log(LogState, ?RLX_INFO, FormatString, Args).
%% @doc log at the error level given the current log state with a string or
%% format string that returns a function
-spec error(t(), string() | log_fun()) -> ok.
error(LogState, Fun)
when erlang:is_function(Fun) ->
- log(LogState, ?RCL_ERROR, Fun);
+ log(LogState, ?RLX_ERROR, Fun);
error(LogState, String) ->
error(LogState, "~s~n", [String]).
@@ -121,7 +121,7 @@ error(LogState, String) ->
%% and argements @see io:format/2
-spec error(t(), string(), [any()]) -> ok.
error(LogState, FormatString, Args) ->
- log(LogState, ?RCL_ERROR, FormatString, Args).
+ log(LogState, ?RLX_ERROR, FormatString, Args).
%% @doc Execute the fun passed in if log level is as expected.
-spec log(t(), int_log_level(), log_fun()) -> ok.
@@ -158,11 +158,11 @@ log_level({?MODULE, DetailLogLevel}) ->
%% @doc get the current log level as an atom
-spec atom_log_level(t()) -> atom_log_level().
-atom_log_level({?MODULE, ?RCL_ERROR}) ->
+atom_log_level({?MODULE, ?RLX_ERROR}) ->
error;
-atom_log_level({?MODULE, ?RCL_INFO}) ->
+atom_log_level({?MODULE, ?RLX_INFO}) ->
info;
-atom_log_level({?MODULE, ?RCL_DEBUG}) ->
+atom_log_level({?MODULE, ?RLX_DEBUG}) ->
debug.
-spec format(t()) -> iolist().
@@ -181,24 +181,24 @@ format(Log) ->
should_test() ->
ErrorLogState = new(error),
- ?assertMatch(true, should(ErrorLogState, ?RCL_ERROR)),
- ?assertMatch(true, not should(ErrorLogState, ?RCL_INFO)),
- ?assertMatch(true, not should(ErrorLogState, ?RCL_DEBUG)),
- ?assertEqual(?RCL_ERROR, log_level(ErrorLogState)),
+ ?assertMatch(true, should(ErrorLogState, ?RLX_ERROR)),
+ ?assertMatch(true, not should(ErrorLogState, ?RLX_INFO)),
+ ?assertMatch(true, not should(ErrorLogState, ?RLX_DEBUG)),
+ ?assertEqual(?RLX_ERROR, log_level(ErrorLogState)),
?assertEqual(error, atom_log_level(ErrorLogState)),
InfoLogState = new(info),
- ?assertMatch(true, should(InfoLogState, ?RCL_ERROR)),
- ?assertMatch(true, should(InfoLogState, ?RCL_INFO)),
- ?assertMatch(true, not should(InfoLogState, ?RCL_DEBUG)),
- ?assertEqual(?RCL_INFO, log_level(InfoLogState)),
+ ?assertMatch(true, should(InfoLogState, ?RLX_ERROR)),
+ ?assertMatch(true, should(InfoLogState, ?RLX_INFO)),
+ ?assertMatch(true, not should(InfoLogState, ?RLX_DEBUG)),
+ ?assertEqual(?RLX_INFO, log_level(InfoLogState)),
?assertEqual(info, atom_log_level(InfoLogState)),
DebugLogState = new(debug),
- ?assertMatch(true, should(DebugLogState, ?RCL_ERROR)),
- ?assertMatch(true, should(DebugLogState, ?RCL_INFO)),
- ?assertMatch(true, should(DebugLogState, ?RCL_DEBUG)),
- ?assertEqual(?RCL_DEBUG, log_level(DebugLogState)),
+ ?assertMatch(true, should(DebugLogState, ?RLX_ERROR)),
+ ?assertMatch(true, should(DebugLogState, ?RLX_INFO)),
+ ?assertMatch(true, should(DebugLogState, ?RLX_DEBUG)),
+ ?assertEqual(?RLX_DEBUG, log_level(DebugLogState)),
?assertEqual(debug, atom_log_level(DebugLogState)).
-endif.
diff --git a/src/rcl_provider.erl b/src/rlx_provider.erl
index 4d8f044..b0de178 100644
--- a/src/rcl_provider.erl
+++ b/src/rlx_provider.erl
@@ -21,7 +21,7 @@
%%% A module that supports providing state manipulation services to the system.
%%% @end
%%%-------------------------------------------------------------------
--module(rcl_provider).
+-module(rlx_provider).
%% API
-export([new/2,
@@ -33,7 +33,7 @@
-export_type([t/0]).
--include_lib("relcool/include/relcool.hrl").
+-include_lib("relx/include/relx.hrl").
%%%===================================================================
%%% Types
@@ -44,8 +44,8 @@
-ifdef(have_callback_support).
--callback init(rcl_state:t()) -> {ok, rcl_state:t()} | relcool:error().
--callback do(rcl_state:t()) -> {ok, rcl_state:t()} | relcool:error().
+-callback init(rlx_state:t()) -> {ok, rlx_state:t()} | relx:error().
+-callback do(rlx_state:t()) -> {ok, rlx_state:t()} | relx:error().
-callback format_error(Reason::term()) -> iolist().
-else.
@@ -72,13 +72,13 @@ behaviour_info(_) ->
%%
%% @param ModuleName The module name.
%% @param State0 The current state of the system
--spec new(module(), rcl_state:t()) ->
- {t(), {ok, rcl_state:t()}} | relcool:error().
+-spec new(module(), rlx_state:t()) ->
+ {t(), {ok, rlx_state:t()}} | relx:error().
new(ModuleName, State0) when is_atom(ModuleName) ->
State1 = ModuleName:init(State0),
case code:which(ModuleName) of
non_existing ->
- ?RCL_ERROR({non_existing, ModuleName});
+ ?RLX_ERROR({non_existing, ModuleName});
_ ->
{{?MODULE, ModuleName}, State1}
end.
@@ -87,8 +87,8 @@ new(ModuleName, State0) when is_atom(ModuleName) ->
%%
%% @param Provider the provider object
%% @param State the current state of the system
--spec do(Provider::t(), rcl_state:t()) ->
- {ok, rcl_state:t()} | relcool:error().
+-spec do(Provider::t(), rlx_state:t()) ->
+ {ok, rlx_state:t()} | relx:error().
do({?MODULE, Mod}, State) ->
Mod:do(State).
diff --git a/src/rcl_prv_assembler.erl b/src/rlx_prv_assembler.erl
index f40bdc5..18a372c 100644
--- a/src/rcl_prv_assembler.erl
+++ b/src/rlx_prv_assembler.erl
@@ -20,37 +20,37 @@
%%%
%%% @doc Given a complete built release this provider assembles that release
%%% into a release directory.
--module(rcl_prv_assembler).
+-module(rlx_prv_assembler).
--behaviour(rcl_provider).
+-behaviour(rlx_provider).
-export([init/1,
do/1,
format_error/1]).
--include_lib("relcool/include/relcool.hrl").
+-include_lib("relx/include/relx.hrl").
%%============================================================================
%% API
%%============================================================================
--spec init(rcl_state:t()) -> {ok, rcl_state:t()}.
+-spec init(rlx_state:t()) -> {ok, rlx_state:t()}.
init(State) ->
{ok, State}.
%% @doc recursively dig down into the library directories specified in the state
%% looking for OTP Applications
--spec do(rcl_state:t()) -> {ok, rcl_state:t()} | relcool:error().
+-spec do(rlx_state:t()) -> {ok, rlx_state:t()} | relx:error().
do(State) ->
- {RelName, RelVsn} = rcl_state:default_release(State),
- Release = rcl_state:get_release(State, RelName, RelVsn),
- OutputDir = rcl_state:output_dir(State),
+ {RelName, RelVsn} = rlx_state:default_configured_release(State),
+ Release = rlx_state:get_realized_release(State, RelName, RelVsn),
+ OutputDir = rlx_state:output_dir(State),
case create_output_dir(OutputDir) of
ok ->
- case rcl_release:realized(Release) of
+ case rlx_release:realized(Release) of
true ->
copy_app_directories_to_output(State, Release, OutputDir);
false ->
- ?RCL_ERROR({unresolved_release, RelName, RelVsn})
+ ?RLX_ERROR({unresolved_release, RelName, RelVsn})
end;
Error ->
Error
@@ -73,16 +73,30 @@ format_error({release_script_generation_error, RelFile}) ->
[RelFile]);
format_error({release_script_generation_warning, Module, Warnings}) ->
["Warnings generating release \s",
- rcl_util:indent(1), Module:format_warning(Warnings)];
+ rlx_util:indent(1), Module:format_warning(Warnings)];
format_error({unable_to_create_output_dir, OutputDir}) ->
io_lib:format("Unable to create output directory (possible permissions issue): ~s",
[OutputDir]);
format_error({release_script_generation_error, Module, Errors}) ->
["Errors generating release \n",
- rcl_util:indent(1), Module:format_error(Errors)];
+ rlx_util:indent(1), Module:format_error(Errors)];
+format_error({relup_generation_error, CurrentName, UpFromName}) ->
+ io_lib:format("Unknown internal release error generating the relup from ~s to ~s",
+ [UpFromName, CurrentName]);
+format_error({relup_generation_warning, Module, Warnings}) ->
+ ["Warnings generating relup \s",
+ rlx_util:indent(1), Module:format_warning(Warnings)];
+format_error({relup_script_generation_error,
+ {relupcript_generation_error, systools_relup,
+ {missing_sasl, _}}}) ->
+ "Unfortunately, due to requirements in systools, you need to have the sasl application "
+ "in both the current release and the release to upgrade from.";
+format_error({relup_script_generation_error, Module, Errors}) ->
+ ["Errors generating relup \n",
+ rlx_util:indent(1), Module:format_error(Errors)];
format_error({unable_to_make_symlink, AppDir, TargetDir, Reason}) ->
io_lib:format("Unable to symlink directory ~s to ~s because \n~s~s",
- [AppDir, TargetDir, rcl_util:indent(1),
+ [AppDir, TargetDir, rlx_util:indent(1),
file:format_error(Reason)]).
%%%===================================================================
@@ -93,11 +107,11 @@ format_error({unable_to_make_symlink, AppDir, TargetDir, Reason}) ->
create_output_dir(OutputDir) ->
case filelib:is_dir(OutputDir) of
false ->
- case rcl_util:mkdir_p(OutputDir) of
+ case rlx_util:mkdir_p(OutputDir) of
ok ->
ok;
{error, _} ->
- ?RCL_ERROR({unable_to_create_output_dir, OutputDir})
+ ?RLX_ERROR({unable_to_create_output_dir, OutputDir})
end;
true ->
ok
@@ -106,7 +120,7 @@ create_output_dir(OutputDir) ->
copy_app_directories_to_output(State, Release, OutputDir) ->
LibDir = filename:join([OutputDir, "lib"]),
ok = ec_file:mkdir_p(LibDir),
- Apps = rcl_release:application_details(Release),
+ Apps = rlx_release:application_details(Release),
Result = lists:filter(fun({error, _}) ->
true;
(_) ->
@@ -123,9 +137,9 @@ copy_app_directories_to_output(State, Release, OutputDir) ->
end.
copy_app(LibDir, App) ->
- AppName = erlang:atom_to_list(rcl_app_info:name(App)),
- AppVsn = rcl_app_info:vsn_as_string(App),
- AppDir = rcl_app_info:dir(App),
+ AppName = erlang:atom_to_list(rlx_app_info:name(App)),
+ AppVsn = rlx_app_info:vsn_as_string(App),
+ AppDir = rlx_app_info:dir(App),
TargetDir = filename:join([LibDir, AppName ++ "-" ++ AppVsn]),
if
AppDir == TargetDir ->
@@ -138,7 +152,7 @@ copy_app(LibDir, App) ->
copy_app(App, AppDir, TargetDir) ->
remove_symlink_or_directory(TargetDir),
- case rcl_app_info:link(App) of
+ case rlx_app_info:link(App) of
true ->
link_directory(AppDir, TargetDir);
false ->
@@ -161,7 +175,7 @@ remove_symlink_or_directory(TargetDir) ->
link_directory(AppDir, TargetDir) ->
case file:make_symlink(AppDir, TargetDir) of
{error, Reason} ->
- ?RCL_ERROR({unable_to_make_symlink, AppDir, TargetDir, Reason});
+ ?RLX_ERROR({unable_to_make_symlink, AppDir, TargetDir, Reason});
ok ->
ok
end.
@@ -182,10 +196,10 @@ copy_dir(AppDir, TargetDir, SubDir) ->
SubTarget = filename:join(TargetDir, SubDir),
case filelib:is_dir(SubSource) of
true ->
- ok = rcl_util:mkdir_p(SubTarget),
+ ok = rlx_util:mkdir_p(SubTarget),
case ec_file:copy(SubSource, SubTarget, [recursive]) of
{error, E} ->
- ?RCL_ERROR({ec_file_error, AppDir, SubTarget, E});
+ ?RLX_ERROR({ec_file_error, AppDir, SubTarget, E});
ok ->
ok
end;
@@ -193,42 +207,41 @@ copy_dir(AppDir, TargetDir, SubDir) ->
ok
end.
-create_release_info(State, Release, OutputDir) ->
- RelName = erlang:atom_to_list(rcl_release:name(Release)),
- ReleaseDir = filename:join([OutputDir,
- "releases",
- RelName ++ "-" ++
- rcl_release:vsn(Release)]),
+create_release_info(State0, Release0, OutputDir) ->
+ RelName = erlang:atom_to_list(rlx_release:name(Release0)),
+ ReleaseDir = release_output_dir(State0, Release0),
ReleaseFile = filename:join([ReleaseDir, RelName ++ ".rel"]),
ok = ec_file:mkdir_p(ReleaseDir),
- case rcl_release:metadata(Release) of
+ Release1 = rlx_release:relfile(Release0, ReleaseFile),
+ State1 = rlx_state:update_realized_release(State0, Release1),
+ case rlx_release:metadata(Release1) of
{ok, Meta} ->
ok = ec_file:write_term(ReleaseFile, Meta),
- write_bin_file(State, Release, OutputDir, ReleaseDir);
+ write_bin_file(State1, Release1, OutputDir, ReleaseDir);
E ->
E
end.
write_bin_file(State, Release, OutputDir, RelDir) ->
- RelName = erlang:atom_to_list(rcl_release:name(Release)),
- RelVsn = rcl_release:vsn(Release),
+ RelName = erlang:atom_to_list(rlx_release:name(Release)),
+ RelVsn = rlx_release:vsn(Release),
BinDir = filename:join([OutputDir, "bin"]),
ok = ec_file:mkdir_p(BinDir),
- VsnRel = filename:join(BinDir, RelName ++ "-" ++ RelVsn),
+ VsnRel = filename:join(BinDir, rlx_release:canonical_name(Release)),
BareRel = filename:join(BinDir, RelName),
- ErlOpts = rcl_state:get(State, erl_opts, ""),
- StartFile = case rcl_state:get(State, extended_start_script, false) of
+ ErlOpts = rlx_state:get(State, erl_opts, ""),
+ StartFile = case rlx_state:get(State, extended_start_script, false) of
false ->
bin_file_contents(RelName, RelVsn,
- rcl_release:erts(Release),
+ rlx_release:erts(Release),
ErlOpts);
true ->
- extended_bin_file_contents(RelName, RelVsn, rcl_release:erts(Release), ErlOpts)
+ extended_bin_file_contents(RelName, RelVsn, rlx_release:erts(Release), ErlOpts)
end,
%% We generate the start script by default, unless the user
%% tells us not too
- case rcl_state:get(State, generate_start_script, true) of
+ case rlx_state:get(State, generate_start_script, true) of
false ->
ok;
_ ->
@@ -241,19 +254,19 @@ write_bin_file(State, Release, OutputDir, RelDir) ->
copy_or_generate_sys_config_file(State, Release, OutputDir, RelDir).
%% @doc copy config/sys.config or generate one to releases/VSN/sys.config
--spec copy_or_generate_sys_config_file(rcl_state:t(), rcl_release:t(),
+-spec copy_or_generate_sys_config_file(rlx_state:t(), rlx_release:t(),
file:name(), file:name()) ->
- {ok, rcl_state:t()} | relcool:error().
+ {ok, rlx_state:t()} | relx:error().
copy_or_generate_sys_config_file(State, Release, OutputDir, RelDir) ->
RelSysConfPath = filename:join([RelDir, "sys.config"]),
- case rcl_state:sys_config(State) of
+ case rlx_state:sys_config(State) of
undefined ->
ok = generate_sys_config_file(RelSysConfPath),
include_erts(State, Release, OutputDir, RelDir);
ConfigPath ->
case filelib:is_regular(ConfigPath) of
false ->
- ?RCL_ERROR({config_does_not_exist, ConfigPath});
+ ?RLX_ERROR({config_does_not_exist, ConfigPath});
true ->
ok = ec_file:copy(ConfigPath, RelSysConfPath),
include_erts(State, Release, OutputDir, RelDir)
@@ -277,23 +290,23 @@ generate_sys_config_file(RelSysConfPath) ->
file:close(Fd).
%% @doc Optionally add erts directory to release, if defined.
--spec include_erts(rcl_state:t(), rcl_release:t(), file:name(), file:name()) -> {ok, rcl_state:t()} | relcool:error().
+-spec include_erts(rlx_state:t(), rlx_release:t(), file:name(), file:name()) -> {ok, rlx_state:t()} | relx:error().
include_erts(State, Release, OutputDir, RelDir) ->
- case rcl_state:get(State, include_erts, true) of
+ case rlx_state:get(State, include_erts, true) of
true ->
Prefix = code:root_dir(),
- ErtsVersion = rcl_release:erts(Release),
+ ErtsVersion = rlx_release:erts(Release),
ErtsDir = filename:join([Prefix, "erts-" ++ ErtsVersion]),
LocalErts = filename:join([OutputDir, "erts-" ++ ErtsVersion]),
case filelib:is_dir(ErtsDir) of
false ->
- ?RCL_ERROR({specified_erts_does_not_exist, ErtsVersion});
+ ?RLX_ERROR({specified_erts_does_not_exist, ErtsVersion});
true ->
ok = ec_file:mkdir_p(LocalErts),
ok = ec_file:copy(ErtsDir, LocalErts, [recursive]),
ok = ec_file:remove(filename:join([LocalErts, "bin", "erl"])),
ok = file:write_file(filename:join([LocalErts, "bin", "erl"]), erl_script(ErtsVersion)),
- case rcl_state:get(State, extended_start_script, false) of
+ case rlx_state:get(State, extended_start_script, false) of
true ->
ok = ec_file:copy(filename:join([Prefix, "bin", "start_clean.boot"]),
filename:join([OutputDir, "bin", "start_clean.boot"])),
@@ -311,58 +324,158 @@ include_erts(State, Release, OutputDir, RelDir) ->
end.
--spec make_boot_script(rcl_state:t(), rcl_release:t(), file:name(), file:name()) ->
- {ok, rcl_state:t()} | relcool:error().
+-spec make_boot_script(rlx_state:t(), rlx_release:t(), file:name(), file:name()) ->
+ {ok, rlx_state:t()} | relx:error().
make_boot_script(State, Release, OutputDir, RelDir) ->
Options = [{path, [RelDir | get_code_paths(Release, OutputDir)]},
{outdir, RelDir},
no_module_tests, silent],
- Name = erlang:atom_to_list(rcl_release:name(Release)),
+ Name = erlang:atom_to_list(rlx_release:name(Release)),
ReleaseFile = filename:join([RelDir, Name ++ ".rel"]),
- rcl_log:debug(rcl_state:log(State),
- "Creating script from release file ~s ~n with options ~p ~n",
- [ReleaseFile, Options]),
- case make_script(Name, Options) of
+ case make_script(Options,
+ fun(CorrectedOptions) ->
+ systools:make_script(Name, CorrectedOptions)
+ end) of
ok ->
- rcl_log:error(rcl_state:log(State),
+ rlx_log:error(rlx_state:log(State),
"release successfully created!"),
- {ok, State};
+ make_relup(State, Release);
error ->
- ?RCL_ERROR({release_script_generation_error, ReleaseFile});
+ ?RLX_ERROR({release_script_generation_error, ReleaseFile});
{ok, _, []} ->
- rcl_log:error(rcl_state:log(State),
+ rlx_log:error(rlx_state:log(State),
"release successfully created!"),
- {ok, State};
+ make_relup(State, Release);
{ok,Module,Warnings} ->
- ?RCL_ERROR({release_script_generation_warn, Module, Warnings});
+ ?RLX_ERROR({release_script_generation_warn, Module, Warnings});
{error,Module,Error} ->
- ?RCL_ERROR({release_script_generation_error, Module, Error})
+ ?RLX_ERROR({release_script_generation_error, Module, Error})
end.
--spec make_script(string(), [term()]) ->
- ok |
- error |
- {ok, module(), [term()]} |
- {error,module,[term()]}.
-make_script(Name, Options) ->
+-spec make_script([term()],
+ fun(([term()]) -> Res)) -> Res.
+make_script(Options, RunFun) ->
%% Erts 5.9 introduced a non backwards compatible option to
%% erlang this takes that into account
Erts = erlang:system_info(version),
case ec_semver:gte(Erts, "5.9") of
true ->
- systools:make_script(Name, [no_warn_sasl | Options]);
+ RunFun([no_warn_sasl | Options]);
_ ->
- systools:make_script(Name, Options)
+ RunFun(Options)
+ end.
+
+make_relup(State, Release) ->
+ case rlx_state:action(State) of
+ relup ->
+ UpFrom =
+ case rlx_state:upfrom(State) of
+ undefined ->
+ get_last_release(State, Release);
+ Vsn ->
+ get_up_release(State, Release, Vsn)
+ end,
+ case UpFrom of
+ undefined ->
+ ?RLX_ERROR(no_upfrom_release_found);
+ _ ->
+ make_upfrom_script(State, Release, UpFrom)
+ end;
+ _ ->
+ {ok, State}
+ end.
+
+make_upfrom_script(State, Release, UpFrom) ->
+ OutputDir = rlx_state:output_dir(State),
+ Options = [{outdir, OutputDir},
+ {path, get_code_paths(Release, OutputDir) ++
+ get_code_paths(UpFrom, OutputDir)},
+ silent],
+ CurrentRel = strip_rel(rlx_release:relfile(Release)),
+ UpFromRel = strip_rel(rlx_release:relfile(UpFrom)),
+ rlx_log:debug(rlx_state:log(State),
+ "systools:make_relup(~p, ~p, ~p, ~p)",
+ [CurrentRel, UpFromRel, UpFromRel, Options]),
+ case make_script(Options,
+ fun(CorrectOptions) ->
+ systools:make_relup(CurrentRel, [UpFromRel], [UpFromRel], CorrectOptions)
+ end) of
+ ok ->
+ rlx_log:error(rlx_state:log(State),
+ "relup from ~s to ~s successfully created!",
+ [UpFromRel, CurrentRel]),
+ {ok, State};
+ error ->
+ ?RLX_ERROR({relup_script_generation_error, CurrentRel, UpFromRel});
+ {ok, RelUp, _, []} ->
+ rlx_log:error(rlx_state:log(State),
+ "relup successfully created!"),
+ write_relup_file(State, Release, RelUp),
+ {ok, State};
+ {ok,_, Module,Warnings} ->
+ ?RLX_ERROR({relup_script_generation_warn, Module, Warnings});
+ {error,Module,Errors} ->
+ ?RLX_ERROR({relupcript_generation_error, Module, Errors})
end.
+write_relup_file(State, Release, Relup) ->
+ OutDir = release_output_dir(State, Release),
+ RelName = rlx_util:to_string(rlx_release:name(Release)),
+ RelupFile = filename:join(OutDir, RelName ++ ".relup"),
+ ok = ec_file:write_term(RelupFile, Relup).
+
+strip_rel(Name) ->
+ rlx_util:to_string(filename:join(filename:dirname(Name),
+ filename:basename(Name, ".rel"))).
+
+
+get_up_release(State, Release, Vsn) ->
+ Name = rlx_release:name(Release),
+ try
+ ec_dictionary:get({Name, Vsn}, rlx_state:realized_releases(State))
+ catch
+ throw:notfound ->
+ undefined
+ end.
+
+get_last_release(State, Release) ->
+ Releases0 = [Rel || {{_, _}, Rel} <- ec_dictionary:to_list(rlx_state:realized_releases(State))],
+ Releases1 = lists:sort(fun(R1, R2) ->
+ ec_semver:lte(rlx_release:vsn(R1),
+ rlx_release:vsn(R2))
+ end, Releases0),
+ Res = lists:foldl(fun(_Rel, R = {found, _}) ->
+ R;
+ (Rel, Prev) ->
+ case rlx_release:vsn(Rel) == rlx_release:vsn(Release) of
+ true ->
+ {found, Prev};
+ false ->
+ Rel
+ end
+ end, undefined, Releases1),
+ case Res of
+ {found, R} ->
+ R;
+ Else ->
+ Else
+ end.
+
+-spec release_output_dir(rlx_state:t(), rlx_release:t()) -> string().
+release_output_dir(State, Release) ->
+ OutputDir = rlx_state:output_dir(State),
+ filename:join([OutputDir,
+ "releases",
+ rlx_release:canonical_name(Release)]).
+
%% @doc Generates the correct set of code paths for the system.
--spec get_code_paths(rcl_release:t(), file:name()) -> [file:name()].
+-spec get_code_paths(rlx_release:t(), file:name()) -> [file:name()].
get_code_paths(Release, OutDir) ->
LibDir = filename:join(OutDir, "lib"),
[filename:join([LibDir,
- erlang:atom_to_list(rcl_app_info:name(App)) ++ "-" ++
- rcl_app_info:vsn_as_string(App), "ebin"]) ||
- App <- rcl_release:application_details(Release)].
+ erlang:atom_to_list(rlx_app_info:name(App)) ++ "-" ++
+ rlx_app_info:vsn_as_string(App), "ebin"]) ||
+ App <- rlx_release:application_details(Release)].
erl_script(ErtsVsn) ->
[<<"#!/bin/sh
diff --git a/src/rcl_prv_config.erl b/src/rlx_prv_config.erl
index dfbc321..36a0527 100644
--- a/src/rcl_prv_config.erl
+++ b/src/rlx_prv_config.erl
@@ -21,31 +21,31 @@
%%% A module that provides config parsing and support to the system
%%% @end
%%%-------------------------------------------------------------------
--module(rcl_prv_config).
+-module(rlx_prv_config).
--behaviour(rcl_provider).
+-behaviour(rlx_provider).
%% API
-export([init/1,
do/1,
format_error/1]).
--include_lib("relcool/include/relcool.hrl").
+-include_lib("relx/include/relx.hrl").
%%%===================================================================
%%% API
%%%===================================================================
%% @doc Required by the system, but not used in this provider
--spec init(rcl_state:t()) -> {ok, rcl_state:t()} | relcool:error().
+-spec init(rlx_state:t()) -> {ok, rlx_state:t()} | relx:error().
init(State) ->
{ok, State}.
%% @doc parse all the configs currently specified in the state,
%% populating the state as a result.
--spec do(rcl_state:t()) ->{ok, rcl_state:t()} | relcool:error().
+-spec do(rlx_state:t()) ->{ok, rlx_state:t()} | relx:error().
do(State) ->
- case rcl_state:config_file(State) of
+ case rlx_state:config_file(State) of
[] ->
search_for_dominating_config(State);
undefined ->
@@ -65,7 +65,7 @@ format_error({invalid_term, Term}) ->
%%% Internal Functions
%%%===================================================================
search_for_dominating_config({ok, Cwd}) ->
- ConfigFile = filename:join(Cwd, "relcool.config"),
+ ConfigFile = filename:join(Cwd, "relx.config"),
case ec_file:exists(ConfigFile) of
true ->
{ok, ConfigFile};
@@ -80,8 +80,8 @@ search_for_dominating_config(State0) ->
{ok, Config} ->
%% we need to set the root dir on state as well
{ok, RootDir} = parent_dir(Config),
- State1 = rcl_state:root_dir(State0, RootDir),
- load_config(Config, rcl_state:config_file(State1, Config));
+ State1 = rlx_state:root_dir(State0, RootDir),
+ load_config(Config, rlx_state:config_file(State1, Config));
no_config ->
{ok, State0}
end.
@@ -106,24 +106,24 @@ parent_dir([H | T], Acc) ->
parent_dir(T, [H | Acc]).
--spec load_config(file:filename(), rcl_state:t()) ->
- {ok, rcl_state:t()} | relcool:error().
+-spec load_config(file:filename(), rlx_state:t()) ->
+ {ok, rlx_state:t()} | relx:error().
load_config(ConfigFile, State) ->
{ok, CurrentCwd} = file:get_cwd(),
ok = file:set_cwd(filename:dirname(ConfigFile)),
Result = case file:consult(ConfigFile) of
{error, Reason} ->
- ?RCL_ERROR({consult, ConfigFile, Reason});
+ ?RLX_ERROR({consult, ConfigFile, Reason});
{ok, Terms} ->
lists:foldl(fun load_terms/2, {ok, State}, Terms)
end,
ok = file:set_cwd(CurrentCwd),
Result.
--spec load_terms(term(), {ok, rcl_state:t()} | relcool:error()) ->
- {ok, rcl_state:t()} | relcool:error().
+-spec load_terms(term(), {ok, rlx_state:t()} | relx:error()) ->
+ {ok, rlx_state:t()} | relx:error().
load_terms({default_release, RelName, RelVsn}, {ok, State}) ->
- {ok, rcl_state:default_release(State, RelName, RelVsn)};
+ {ok, rlx_state:default_configured_release(State, RelName, RelVsn)};
load_terms({paths, Paths}, {ok, State}) ->
code:add_pathsa([filename:absname(Path) || Path <- Paths]),
{ok, State};
@@ -133,7 +133,7 @@ load_terms({providers, Providers0}, {ok, State0}) ->
{_, E={error, _}} ->
E;
{Providers3, {ok, State3}} ->
- {ok, rcl_state:providers(State3, Providers3)}
+ {ok, rlx_state:providers(State3, Providers3)}
end;
load_terms({add_providers, Providers0}, {ok, State0}) ->
Providers1 = gen_providers(Providers0, State0),
@@ -141,45 +141,45 @@ load_terms({add_providers, Providers0}, {ok, State0}) ->
{_, E={error, _}} ->
E;
{Providers3, {ok, State1}} ->
- ExistingProviders = rcl_state:providers(State1),
- {ok, rcl_state:providers(State1, ExistingProviders ++ Providers3)}
+ ExistingProviders = rlx_state:providers(State1),
+ {ok, rlx_state:providers(State1, ExistingProviders ++ Providers3)}
end;
load_terms({skip_apps, SkipApps0}, {ok, State0}) ->
- {ok, rcl_state:skip_apps(State0, SkipApps0)};
+ {ok, rlx_state:skip_apps(State0, SkipApps0)};
load_terms({overrides, Overrides0}, {ok, State0}) ->
- {ok, rcl_state:overrides(State0, Overrides0)};
+ {ok, rlx_state:overrides(State0, Overrides0)};
load_terms({release, {RelName, Vsn}, Applications}, {ok, State0}) ->
- Release0 = rcl_release:new(RelName, Vsn),
- case rcl_release:goals(Release0, Applications) of
+ Release0 = rlx_release:new(RelName, Vsn),
+ case rlx_release:goals(Release0, Applications) of
E={error, _} ->
E;
{ok, Release1} ->
- {ok, rcl_state:add_release(State0, Release1)}
+ {ok, rlx_state:add_configured_release(State0, Release1)}
end;
load_terms({release, {RelName, Vsn}, {erts, ErtsVsn},
Applications}, {ok, State}) ->
- Release0 = rcl_release:erts(rcl_release:new(RelName, Vsn), ErtsVsn),
- case rcl_release:goals(Release0, Applications) of
+ Release0 = rlx_release:erts(rlx_release:new(RelName, Vsn), ErtsVsn),
+ case rlx_release:goals(Release0, Applications) of
E={error, _} ->
E;
{ok, Release1} ->
- {ok, rcl_state:add_release(State, Release1)}
+ {ok, rlx_state:add_configured_release(State, Release1)}
end;
load_terms({sys_config, SysConfig}, {ok, State}) ->
- {ok, rcl_state:sys_config(State, filename:absname(SysConfig))};
+ {ok, rlx_state:sys_config(State, filename:absname(SysConfig))};
load_terms({Name, Value}, {ok, State})
when erlang:is_atom(Name) ->
- {ok, rcl_state:put(State, Name, Value)};
+ {ok, rlx_state:put(State, Name, Value)};
load_terms(_, Error={error, _}) ->
Error;
load_terms(InvalidTerm, _) ->
- ?RCL_ERROR({invalid_term, InvalidTerm}).
+ ?RLX_ERROR({invalid_term, InvalidTerm}).
--spec gen_providers([module()], rcl_state:t()) ->
- {[rcl_provider:t()], {ok, rcl_state:t()} | relcool:error()}.
+-spec gen_providers([module()], rlx_state:t()) ->
+ {[rlx_provider:t()], {ok, rlx_state:t()} | relx:error()}.
gen_providers(Providers, State) ->
lists:foldl(fun(ProviderName, {Providers1, {ok, State1}}) ->
- {Provider, State2} = rcl_provider:new(ProviderName, State1),
+ {Provider, State2} = rlx_provider:new(ProviderName, State1),
{[Provider | Providers1], State2};
(_, E={_, {error, _}}) ->
E
diff --git a/src/rcl_prv_discover.erl b/src/rlx_prv_discover.erl
index 3627787..5e54828 100644
--- a/src/rcl_prv_discover.erl
+++ b/src/rlx_prv_discover.erl
@@ -21,36 +21,36 @@
%%% @doc This provider uses the lib_dir setting of the state. It searches the
%%% Lib Dirs looking for all OTP Applications that are available. When it finds
%%% those OTP Applications it loads the information about them and adds them to
-%%% the state of available apps. This implements the rcl_provider behaviour.
--module(rcl_prv_discover).
--behaviour(rcl_provider).
+%%% the state of available apps. This implements the rlx_provider behaviour.
+-module(rlx_prv_discover).
+-behaviour(rlx_provider).
-export([init/1,
do/1,
format_error/1]).
--include_lib("relcool/include/relcool.hrl").
+-include_lib("relx/include/relx.hrl").
%%============================================================================
%% API
%%============================================================================
--spec init(rcl_state:t()) -> {ok, rcl_state:t()}.
+-spec init(rlx_state:t()) -> {ok, rlx_state:t()}.
init(State) ->
{ok, State}.
%% @doc recursively dig down into the library directories specified in the state
%% looking for OTP Applications
--spec do(rcl_state:t()) -> {ok, rcl_state:t()} | relcool:error().
+-spec do(rlx_state:t()) -> {ok, rlx_state:t()} | relx:error().
do(State0) ->
LibDirs = get_lib_dirs(State0),
- case rcl_app_discovery:do(State0, LibDirs) of
+ case rlx_app_discovery:do(State0, LibDirs) of
{ok, AppMeta} ->
- case rcl_rel_discovery:do(State0, LibDirs, AppMeta) of
+ case rlx_rel_discovery:do(State0, LibDirs, AppMeta) of
{ok, Releases} ->
- State1 = rcl_state:available_apps(State0, AppMeta),
- {ok, rcl_state:discovered_releases(State1, lists:foldl(fun add/2,
- ec_dictionary:new(ec_dict),
- Releases))};
+ State1 = rlx_state:available_apps(State0, AppMeta),
+ {ok, rlx_state:realized_releases(State1, lists:foldl(fun add/2,
+ ec_dictionary:new(ec_dict),
+ Releases))};
Error ->
Error
end;
@@ -69,13 +69,13 @@ format_error(_) ->
%%%===================================================================
%% @doc only add the release if its not documented in the system
add(Rel, Dict) ->
- RelName = rcl_release:name(Rel),
- RelVsn = rcl_release:vsn(Rel),
+ RelName = rlx_release:name(Rel),
+ RelVsn = rlx_release:vsn(Rel),
ec_dictionary:add({RelName, RelVsn}, Rel, Dict).
get_lib_dirs(State) ->
- LibDirs0 = rcl_state:lib_dirs(State),
- case rcl_state:get(State, disable_default_libs, false) of
+ LibDirs0 = rlx_state:lib_dirs(State),
+ case rlx_state:get(State, disable_default_libs, false) of
true ->
LibDirs0;
false ->
@@ -85,15 +85,15 @@ get_lib_dirs(State) ->
add_release_output_dir(State)])
end.
--spec add_common_project_dirs(rcl_state:t()) -> [file:name()].
+-spec add_common_project_dirs(rlx_state:t()) -> [file:name()].
add_common_project_dirs(State) ->
%% Check to see if there is a rebar.config. If so then look for a deps
%% dir. If both are there then we add that to the lib dirs.
- case rcl_state:get(State, disable_project_subdirs, false) of
+ case rlx_state:get(State, disable_project_subdirs, false) of
true ->
[];
false ->
- Root = rcl_state:root_dir(State),
+ Root = rlx_state:root_dir(State),
Apps = filename:join(Root, "apps"),
Lib = filename:join(Root, "lib"),
Deps = filename:join(Root, "deps"),
@@ -108,9 +108,9 @@ add_common_project_dirs(State) ->
end, [], [Deps, Lib, Apps, Ebin])
end.
--spec add_system_lib_dir(rcl_state:t()) -> [file:name()].
+-spec add_system_lib_dir(rlx_state:t()) -> [file:name()].
add_system_lib_dir(State) ->
- ExcludeSystem = rcl_state:get(State, discover_exclude_system, false),
+ ExcludeSystem = rlx_state:get(State, discover_exclude_system, false),
case ExcludeSystem of
true ->
[];
@@ -119,11 +119,11 @@ add_system_lib_dir(State) ->
end.
add_release_output_dir(State) ->
- case rcl_state:get(State, disable_discover_release_output, false) of
+ case rlx_state:get(State, disable_discover_release_output, false) of
true ->
[];
false ->
- Output = erlang:iolist_to_binary(rcl_state:output_dir(State)),
+ Output = erlang:iolist_to_binary(rlx_state:output_dir(State)),
case ec_file:exists(erlang:binary_to_list(Output)) of
true ->
Output;
diff --git a/src/rcl_prv_overlay.erl b/src/rlx_prv_overlay.erl
index 40471ea..5fffd78 100644
--- a/src/rcl_prv_overlay.erl
+++ b/src/rlx_prv_overlay.erl
@@ -20,9 +20,9 @@
%%%
%%% @doc Given a complete built release this provider assembles that release
%%% into a release directory.
--module(rcl_prv_overlay).
+-module(rlx_prv_overlay).
--behaviour(rcl_provider).
+-behaviour(rlx_provider).
-export([init/1,
do/1,
@@ -30,26 +30,26 @@
-define(DIRECTORY_RE, ".*(\/|\\\\)$").
--include_lib("relcool/include/relcool.hrl").
+-include_lib("relx/include/relx.hrl").
%%============================================================================
%% API
%%============================================================================
--spec init(rcl_state:t()) -> {ok, rcl_state:t()}.
+-spec init(rlx_state:t()) -> {ok, rlx_state:t()}.
init(State) ->
{ok, State}.
%% @doc recursively dig down into the library directories specified in the state
%% looking for OTP Applications
--spec do(rcl_state:t()) -> {ok, rcl_state:t()} | relcool:error().
+-spec do(rlx_state:t()) -> {ok, rlx_state:t()} | relx:error().
do(State) ->
- {RelName, RelVsn} = rcl_state:default_release(State),
- Release = rcl_state:get_release(State, RelName, RelVsn),
- case rcl_release:realized(Release) of
+ {RelName, RelVsn} = rlx_state:default_configured_release(State),
+ Release = rlx_state:get_realized_release(State, RelName, RelVsn),
+ case rlx_release:realized(Release) of
true ->
generate_overlay_vars(State, Release);
false ->
- ?RCL_ERROR({unresolved_release, RelName, RelVsn})
+ ?RLX_ERROR({unresolved_release, RelName, RelVsn})
end.
-spec format_error(ErrorDetail::term()) -> iolist().
@@ -62,13 +62,13 @@ format_error({unable_to_read_varsfile, FileName, Reason}) ->
io_lib:format("Unable to read vars file (~s) for overlay due to: ~p",
[FileName, Reason]);
format_error({overlay_failed, Errors}) ->
- [[format_error(rcl_util:error_reason(Error)), "\n"] || Error <- Errors];
+ [[format_error(rlx_util:error_reason(Error)), "\n"] || Error <- Errors];
format_error({dir_render_failed, Dir, Error}) ->
io_lib:format("rendering mkdir path failed ~s with ~p",
[Dir, Error]);
format_error({unable_to_make_symlink, AppDir, TargetDir, Reason}) ->
io_lib:format("Unable to symlink directory ~s to ~s because \n~s~s",
- [AppDir, TargetDir, rcl_util:indent(1),
+ [AppDir, TargetDir, rlx_util:indent(1),
file:format_error(Reason)]);
format_error({copy_failed, FromFile, ToFile, Err}) ->
io_lib:format("Unable to copy from ~s to ~s because of ~p",
@@ -92,25 +92,25 @@ format_error({unable_to_make_dir, Absolute, Error}) ->
%%%===================================================================
%%% Internal Functions
%%%===================================================================
--spec generate_overlay_vars(rcl_state:t(), rcl_release:t()) ->
- {ok, rcl_state:t()} | relcool:error().
+-spec generate_overlay_vars(rlx_state:t(), rlx_release:t()) ->
+ {ok, rlx_state:t()} | relx:error().
generate_overlay_vars(State, Release) ->
StateVars = generate_state_vars(State),
ReleaseVars = generate_release_vars(Release),
get_overlay_vars_from_file(State, StateVars ++ ReleaseVars).
--spec get_overlay_vars_from_file(rcl_state:t(), proplists:proplist()) ->
- {ok, rcl_state:t()} | relcool:error().
+-spec get_overlay_vars_from_file(rlx_state:t(), proplists:proplist()) ->
+ {ok, rlx_state:t()} | relx:error().
get_overlay_vars_from_file(State, OverlayVars) ->
- case rcl_state:get(State, overlay_vars, undefined) of
+ case rlx_state:get(State, overlay_vars, undefined) of
undefined ->
do_overlay(State, OverlayVars);
FileName ->
read_overlay_vars(State, OverlayVars, FileName)
end.
--spec read_overlay_vars(rcl_state:t(), proplists:proplist(), file:name()) ->
- {ok, rcl_state:t()} | relcool:error().
+-spec read_overlay_vars(rlx_state:t(), proplists:proplist(), file:name()) ->
+ {ok, rlx_state:t()} | relx:error().
read_overlay_vars(State, OverlayVars, FileName) ->
RelativeRoot = get_relative_root(State),
RelativePath = filename:join(RelativeRoot, erlang:iolist_to_binary(FileName)),
@@ -123,12 +123,12 @@ read_overlay_vars(State, OverlayVars, FileName) ->
Error
end;
{error, Reason} ->
- ?RCL_ERROR({unable_to_read_varsfile, FileName, Reason})
+ ?RLX_ERROR({unable_to_read_varsfile, FileName, Reason})
end.
-spec render_overlay_vars(proplists:proplist(), proplists:proplist(),
proplists:proplist()) ->
- {ok, proplists:proplist()} | relcool:error().
+ {ok, proplists:proplist()} | relx:error().
render_overlay_vars(OverlayVars, [{Key, Value} | Rest], Acc)
when erlang:is_list(Value) ->
case io_lib:printable_list(Value) of
@@ -161,66 +161,66 @@ render_overlay_vars(OverlayVars, [KeyValue | Rest], Acc) ->
render_overlay_vars(_OverlayVars, [], Acc) ->
{ok, Acc}.
--spec generate_release_vars(rcl_release:t()) -> proplists:proplist().
+-spec generate_release_vars(rlx_release:t()) -> proplists:proplist().
generate_release_vars(Release) ->
- [{erts_vsn, rcl_release:erts(Release)},
- {release_erts_version, rcl_release:erts(Release)},
- {release_name, rcl_release:name(Release)},
- {rel_vsn, rcl_release:vsn(Release)},
- {release_version, rcl_release:vsn(Release)},
+ [{erts_vsn, rlx_release:erts(Release)},
+ {release_erts_version, rlx_release:erts(Release)},
+ {release_name, rlx_release:name(Release)},
+ {rel_vsn, rlx_release:vsn(Release)},
+ {release_version, rlx_release:vsn(Release)},
{release_applications, lists:map(fun(App) ->
- rcl_app_info:name(App)
- end, rcl_release:application_details(Release))},
- {release, [generate_app_vars(App)|| App <- rcl_release:application_details(Release)]},
+ rlx_app_info:name(App)
+ end, rlx_release:application_details(Release))},
+ {release, [generate_app_vars(App)|| App <- rlx_release:application_details(Release)]},
{release_goals, [if
erlang:is_list(Constraint) ->
Constraint;
true ->
- rcl_depsolver:format_constraint(Constraint)
- end || Constraint <- rcl_release:goals(Release)]}].
+ rlx_depsolver:format_constraint(Constraint)
+ end || Constraint <- rlx_release:goals(Release)]}].
--spec generate_app_vars(rcl_app_info:t()) -> AppInfo::tuple().
+-spec generate_app_vars(rlx_app_info:t()) -> AppInfo::tuple().
generate_app_vars(App) ->
- {rcl_app_info:name(App),
- [{version, rcl_app_info:vsn_as_string(App)},
- {dir, rcl_app_info:dir(App)},
- {active_dependencies, rcl_app_info:active_deps(App)},
- {library_dependencies, rcl_app_info:library_deps(App)},
- {link, rcl_app_info:link(App)}]}.
+ {rlx_app_info:name(App),
+ [{version, rlx_app_info:vsn_as_string(App)},
+ {dir, rlx_app_info:dir(App)},
+ {active_dependencies, rlx_app_info:active_deps(App)},
+ {library_dependencies, rlx_app_info:library_deps(App)},
+ {link, rlx_app_info:link(App)}]}.
--spec generate_state_vars(rcl_state:t()) -> proplists:proplist().
+-spec generate_state_vars(rlx_state:t()) -> proplists:proplist().
generate_state_vars(State) ->
- [{log, rcl_log:format(rcl_state:log(State))},
- {output_dir, rcl_state:output_dir(State)},
- {target_dir, rcl_state:output_dir(State)},
- {overridden, [AppName || {AppName, _} <- rcl_state:overrides(State)]},
- {overrides, rcl_state:overrides(State)},
- {goals, [rcl_depsolver:format_constraint(Constraint) ||
- Constraint <- rcl_state:goals(State)]},
- {lib_dirs, rcl_state:lib_dirs(State)},
- {config_file, rcl_state:config_file(State)},
- {providers, rcl_state:providers(State)},
- {sys_config, rcl_state:sys_config(State)},
- {root_dir, rcl_state:root_dir(State)},
- {default_release_name, case rcl_state:default_release(State) of
+ [{log, rlx_log:format(rlx_state:log(State))},
+ {output_dir, rlx_state:output_dir(State)},
+ {target_dir, rlx_state:output_dir(State)},
+ {overridden, [AppName || {AppName, _} <- rlx_state:overrides(State)]},
+ {overrides, rlx_state:overrides(State)},
+ {goals, [rlx_depsolver:format_constraint(Constraint) ||
+ Constraint <- rlx_state:goals(State)]},
+ {lib_dirs, rlx_state:lib_dirs(State)},
+ {config_file, rlx_state:config_file(State)},
+ {providers, rlx_state:providers(State)},
+ {sys_config, rlx_state:sys_config(State)},
+ {root_dir, rlx_state:root_dir(State)},
+ {default_release_name, case rlx_state:default_configured_release(State) of
{Name0, _} ->
Name0
end},
- {default_release_version, case rcl_state:default_release(State) of
+ {default_release_version, case rlx_state:default_configured_release(State) of
{_, Vsn0} ->
Vsn0
end},
- {default_release, case rcl_state:default_release(State) of
+ {default_release, case rlx_state:default_configured_release(State) of
{Name1, undefined} ->
erlang:atom_to_list(Name1);
{Name1, Vsn1} ->
erlang:atom_to_list(Name1) ++ "-" ++ Vsn1
end}].
--spec do_overlay(rcl_state:t(), proplists:proplist()) ->
- {ok, rcl_state:t()} | relcool:error().
+-spec do_overlay(rlx_state:t(), proplists:proplist()) ->
+ {ok, rlx_state:t()} | relx:error().
do_overlay(State, OverlayVars) ->
- case rcl_state:get(State, overlay, undefined) of
+ case rlx_state:get(State, overlay, undefined) of
undefined ->
{ok, State};
Overlays ->
@@ -231,44 +231,44 @@ do_overlay(State, OverlayVars) ->
end, Overlays))
end.
--spec handle_errors(rcl_state:t(), [ok | relcool:error()]) ->
- {ok, rcl_state:t()} | relcool:error().
+-spec handle_errors(rlx_state:t(), [ok | relx:error()]) ->
+ {ok, rlx_state:t()} | relx:error().
handle_errors(State, Result) ->
case [Error || Error <- Result,
- rcl_util:is_error(Error)] of
+ rlx_util:is_error(Error)] of
Errors = [_|_] ->
- ?RCL_ERROR({overlay_failed, Errors});
+ ?RLX_ERROR({overlay_failed, Errors});
[] ->
{ok, State}
end.
--spec do_individual_overlay(rcl_state:t(), proplists:proplist(),
+-spec do_individual_overlay(rlx_state:t(), proplists:proplist(),
OverlayDirective::term()) ->
- {ok, rcl_state:t()} | relcool:error().
+ {ok, rlx_state:t()} | relx:error().
do_individual_overlay(State, OverlayVars, {mkdir, Dir}) ->
- ModuleName = make_template_name("rcl_mkdir_template", Dir),
+ ModuleName = make_template_name("rlx_mkdir_template", Dir),
case erlydtl:compile(erlang:iolist_to_binary(Dir), ModuleName) of
{ok, ModuleName} ->
case render(ModuleName, OverlayVars) of
{ok, IoList} ->
Absolute = absolutize(State,
- filename:join(rcl_state:output_dir(State),
+ filename:join(rlx_state:output_dir(State),
erlang:iolist_to_binary(IoList))),
- case rcl_util:mkdir_p(Absolute) of
+ case rlx_util:mkdir_p(Absolute) of
{error, Error} ->
- ?RCL_ERROR({unable_to_make_dir, Absolute, Error});
+ ?RLX_ERROR({unable_to_make_dir, Absolute, Error});
ok ->
ok
end;
{error, Error} ->
- ?RCL_ERROR({dir_render_failed, Dir, Error})
+ ?RLX_ERROR({dir_render_failed, Dir, Error})
end;
{error, Reason} ->
- ?RCL_ERROR({unable_to_compile_template, Dir, Reason})
+ ?RLX_ERROR({unable_to_compile_template, Dir, Reason})
end;
do_individual_overlay(State, OverlayVars, {copy, From, To}) ->
- FromTemplateName = make_template_name("rcl_copy_from_template", From),
- ToTemplateName = make_template_name("rcl_copy_to_template", To),
+ FromTemplateName = make_template_name("rlx_copy_from_template", From),
+ ToTemplateName = make_template_name("rlx_copy_to_template", To),
file_render_do(OverlayVars, From, FromTemplateName,
fun(FromFile) ->
file_render_do(OverlayVars, To, ToTemplateName,
@@ -277,8 +277,8 @@ do_individual_overlay(State, OverlayVars, {copy, From, To}) ->
end)
end);
do_individual_overlay(State, OverlayVars, {template, From, To}) ->
- FromTemplateName = make_template_name("rcl_template_from_template", From),
- ToTemplateName = make_template_name("rcl_template_to_template", To),
+ FromTemplateName = make_template_name("rlx_template_from_template", From),
+ ToTemplateName = make_template_name("rlx_template_to_template", To),
file_render_do(OverlayVars, From, FromTemplateName,
fun(FromFile) ->
file_render_do(OverlayVars, To, ToTemplateName,
@@ -291,15 +291,15 @@ do_individual_overlay(State, OverlayVars, {template, From, To}) ->
write_template(OverlayVars,
FromFile1,
absolutize(State,
- filename:join(rcl_state:output_dir(State),
+ filename:join(rlx_state:output_dir(State),
erlang:iolist_to_binary(ToFile))))
end)
end).
--spec copy_to(rcl_state:t(), file:name(), file:name()) -> ok | relcool:error().
+-spec copy_to(rlx_state:t(), file:name(), file:name()) -> ok | relx:error().
copy_to(State, FromFile0, ToFile0) ->
RelativeRoot = get_relative_root(State),
- ToFile1 = absolutize(State, filename:join(rcl_state:output_dir(State),
+ ToFile1 = absolutize(State, filename:join(rlx_state:output_dir(State),
erlang:iolist_to_binary(ToFile0))),
FromFile1 = absolutize(State, filename:join(RelativeRoot,
@@ -309,7 +309,7 @@ copy_to(State, FromFile0, ToFile0) ->
filelib:ensure_dir(ToFile1),
ToFile1;
true ->
- rcl_util:mkdir_p(ToFile1),
+ rlx_util:mkdir_p(ToFile1),
erlang:iolist_to_binary(filename:join(ToFile1,
filename:basename(FromFile1)))
end,
@@ -319,15 +319,15 @@ copy_to(State, FromFile0, ToFile0) ->
ok = file:write_file_info(ToFile2, FileInfo),
ok;
{error, Err} ->
- ?RCL_ERROR({copy_failed,
+ ?RLX_ERROR({copy_failed,
FromFile1,
ToFile1, Err})
end.
get_relative_root(State) ->
- case rcl_state:config_file(State) of
+ case rlx_state:config_file(State) of
[] ->
- rcl_state:root_dir(State);
+ rlx_state:root_dir(State);
Config ->
filename:dirname(Config)
end.
@@ -343,19 +343,19 @@ is_directory(ToFile0, ToFile1) ->
-spec render_template(proplists:proplist(), iolist()) ->
- ok | relcool:error().
+ ok | relx:error().
render_template(OverlayVars, Data) ->
- TemplateName = make_template_name("rcl_template_renderer", Data),
+ TemplateName = make_template_name("rlx_template_renderer", Data),
case erlydtl:compile(Data, TemplateName) of
Good when Good =:= ok; Good =:= {ok, TemplateName} ->
case render(TemplateName, OverlayVars) of
{ok, IoData} ->
{ok, IoData};
{error, Reason} ->
- ?RCL_ERROR({unable_to_render_template, Data, Reason})
+ ?RLX_ERROR({unable_to_render_template, Data, Reason})
end;
{error, Reason} ->
- ?RCL_ERROR({unable_to_compile_template, Data, Reason})
+ ?RLX_ERROR({unable_to_compile_template, Data, Reason})
end.
write_template(OverlayVars, FromFile, ToFile) ->
@@ -369,18 +369,18 @@ write_template(OverlayVars, FromFile, ToFile) ->
ok = file:write_file_info(ToFile, FileInfo),
ok;
{error, Reason} ->
- ?RCL_ERROR({unable_to_write, ToFile, Reason})
+ ?RLX_ERROR({unable_to_write, ToFile, Reason})
end;
{error, Reason} ->
- ?RCL_ERROR({unable_to_enclosing_dir, ToFile, Reason})
+ ?RLX_ERROR({unable_to_enclosing_dir, ToFile, Reason})
end;
Error ->
Error
end.
-spec file_render_do(proplists:proplist(), iolist(), module(),
- fun((term()) -> {ok, rcl_state:t()} | relcool:error())) ->
- {ok, rcl_state:t()} | relcool:error().
+ fun((term()) -> {ok, rlx_state:t()} | relx:error())) ->
+ {ok, rlx_state:t()} | relx:error().
file_render_do(OverlayVars, Data, TemplateName, NextAction) ->
case erlydtl:compile(erlang:iolist_to_binary(Data), TemplateName) of
{ok, TemplateName} ->
@@ -388,10 +388,10 @@ file_render_do(OverlayVars, Data, TemplateName, NextAction) ->
{ok, IoList} ->
NextAction(IoList);
{error, Error} ->
- ?RCL_ERROR({render_failed, Data, Error})
+ ?RLX_ERROR({render_failed, Data, Error})
end;
{error, Reason} ->
- ?RCL_ERROR({unable_to_compile_template, Data, Reason})
+ ?RLX_ERROR({unable_to_compile_template, Data, Reason})
end.
-spec make_template_name(string(), term()) -> module().
@@ -414,5 +414,5 @@ render(ModuleName, OverlayVars) ->
end.
absolutize(State, FileName) ->
- filename:absname(filename:join(rcl_state:root_dir(State),
+ filename:absname(filename:join(rlx_state:root_dir(State),
erlang:iolist_to_binary(FileName))).
diff --git a/src/rcl_prv_release.erl b/src/rlx_prv_release.erl
index eac1f20..10e1eb0 100644
--- a/src/rcl_prv_release.erl
+++ b/src/rlx_prv_release.erl
@@ -21,27 +21,27 @@
%%% @doc This provider uses the lib_dir setting of the state. It searches the
%%% Lib Dirs looking for all OTP Applications that are available. When it finds
%%% those OTP Applications it loads the information about them and adds them to
-%%% the state of available apps. This implements the rcl_provider behaviour.
--module(rcl_prv_release).
+%%% the state of available apps. This implements the rlx_provider behaviour.
+-module(rlx_prv_release).
--behaviour(rcl_provider).
+-behaviour(rlx_provider).
-export([init/1,
do/1,
format_error/1]).
--include_lib("relcool/include/relcool.hrl").
+-include_lib("relx/include/relx.hrl").
%%============================================================================
%% API
%%============================================================================
--spec init(rcl_state:t()) -> {ok, rcl_state:t()}.
+-spec init(rlx_state:t()) -> {ok, rlx_state:t()}.
init(State) ->
{ok, State}.
%% @doc recursively dig down into the library directories specified in the state
%% looking for OTP Applications
--spec do(rcl_state:t()) -> {ok, rcl_state:t()} | relcool:error().
+-spec do(rlx_state:t()) -> {ok, rlx_state:t()} | relx:error().
do(State) ->
DepGraph = create_dep_graph(State),
find_default_release(State, DepGraph).
@@ -65,37 +65,37 @@ format_error({release_not_found, {RelName, RelVsn}}) ->
io_lib:format("No releases exist in the system for ~p:~s!", [RelName, RelVsn]);
format_error({failed_solve, Error}) ->
io_lib:format("Failed to solve release:\n ~s",
- [rcl_depsolver:format_error({error, Error})]).
+ [rlx_depsolver:format_error({error, Error})]).
%%%===================================================================
%%% Internal Functions
%%%===================================================================
--spec create_dep_graph(rcl_state:t()) -> rcl_depsolver:t().
+-spec create_dep_graph(rlx_state:t()) -> rlx_depsolver:t().
create_dep_graph(State) ->
- Apps = rcl_state:available_apps(State),
- Graph0 = rcl_depsolver:new_graph(),
+ Apps = rlx_state:available_apps(State),
+ Graph0 = rlx_depsolver:new_graph(),
lists:foldl(fun(App, Graph1) ->
- AppName = rcl_app_info:name(App),
- AppVsn = rcl_app_info:vsn(App),
- Deps = rcl_app_info:active_deps(App) ++
- rcl_app_info:library_deps(App),
- rcl_depsolver:add_package_version(Graph1,
+ AppName = rlx_app_info:name(App),
+ AppVsn = rlx_app_info:vsn(App),
+ Deps = rlx_app_info:active_deps(App) ++
+ rlx_app_info:library_deps(App),
+ rlx_depsolver:add_package_version(Graph1,
AppName,
AppVsn,
Deps)
end, Graph0, Apps).
--spec find_default_release(rcl_state:t(), rcl_depsolver:t()) ->
- {ok, rcl_state:t()} | relcool:error().
+-spec find_default_release(rlx_state:t(), rlx_depsolver:t()) ->
+ {ok, rlx_state:t()} | relx:error().
find_default_release(State, DepGraph) ->
- case rcl_state:default_release(State) of
+ case rlx_state:default_configured_release(State) of
{undefined, undefined} ->
resolve_default_release(State, DepGraph);
{RelName, undefined} ->
resolve_default_version(State, DepGraph, RelName);
{undefined, Vsn} ->
- ?RCL_ERROR({no_release_name, Vsn});
+ ?RLX_ERROR({no_release_name, Vsn});
{RelName, RelVsn} ->
solve_release(State, DepGraph, RelName, RelVsn)
end.
@@ -103,29 +103,29 @@ find_default_release(State, DepGraph) ->
resolve_default_release(State0, DepGraph) ->
%% Here we will just get the highest versioned release and run that.
case lists:sort(fun release_sort/2,
- ec_dictionary:to_list(rcl_state:releases(State0))) of
+ ec_dictionary:to_list(rlx_state:configured_releases(State0))) of
[{{RelName, RelVsn}, _} | _] ->
- State1 = rcl_state:default_release(State0, RelName, RelVsn),
+ State1 = rlx_state:default_configured_release(State0, RelName, RelVsn),
solve_release(State1, DepGraph, RelName, RelVsn);
[] ->
- ?RCL_ERROR(no_releases_in_system)
+ ?RLX_ERROR(no_releases_in_system)
end.
resolve_default_version(State0, DepGraph, RelName) ->
%% Here we will just get the lastest version and run that.
- AllReleases = ec_dictionary:to_list(rcl_state:releases(State0)),
+ AllReleases = ec_dictionary:to_list(rlx_state:configured_releases(State0)),
SpecificReleases = [Rel || Rel={{PossibleRelName, _}, _} <- AllReleases,
PossibleRelName =:= RelName],
case lists:sort(fun release_sort/2, SpecificReleases) of
[{{RelName, RelVsn}, _} | _] ->
- State1 = rcl_state:default_release(State0, RelName, RelVsn),
+ State1 = rlx_state:default_configured_release(State0, RelName, RelVsn),
solve_release(State1, DepGraph, RelName, RelVsn);
[] ->
- ?RCL_ERROR({no_releases_for, RelName})
+ ?RLX_ERROR({no_releases_for, RelName})
end.
--spec release_sort({{rcl_release:name(),rcl_release:vsn()}, term()},
- {{rcl_release:name(),rcl_release:vsn()}, term()}) ->
+-spec release_sort({{rlx_release:name(),rlx_release:vsn()}, term()},
+ {{rlx_release:name(),rlx_release:vsn()}, term()}) ->
boolean().
release_sort({{RelName, RelVsnA}, _},
{{RelName, RelVsnB}, _}) ->
@@ -139,42 +139,42 @@ release_sort({{RelNameA, RelVsnA}, _}, {{RelNameB, RelVsnB}, _}) ->
ec_semver:lte(RelVsnA, RelVsnB).
solve_release(State0, DepGraph, RelName, RelVsn) ->
- rcl_log:debug(rcl_state:log(State0),
+ rlx_log:debug(rlx_state:log(State0),
"Solving Release ~p-~s~n",
[RelName, RelVsn]),
try
- Release = rcl_state:get_release(State0, RelName, RelVsn),
- Goals = rcl_release:goals(Release),
+ Release = rlx_state:get_configured_release(State0, RelName, RelVsn),
+ Goals = rlx_release:goals(Release),
case Goals of
[] ->
- ?RCL_ERROR(no_goals_specified);
+ ?RLX_ERROR(no_goals_specified);
_ ->
- case rcl_depsolver:solve(DepGraph, Goals) of
+ case rlx_depsolver:solve(DepGraph, Goals) of
{ok, Pkgs} ->
set_resolved(State0, Release, Pkgs);
{error, Error} ->
- ?RCL_ERROR({failed_solve, Error})
+ ?RLX_ERROR({failed_solve, Error})
end
end
catch
throw:not_found ->
- ?RCL_ERROR({release_not_found, RelName, RelVsn})
+ ?RLX_ERROR({release_not_found, RelName, RelVsn})
end.
set_resolved(State, Release0, Pkgs) ->
- case rcl_release:realize(Release0, Pkgs, rcl_state:available_apps(State)) of
+ case rlx_release:realize(Release0, Pkgs, rlx_state:available_apps(State)) of
{ok, Release1} ->
- rcl_log:info(rcl_state:log(State),
+ rlx_log:info(rlx_state:log(State),
"Resolved ~p-~s~n",
- [rcl_release:name(Release1),
- rcl_release:vsn(Release1)]),
- rcl_log:debug(rcl_state:log(State),
+ [rlx_release:name(Release1),
+ rlx_release:vsn(Release1)]),
+ rlx_log:debug(rlx_state:log(State),
fun() ->
- rcl_release:format(1, Release1)
+ rlx_release:format(1, Release1)
end),
- {ok, rcl_state:update_release(State, Release1)};
+ {ok, rlx_state:add_realized_release(State, Release1)};
{error, E} ->
- ?RCL_ERROR({release_error, E})
+ ?RLX_ERROR({release_error, E})
end.
%%%===================================================================
diff --git a/src/rcl_rel_discovery.erl b/src/rlx_rel_discovery.erl
index d9012ea..53b329f 100644
--- a/src/rcl_rel_discovery.erl
+++ b/src/rlx_rel_discovery.erl
@@ -21,13 +21,13 @@
%%% @doc This provider uses the lib_dir setting of the state. It searches the
%%% Lib Dirs looking for all OTP Applications that are available. When it finds
%%% those OTP Applications it loads the information about them and adds them to
-%%% the state of available apps. This implements the rcl_provider behaviour.
--module(rcl_rel_discovery).
+%%% the state of available apps. This implements the rlx_provider behaviour.
+-module(rlx_rel_discovery).
-export([do/3,
format_error/1]).
--include_lib("relcool/include/relcool.hrl").
+-include_lib("relx/include/relx.hrl").
%%============================================================================
%% API
@@ -35,13 +35,13 @@
%% @doc recursively dig down into the library directories specified in the state
%% looking for OTP Applications
--spec do(rcl_state:t(), [filename:name()], [rcl_app_info:t()]) ->
- {ok, [rcl_release:t()]} | relcool:error().
+-spec do(rlx_state:t(), [filename:name()], [rlx_app_info:t()]) ->
+ {ok, [rlx_release:t()]} | relx:error().
do(State, LibDirs, AppMeta) ->
- rcl_log:info(rcl_state:log(State),
+ rlx_log:info(rlx_state:log(State),
fun() ->
["Resolving available releases from directories:\n",
- [[rcl_util:indent(1), LibDir, "\n"] || LibDir <- LibDirs]]
+ [[rlx_util:indent(1), LibDir, "\n"] || LibDir <- LibDirs]]
end),
resolve_rel_metadata(State, LibDirs, AppMeta).
@@ -54,7 +54,7 @@ format_error(ErrorDetails)
%%% Internal Functions
%%%===================================================================
resolve_rel_metadata(State, LibDirs, AppMeta) ->
- ReleaseMeta0 = lists:flatten(rcl_dscv_util:do(fun(LibDir, FileType) ->
+ ReleaseMeta0 = lists:flatten(rlx_dscv_util:do(fun(LibDir, FileType) ->
discover_dir(LibDir,
AppMeta,
FileType)
@@ -75,14 +75,14 @@ resolve_rel_metadata(State, LibDirs, AppMeta) ->
case Errors of
[] ->
ReleaseMeta1 = [RelMeta || {ok, RelMeta} <- ReleaseMeta0],
- rcl_log:debug(rcl_state:log(State),
+ rlx_log:debug(rlx_state:log(State),
fun() ->
["Resolved the following OTP Releases from the system: \n",
- [[rcl_release:format(1, Rel), "\n"] || Rel <- ReleaseMeta1]]
+ [[rlx_release:format(1, Rel), "\n"] || Rel <- ReleaseMeta1]]
end),
{ok, ReleaseMeta1};
_ ->
- ?RCL_ERROR(Errors)
+ ?RLX_ERROR(Errors)
end.
-spec format_detail(ErrorDetail::term()) -> iolist().
@@ -91,8 +91,8 @@ format_detail({accessing, File, eaccess}) ->
format_detail({accessing, File, Type}) ->
io_lib:format("error (~p) accessing file ~s", [Type, File]).
--spec discover_dir(file:name(), [rcl_app_info:t()], directory | file) ->
- {ok, rcl_release:t()}
+-spec discover_dir(file:name(), [rlx_app_info:t()], directory | file) ->
+ {ok, rlx_release:t()}
| {error, Reason::term()}
| {noresult, false}.
discover_dir(_File, _AppMeta, directory) ->
@@ -101,8 +101,8 @@ discover_dir(File, AppMeta, file) ->
is_valid_release(File, AppMeta).
-spec is_valid_release(file:name(),
- [rcl_app_info:t()]) ->
- {ok, rcl_release:t()}
+ [rlx_app_info:t()]) ->
+ {ok, rlx_release:t()}
| {error, Reason::term()}
| {noresult, false}.
is_valid_release(File, AppMeta) ->
@@ -118,20 +118,20 @@ resolve_release(RelFile, AppMeta) ->
{ok, [{release, {RelName, RelVsn},
{erts, ErtsVsn},
Apps}]} ->
- build_release(RelName, RelVsn, ErtsVsn, Apps, AppMeta);
+ build_release(RelFile, RelName, RelVsn, ErtsVsn, Apps, AppMeta);
{ok, InvalidRelease} ->
- ?RCL_ERROR({invalid_release_information, InvalidRelease});
+ ?RLX_ERROR({invalid_release_information, InvalidRelease});
{error, Reason} ->
- ?RCL_ERROR({unable_to_read, RelFile, Reason})
+ ?RLX_ERROR({unable_to_read, RelFile, Reason})
end.
-build_release(RelName, RelVsn, ErtsVsn, Apps, AppMeta) ->
- Release = rcl_release:erts(rcl_release:new(RelName, RelVsn),
+build_release(RelFile, RelName, RelVsn, ErtsVsn, Apps, AppMeta) ->
+ Release = rlx_release:erts(rlx_release:new(RelName, RelVsn, RelFile),
ErtsVsn),
resolve_apps(Apps, AppMeta, Release, []).
resolve_apps([], _AppMeta, Release, Acc) ->
- {ok, rcl_release:application_details(Release, Acc)};
+ {ok, rlx_release:application_details(Release, Acc)};
resolve_apps([AppInfo | Apps], AppMeta, Release, Acc) ->
AppName = erlang:element(1, AppInfo),
AppVsn = ec_semver:parse(erlang:element(2, AppInfo)),
@@ -144,13 +144,13 @@ resolve_apps([AppInfo | Apps], AppMeta, Release, Acc) ->
find_app(AppName, AppVsn, AppMeta) ->
case ec_lists:find(fun(App) ->
- NAppName = rcl_app_info:name(App),
- NAppVsn = rcl_app_info:vsn(App),
+ NAppName = rlx_app_info:name(App),
+ NAppVsn = rlx_app_info:vsn(App),
AppName == NAppName andalso
AppVsn == NAppVsn
end, AppMeta) of
{ok, Head} ->
Head;
error ->
- ?RCL_ERROR({could_not_find, {AppName, AppVsn}})
+ ?RLX_ERROR({could_not_find, {AppName, AppVsn}})
end.
diff --git a/src/rcl_release.erl b/src/rlx_release.erl
index 97465d0..68193fa 100644
--- a/src/rcl_release.erl
+++ b/src/rlx_release.erl
@@ -20,9 +20,12 @@
%%%
%%% @doc This module represents a release and its metadata and is used to
%%% manipulate the release metadata.
--module(rcl_release).
+-module(rlx_release).
-export([new/2,
+ new/3,
+ relfile/1,
+ relfile/2,
erts/2,
erts/1,
goals/2,
@@ -35,6 +38,7 @@
application_details/2,
realized/1,
metadata/1,
+ canonical_name/1,
format/1,
format/2,
format_error/1]).
@@ -48,16 +52,17 @@
application_spec/0,
application_goal/0]).
--include_lib("relcool/include/relcool.hrl").
+-include_lib("relx/include/relx.hrl").
-record(release_t, {name :: atom(),
vsn :: ec_semver:any_version(),
erts :: ec_semver:any_version(),
- goals = [] :: [rcl_depsolver:constraint()],
+ goals = [] :: [rlx_depsolver:constraint()],
realized = false :: boolean(),
annotations = undefined :: annotations(),
applications = [] :: [application_spec()],
- app_detail = [] :: [rcl_app_info:t()]}).
+ relfile :: undefined | string(),
+ app_detail = [] :: [rlx_app_info:t()]}).
%%============================================================================
%% types
@@ -73,7 +78,7 @@
{app_name(), app_vsn(), app_type() | incl_apps()} |
{app_name(), app_vsn(), app_type(), incl_apps()}.
--type application_constraint() :: rcl_depsolver:raw_constraint() | string() | binary().
+-type application_constraint() :: rlx_depsolver:raw_constraint() | string() | binary().
-type application_goal() :: application_constraint()
| {application_constraint(), app_type() | incl_apps()}
| {application_constraint(), app_type(), incl_apps() | none}.
@@ -87,11 +92,25 @@
%%============================================================================
%% API
%%============================================================================
--spec new(atom(), string()) -> t().
-new(ReleaseName, ReleaseVsn) ->
+-spec new(atom(), string(), undefined | file:name()) -> t().
+new(ReleaseName, ReleaseVsn, Relfile) ->
#release_t{name=to_atom(ReleaseName), vsn=ReleaseVsn,
+ relfile = Relfile,
annotations=ec_dictionary:new(ec_dict)}.
+-spec new(atom(), string()) -> t().
+new(ReleaseName, ReleaseVsn) ->
+ new(ReleaseName, ReleaseVsn, undefined).
+
+
+-spec relfile(t()) -> file:name() | undefined.
+relfile(#release_t{relfile=Relfile}) ->
+ Relfile.
+
+-spec relfile(t(), file:name()) -> t().
+relfile(Release, Relfile) ->
+ Release#release_t{relfile=Relfile}.
+
-spec name(t()) -> atom().
name(#release_t{name=Name}) ->
Name.
@@ -108,7 +127,7 @@ erts(Release, Vsn) ->
erts(#release_t{erts=Vsn}) ->
Vsn.
--spec goals(t(), [application_goal()]) -> {ok, t()} | relcool:error().
+-spec goals(t(), [application_goal()]) -> {ok, t()} | relx:error().
goals(Release, Goals0) ->
lists:foldl(fun parse_goal0/2,
{ok, Release}, Goals0).
@@ -117,11 +136,11 @@ goals(Release, Goals0) ->
goals(#release_t{goals=Goals}) ->
Goals.
--spec realize(t(), [{app_name(), app_vsn()}], [rcl_app_info:t()]) ->
- {ok, t()} | relcool:error().
+-spec realize(t(), [{app_name(), app_vsn()}], [rlx_app_info:t()]) ->
+ {ok, t()} | relx:error().
realize(Rel, Pkgs0, World0) ->
World1 = subset_world(Pkgs0, World0),
- case rcl_topo:sort_apps(World1) of
+ case rlx_topo:sort_apps(World1) of
{ok, Pkgs1} ->
process_specs(realize_erts(Rel), Pkgs1);
Error={error, _} ->
@@ -134,16 +153,16 @@ realize(Rel, Pkgs0, World0) ->
applications(#release_t{applications=Apps}) ->
Apps.
-%% @doc this gives the rcl_app_info objects representing the applications in
+%% @doc this gives the rlx_app_info objects representing the applications in
%% this release. These should only be populated by the 'realize' call in this
%% module or by reading an existing rel file.
--spec application_details(t()) -> [rcl_app_info:t()].
+-spec application_details(t()) -> [rlx_app_info:t()].
application_details(#release_t{app_detail=App}) ->
App.
%% @doc this is only expected to be called by a process building a new release
%% from an existing rel file.
--spec application_details(t(), [rcl_app_info:t()]) -> t().
+-spec application_details(t(), [rlx_app_info:t()]) -> t().
application_details(Release, AppDetail) ->
Release#release_t{app_detail=AppDetail}.
@@ -159,9 +178,15 @@ metadata(#release_t{name=Name, vsn=Vsn, erts=ErtsVsn, applications=Apps,
{ok, {release, {erlang:atom_to_list(Name), Vsn}, {erts, ErtsVsn},
Apps}};
false ->
- ?RCL_ERROR({not_realized, Name, Vsn})
+ ?RLX_ERROR({not_realized, Name, Vsn})
end.
+%% @doc produce the canonical name (<name>-<vsn>) for this release
+-spec canonical_name(t()) -> string().
+canonical_name(#release_t{name=Name, vsn=Vsn}) ->
+ erlang:binary_to_list(erlang:iolist_to_binary([erlang:atom_to_list(Name), "-",
+ Vsn])).
+
-spec format(t()) -> iolist().
format(Release) ->
format(0, Release).
@@ -169,31 +194,32 @@ format(Release) ->
-spec format(non_neg_integer(), t()) -> iolist().
format(Indent, #release_t{name=Name, vsn=Vsn, erts=ErtsVsn, realized=Realized,
goals = Goals, applications=Apps}) ->
- BaseIndent = rcl_util:indent(Indent),
- [BaseIndent, "release: ", rcl_util:to_string(Name), "-", Vsn, "\n",
- rcl_util:indent(Indent + 1), " erts-", ErtsVsn,
+ BaseIndent = rlx_util:indent(Indent),
+ [BaseIndent, "release: ", rlx_util:to_string(Name), "-", Vsn, "\n",
+ rlx_util:indent(Indent + 1), " erts-", ErtsVsn,
", realized = ", erlang:atom_to_list(Realized), "\n",
BaseIndent, "goals: \n",
- [[rcl_util:indent(Indent + 1), format_goal(Goal), ",\n"] || Goal <- Goals],
+ [[rlx_util:indent(Indent + 1), format_goal(Goal), ",\n"] || Goal <- Goals],
case Realized of
true ->
[BaseIndent, "applications: \n",
- [[rcl_util:indent(Indent + 1), io_lib:format("~p", [App]), ",\n"] ||
+ [[rlx_util:indent(Indent + 1), io_lib:format("~p", [App]), ",\n"] ||
App <- Apps]];
false ->
[]
end].
+
-spec format_goal(application_goal()) -> iolist().
format_goal({Constraint, AppType}) ->
- io_lib:format("~p", [{rcl_depsolver:format_constraint(Constraint), AppType}]);
+ io_lib:format("~p", [{rlx_depsolver:format_constraint(Constraint), AppType}]);
format_goal({Constraint, AppType, AppInc}) ->
- io_lib:format("~p", [{rcl_depsolver:format_constraint(Constraint), AppType, AppInc}]);
+ io_lib:format("~p", [{rlx_depsolver:format_constraint(Constraint), AppType, AppInc}]);
format_goal(Constraint) ->
- rcl_depsolver:format_constraint(Constraint).
+ rlx_depsolver:format_constraint(Constraint).
-spec format_error(Reason::term()) -> iolist().
format_error({topo_error, E}) ->
- rcl_topo:format_error(E);
+ rlx_topo:format_error(E);
format_error({failed_to_parse, Con}) ->
io_lib:format("Failed to parse constraint ~p", [Con]);
format_error({invalid_constraint, _, Con}) ->
@@ -211,30 +237,30 @@ realize_erts(Rel=#release_t{erts=undefined}) ->
realize_erts(Rel) ->
Rel.
--spec process_specs(t(), [rcl_app_info:t()]) ->
+-spec process_specs(t(), [rlx_app_info:t()]) ->
{ok, t()}.
process_specs(Rel=#release_t{annotations=Annots,
goals=Goals}, World) ->
- ActiveApps = lists:flatten([rcl_app_info:active_deps(El) || El <- World] ++
+ ActiveApps = lists:flatten([rlx_app_info:active_deps(El) || El <- World] ++
[case get_app_name(Goal) of
{error, _} -> [];
G -> G
end || Goal <- Goals]),
- LibraryApps = lists:flatten([rcl_app_info:library_deps(El) || El <- World]),
+ LibraryApps = lists:flatten([rlx_app_info:library_deps(El) || El <- World]),
Specs = [create_app_spec(Annots, App, ActiveApps, LibraryApps) || App <- World],
{ok, Rel#release_t{annotations=Annots,
applications=Specs,
app_detail=World,
realized=true}}.
--spec create_app_spec(annotations(), rcl_app_info:t(), [app_name()],
+-spec create_app_spec(annotations(), rlx_app_info:t(), [app_name()],
[app_name()]) ->
application_spec().
create_app_spec(Annots, App, ActiveApps, LibraryApps) ->
%% If the app only exists as a dependency in a library app then it should
%% get the 'load' annotation unless the release spec has provided something
%% else
- AppName = rcl_app_info:name(App),
+ AppName = rlx_app_info:name(App),
TypeAnnot =
case (lists:member(AppName, LibraryApps) and
(not lists:member(AppName, ActiveApps))) of
@@ -255,7 +281,7 @@ create_app_spec(Annots, App, ActiveApps, LibraryApps) ->
throw:not_found ->
{TypeAnnot, none}
end,
- Vsn = rcl_app_info:vsn_as_string(App),
+ Vsn = rlx_app_info:vsn_as_string(App),
case BaseAnnots of
{none, none} ->
{AppName, Vsn};
@@ -267,16 +293,16 @@ create_app_spec(Annots, App, ActiveApps, LibraryApps) ->
{AppName, Vsn, Type, Incld1}
end.
--spec subset_world([{app_name(), app_vsn()}], [rcl_app_info:t()]) -> [rcl_app_info:t()].
+-spec subset_world([{app_name(), app_vsn()}], [rlx_app_info:t()]) -> [rlx_app_info:t()].
subset_world(Pkgs, World) ->
[get_app_info(Pkg, World) || Pkg <- Pkgs].
--spec get_app_info({app_name(), app_vsn()}, [rcl_app_info:t()]) -> rcl_app_info:t().
+-spec get_app_info({app_name(), app_vsn()}, [rlx_app_info:t()]) -> rlx_app_info:t().
get_app_info({PkgName, PkgVsn}, World) ->
{ok, WorldEl} =
ec_lists:find(fun(El) ->
- rcl_app_info:name(El) =:= PkgName andalso
- rcl_app_info:vsn(El) =:= PkgVsn
+ rlx_app_info:name(El) =:= PkgName andalso
+ rlx_app_info:vsn(El) =:= PkgVsn
end, World),
WorldEl.
@@ -315,7 +341,7 @@ parse_goal0(Constraint0, {ok, Release}) ->
parse_goal0(_, E = {error, _}) ->
E;
parse_goal0(Constraint, _) ->
- ?RCL_ERROR({invalid_constraint, 1, Constraint}).
+ ?RLX_ERROR({invalid_constraint, 1, Constraint}).
parse_goal1(Release = #release_t{annotations=Annots, goals=Goals},
Constraint, NewAnnots) ->
@@ -329,12 +355,12 @@ parse_goal1(Release = #release_t{annotations=Annots, goals=Goals},
end.
-spec parse_constraint(application_constraint()) ->
- rcl_depsolver:constraint() | relcool:error().
+ rlx_depsolver:constraint() | relx:error().
parse_constraint(Constraint0)
when erlang:is_list(Constraint0); erlang:is_binary(Constraint0) ->
- case rcl_goal:parse(Constraint0) of
+ case rlx_goal:parse(Constraint0) of
{fail, _} ->
- ?RCL_ERROR({failed_to_parse, Constraint0});
+ ?RLX_ERROR({failed_to_parse, Constraint0});
{ok, Constraint1} ->
{ok, Constraint1}
end;
@@ -342,17 +368,17 @@ parse_constraint(Constraint0)
when erlang:is_tuple(Constraint0);
erlang:is_atom(Constraint0) ->
Constraint1 = parse_version(Constraint0),
- case rcl_depsolver:is_valid_constraint(Constraint1) of
+ case rlx_depsolver:is_valid_constraint(Constraint1) of
false ->
- ?RCL_ERROR({invalid_constraint, 2, Constraint0});
+ ?RLX_ERROR({invalid_constraint, 2, Constraint0});
true ->
{ok, Constraint1}
end;
parse_constraint(Constraint) ->
- ?RCL_ERROR({invalid_constraint, 3, Constraint}).
+ ?RLX_ERROR({invalid_constraint, 3, Constraint}).
--spec get_app_name(rcl_depsolver:raw_constraint()) ->
- AppName::atom() | relcool:error().
+-spec get_app_name(rlx_depsolver:raw_constraint()) ->
+ AppName::atom() | relx:error().
get_app_name(AppName) when erlang:is_atom(AppName) ->
AppName;
get_app_name({AppName, _}) when erlang:is_atom(AppName) ->
@@ -362,22 +388,22 @@ get_app_name({AppName, _, _}) when erlang:is_atom(AppName) ->
get_app_name({AppName, _, _, _}) when erlang:is_atom(AppName) ->
AppName;
get_app_name(V) ->
- ?RCL_ERROR({invalid_constraint, 4, V}).
+ ?RLX_ERROR({invalid_constraint, 4, V}).
--spec parse_version(rcl_depsolver:raw_constraint()) ->
- rcl_depsolver:constraint().
+-spec parse_version(rlx_depsolver:raw_constraint()) ->
+ rlx_depsolver:constraint().
parse_version({AppName, Version})
when erlang:is_binary(Version);
erlang:is_list(Version) ->
- {AppName, rcl_depsolver:parse_version(Version)};
+ {AppName, rlx_depsolver:parse_version(Version)};
parse_version({AppName, Version, Constraint})
when erlang:is_binary(Version);
erlang:is_list(Version) ->
- {AppName, rcl_depsolver:parse_version(Version), Constraint};
+ {AppName, rlx_depsolver:parse_version(Version), Constraint};
parse_version({AppName, Version, Constraint0, Constraint1})
when erlang:is_binary(Version);
erlang:is_list(Version) ->
- {AppName, rcl_depsolver:parse_version(Version), Constraint1, Constraint0};
+ {AppName, rlx_depsolver:parse_version(Version), Constraint1, Constraint0};
parse_version(Constraint) ->
Constraint.
diff --git a/src/rcl_state.erl b/src/rlx_state.erl
index 4b21bbe..9b0811f 100644
--- a/src/rcl_state.erl
+++ b/src/rlx_state.erl
@@ -18,13 +18,14 @@
%%% @author Eric Merritt <[email protected]>
%%% @copyright (C) 2012 Erlware, LLC.
%%%
-%%% @doc Provides state management services for the relcool tool. Generally,
+%%% @doc Provides state management services for the relx tool. Generally,
%%% those things that are fixed have a direct api. Those things that are mutable
%%% have a more mutable api.
--module(rcl_state).
+-module(rlx_state).
-export([new/2,
log/1,
+ action/1,
output_dir/1,
lib_dirs/1,
overrides/1,
@@ -40,14 +41,16 @@
sys_config/2,
root_dir/1,
root_dir/2,
- add_release/2,
- get_release/3,
- update_release/2,
- releases/1,
- discovered_releases/1,
- discovered_releases/2,
- default_release/1,
- default_release/3,
+ add_configured_release/2,
+ get_configured_release/3,
+ configured_releases/1,
+ realized_releases/1,
+ realized_releases/2,
+ add_realized_release/2,
+ get_realized_release/3,
+ update_realized_release/2,
+ default_configured_release/1,
+ default_configured_release/3,
available_apps/1,
available_apps/2,
get/2,
@@ -55,6 +58,7 @@
put/3,
caller/1,
caller/2,
+ upfrom/1,
format/1,
format/2]).
@@ -63,22 +67,23 @@
releases/0,
cmd_args/0]).
--record(state_t, {log :: rcl_log:t(),
+-record(state_t, {log :: rlx_log:t(),
root_dir :: file:name(),
caller :: caller(),
action :: atom(),
output_dir :: file:name(),
lib_dirs=[] :: [file:name()],
config_file=[] :: file:filename() | undefined,
- goals=[] :: [rcl_depsolver:constraint()],
- providers = [] :: [rcl_provider:t()],
- available_apps = [] :: [rcl_app_info:t()],
- default_release :: {rcl_release:name(), rcl_release:vsn()},
+ goals=[] :: [rlx_depsolver:constraint()],
+ providers = [] :: [rlx_provider:t()],
+ available_apps = [] :: [rlx_app_info:t()],
+ default_configured_release :: {rlx_release:name(), rlx_release:vsn()},
sys_config :: file:filename() | undefined,
overrides :: [{AppName::atom(), Directory::file:filename()}],
skip_apps = [] :: [AppName::atom()],
- releases :: releases(),
- discovered_releases :: releases(),
+ configured_releases :: releases(),
+ realized_releases :: releases(),
+ upfrom :: string() | binary() | undefined,
config_values :: ec_dictionary:dictionary(Key::atom(),
Value::term())}).
@@ -86,9 +91,9 @@
%% types
%%============================================================================
--type releases() :: ec_dictionary:dictionary({rcl_release:name(),
- rcl_release:vsn()},
- rcl_release:t()).
+-type releases() :: ec_dictionary:dictionary({rlx_release:name(),
+ rlx_release:vsn()},
+ rlx_release:t()).
-type cmd_args() :: proplists:proplist().
-type caller() :: command_line | api.
@@ -104,24 +109,31 @@ new(PropList, Target)
erlang:is_atom(Target) ->
{ok, Root} = file:get_cwd(),
State0 =
- #state_t{log = proplists:get_value(log, PropList, rcl_log:new(error)),
+ #state_t{log = proplists:get_value(log, PropList, rlx_log:new(error)),
output_dir=proplists:get_value(output_dir, PropList, ""),
lib_dirs=[to_binary(Dir) || Dir <- proplists:get_value(lib_dirs, PropList, [])],
config_file=proplists:get_value(config, PropList, undefined),
action = Target,
+ caller = proplists:get_value(caller, PropList, api),
goals=proplists:get_value(goals, PropList, []),
providers = [],
- releases=ec_dictionary:new(ec_dict),
- discovered_releases=ec_dictionary:new(ec_dict),
+ configured_releases=ec_dictionary:new(ec_dict),
+ realized_releases=ec_dictionary:new(ec_dict),
config_values=ec_dictionary:new(ec_dict),
overrides = proplists:get_value(overrides, PropList, []),
root_dir = proplists:get_value(root_dir, PropList, Root),
- default_release={proplists:get_value(relname, PropList, undefined),
+ upfrom = proplists:get_value(upfrom, PropList, undefined),
+ default_configured_release={proplists:get_value(relname, PropList, undefined),
proplists:get_value(relvsn, PropList, undefined)}},
- rcl_state:put(create_logic_providers(State0),
+ rlx_state:put(create_logic_providers(State0),
disable_default_libs,
proplists:get_value(disable_default_libs, PropList, false)).
+%% @doc the action targeted for this system
+-spec action(t()) -> atom().
+action(#state_t{action=Action}) ->
+ Action.
+
%% @doc the application overrides for the system
-spec overrides(t()) -> [{AppName::atom(), Directory::file:filename()}].
overrides(#state_t{overrides=Overrides}) ->
@@ -143,7 +155,7 @@ skip_apps(State, SkipApps) ->
State#state_t{skip_apps=SkipApps}.
%% @doc get the current log state for the system
--spec log(t()) -> rcl_log:t().
+-spec log(t()) -> rlx_log:t().
log(#state_t{log=LogState}) ->
LogState.
@@ -155,7 +167,7 @@ output_dir(#state_t{output_dir=OutDir}) ->
lib_dirs(#state_t{lib_dirs=LibDir}) ->
LibDir.
--spec goals(t()) -> [rcl_depsolver:constraint()].
+-spec goals(t()) -> [rlx_depsolver:constraint()].
goals(#state_t{goals=TS}) ->
TS.
@@ -167,7 +179,7 @@ config_file(#state_t{config_file=ConfigFiles}) ->
config_file(State, ConfigFiles) ->
State#state_t{config_file=ConfigFiles}.
--spec providers(t()) -> [rcl_provider:t()].
+-spec providers(t()) -> [rlx_provider:t()].
providers(#state_t{providers=Providers}) ->
Providers.
@@ -187,54 +199,65 @@ root_dir(#state_t{root_dir=RootDir}) ->
root_dir(State, RootDir) ->
State#state_t{root_dir=RootDir}.
--spec providers(t(), [rcl_provider:t()]) -> t().
+-spec providers(t(), [rlx_provider:t()]) -> t().
providers(M, NewProviders) ->
M#state_t{providers=NewProviders}.
--spec add_release(t(), rcl_release:t()) -> t().
-add_release(M=#state_t{releases=Releases}, Release) ->
- M#state_t{releases=ec_dictionary:add({rcl_release:name(Release),
- rcl_release:vsn(Release)},
- Release,
- Releases)}.
-
--spec update_release(t(), rcl_release:t()) -> t().
-update_release(M=#state_t{releases=Releases}, Release) ->
- M#state_t{releases=ec_dictionary:add({rcl_release:name(Release),
- rcl_release:vsn(Release)},
+-spec add_configured_release(t(), rlx_release:t()) -> t().
+add_configured_release(M=#state_t{configured_releases=Releases}, Release) ->
+ M#state_t{configured_releases=ec_dictionary:add({rlx_release:name(Release),
+ rlx_release:vsn(Release)},
Release,
Releases)}.
--spec get_release(t(), rcl_release:name(), rcl_release:vsn()) -> rcl_release:t().
-get_release(#state_t{releases=Releases}, Name, Vsn) ->
+-spec get_configured_release(t(), rlx_release:name(), rlx_release:vsn()) -> rlx_release:t().
+get_configured_release(#state_t{configured_releases=Releases}, Name, Vsn) ->
ec_dictionary:get({Name, Vsn}, Releases).
--spec releases(t()) -> releases().
-releases(#state_t{releases=Releases}) ->
+-spec configured_releases(t()) -> releases().
+configured_releases(#state_t{configured_releases=Releases}) ->
Releases.
--spec discovered_releases(t()) -> releases().
-discovered_releases(#state_t{discovered_releases=Releases}) ->
+-spec realized_releases(t()) -> releases().
+realized_releases(#state_t{realized_releases=Releases}) ->
Releases.
--spec discovered_releases(t(), releases()) -> t().
-discovered_releases(State, Releases) ->
- State#state_t{discovered_releases=Releases}.
+-spec realized_releases(t(), releases()) -> t().
+realized_releases(State, Releases) ->
+ State#state_t{realized_releases=Releases}.
--spec default_release(t()) ->
- {rcl_release:name() | undefined, rcl_release:vsn() | undefined}.
-default_release(#state_t{default_release=Def}) ->
+-spec add_realized_release(t(), rlx_release:t()) -> t().
+add_realized_release(State = #state_t{realized_releases=Releases}, Release) ->
+ NewReleases = ec_dictionary:add({rlx_release:name(Release), rlx_release:vsn(Release)},
+ Release, Releases),
+ State#state_t{realized_releases=NewReleases}.
+
+-spec get_realized_release(t(), rlx_release:name(), rlx_release:vsn()) -> rlx_release:t().
+get_realized_release(#state_t{realized_releases=Releases}, Name, Vsn) ->
+ ec_dictionary:get({Name, Vsn}, Releases).
+
+-spec update_realized_release(t(), rlx_release:t()) ->
+ t().
+update_realized_release(M=#state_t{realized_releases=Releases}, Release) ->
+ M#state_t{realized_releases=ec_dictionary:add({rlx_release:name(Release),
+ rlx_release:vsn(Release)},
+ Release,
+ Releases)}.
+
+-spec default_configured_release(t()) ->
+ {rlx_release:name() | undefined, rlx_release:vsn() | undefined}.
+default_configured_release(#state_t{default_configured_release=Def}) ->
Def.
--spec default_release(t(), rcl_release:name(), rcl_release:vsn()) -> t().
-default_release(M, Name, Vsn) ->
- M#state_t{default_release={Name, Vsn}}.
+-spec default_configured_release(t(), rlx_release:name(), rlx_release:vsn()) -> t().
+default_configured_release(M, Name, Vsn) ->
+ M#state_t{default_configured_release={Name, Vsn}}.
--spec available_apps(t()) -> [rcl_app_info:t()].
+-spec available_apps(t()) -> [rlx_app_info:t()].
available_apps(#state_t{available_apps=Apps}) ->
Apps.
--spec available_apps(t(), [rcl_app_info:t()]) -> t().
+-spec available_apps(t(), [rlx_app_info:t()]) -> t().
available_apps(M, NewApps) ->
M#state_t{available_apps=NewApps}.
@@ -266,6 +289,10 @@ caller(#state_t{caller=Caller}) ->
caller(S, Caller) ->
S#state_t{caller=Caller}.
+-spec upfrom(t()) -> string() | binary() | undefined.
+upfrom(#state_t{upfrom=UpFrom}) ->
+ UpFrom.
+
-spec format(t()) -> iolist().
format(Mod) ->
format(Mod, 0).
@@ -277,19 +304,19 @@ format(#state_t{log=LogState, output_dir=OutDir, lib_dirs=LibDirs,
providers=Providers},
Indent) ->
Values1 = ec_dictionary:to_list(Values0),
- [rcl_util:indent(Indent),
+ [rlx_util:indent(Indent),
<<"state(">>, erlang:atom_to_list(Caller), <<"):\n">>,
- rcl_util:indent(Indent + 1), <<"log: ">>, rcl_log:format(LogState), <<",\n">>,
- rcl_util:indent(Indent + 1), "config file: ", rcl_util:optional_to_string(ConfigFile), "\n",
- rcl_util:indent(Indent + 1), "goals: \n",
- [[rcl_util:indent(Indent + 2), rcl_depsolver:format_constraint(Goal), ",\n"] || Goal <- Goals],
- rcl_util:indent(Indent + 1), "output_dir: ", OutDir, "\n",
- rcl_util:indent(Indent + 1), "lib_dirs: \n",
- [[rcl_util:indent(Indent + 2), LibDir, ",\n"] || LibDir <- LibDirs],
- rcl_util:indent(Indent + 1), "providers: \n",
- [[rcl_util:indent(Indent + 2), rcl_provider:format(Provider), ",\n"] || Provider <- Providers],
- rcl_util:indent(Indent + 1), "provider config values: \n",
- [[rcl_util:indent(Indent + 2), io_lib:format("~p", [Value]), ",\n"] || Value <- Values1]].
+ rlx_util:indent(Indent + 1), <<"log: ">>, rlx_log:format(LogState), <<",\n">>,
+ rlx_util:indent(Indent + 1), "config file: ", rlx_util:optional_to_string(ConfigFile), "\n",
+ rlx_util:indent(Indent + 1), "goals: \n",
+ [[rlx_util:indent(Indent + 2), rlx_depsolver:format_constraint(Goal), ",\n"] || Goal <- Goals],
+ rlx_util:indent(Indent + 1), "output_dir: ", OutDir, "\n",
+ rlx_util:indent(Indent + 1), "lib_dirs: \n",
+ [[rlx_util:indent(Indent + 2), LibDir, ",\n"] || LibDir <- LibDirs],
+ rlx_util:indent(Indent + 1), "providers: \n",
+ [[rlx_util:indent(Indent + 2), rlx_provider:format(Provider), ",\n"] || Provider <- Providers],
+ rlx_util:indent(Indent + 1), "provider config values: \n",
+ [[rlx_util:indent(Indent + 2), io_lib:format("~p", [Value]), ",\n"] || Value <- Values1]].
%%%===================================================================
%%% Internal Functions
@@ -297,11 +324,11 @@ format(#state_t{log=LogState, output_dir=OutDir, lib_dirs=LibDirs,
-spec create_logic_providers(t()) -> t().
create_logic_providers(State0) ->
- {ConfigProvider, {ok, State1}} = rcl_provider:new(rcl_prv_config, State0),
- {DiscoveryProvider, {ok, State2}} = rcl_provider:new(rcl_prv_discover, State1),
- {ReleaseProvider, {ok, State3}} = rcl_provider:new(rcl_prv_release, State2),
- {OverlayProvider, {ok, State4}} = rcl_provider:new(rcl_prv_overlay, State3),
- {AssemblerProvider, {ok, State5}} = rcl_provider:new(rcl_prv_assembler, State4),
+ {ConfigProvider, {ok, State1}} = rlx_provider:new(rlx_prv_config, State0),
+ {DiscoveryProvider, {ok, State2}} = rlx_provider:new(rlx_prv_discover, State1),
+ {ReleaseProvider, {ok, State3}} = rlx_provider:new(rlx_prv_release, State2),
+ {OverlayProvider, {ok, State4}} = rlx_provider:new(rlx_prv_overlay, State3),
+ {AssemblerProvider, {ok, State5}} = rlx_provider:new(rlx_prv_assembler, State4),
State5#state_t{providers=[ConfigProvider, DiscoveryProvider,
ReleaseProvider, OverlayProvider, AssemblerProvider]}.
@@ -320,7 +347,7 @@ to_binary(Dir)
-include_lib("eunit/include/eunit.hrl").
new_test() ->
- LogState = rcl_log:new(error),
+ LogState = rlx_log:new(error),
RCLState = new([{log, LogState}], release),
?assertMatch(LogState, log(RCLState)).
diff --git a/src/rcl_topo.erl b/src/rlx_topo.erl
index 462b7c5..11928c1 100644
--- a/src/rcl_topo.erl
+++ b/src/rlx_topo.erl
@@ -20,7 +20,7 @@
%%% @doc
%%% This is a pretty simple topological sort for erlang. It was
%%% originally written for ermake by Joe Armstrong back in '98. It
-%%% has been pretty heavily modified by Eric Merritt since '06 and modified again for Relcool.
+%%% has been pretty heavily modified by Eric Merritt since '06 and modified again for Relx.
%%%
%%% A partial order on the set S is a set of pairs {Xi,Xj} such that
%%% some relation between Xi and Xj is obeyed.
@@ -30,12 +30,12 @@
%%% order i &lt; j
%%% @end
%%%-------------------------------------------------------------------
--module(rcl_topo).
+-module(rlx_topo).
-export([sort_apps/1,
format_error/1]).
--include_lib("relcool/include/relcool.hrl").
+-include_lib("relx/include/relx.hrl").
%%====================================================================
%% Types
@@ -53,9 +53,9 @@
%% applications. This implies that you have already done the
%% constraint solve before you pass the list of apps here to be
%% sorted.
--spec sort_apps([rcl_app_info:t()]) ->
- {ok, [rcl_app_info:t()]} |
- relcool:error().
+-spec sort_apps([rlx_app_info:t()]) ->
+ {ok, [rlx_app_info:t()]} |
+ relx:error().
sort_apps(Apps) ->
Pairs = apps_to_pairs(Apps),
case sort(Pairs) of
@@ -71,9 +71,9 @@ format_error({cycle, Pairs}) ->
"before we can continue:\n",
case Pairs of
[{P1, P2}] ->
- [rcl_util:indent(1), erlang:atom_to_list(P2), "->", erlang:atom_to_list(P1)];
+ [rlx_util:indent(1), erlang:atom_to_list(P2), "->", erlang:atom_to_list(P1)];
[{P1, P2} | Rest] ->
- [rcl_util:indent(1), erlang:atom_to_list(P2), "->", erlang:atom_to_list(P1),
+ [rlx_util:indent(1), erlang:atom_to_list(P2), "->", erlang:atom_to_list(P1),
[["-> ", erlang:atom_to_list(PP2), " -> ", erlang:atom_to_list(PP1)] || {PP1, PP2} <- Rest]];
[] ->
[]
@@ -83,43 +83,43 @@ format_error({cycle, Pairs}) ->
%% Internal Functions
%%====================================================================
%% @doc Do a topological sort on the list of pairs.
--spec sort([pair()]) -> {ok, [atom()]} | relcool:error().
+-spec sort([pair()]) -> {ok, [atom()]} | relx:error().
sort(Pairs) ->
iterate(Pairs, [], all(Pairs)).
--spec names_to_apps([atom()], [rcl_app_info:t()]) -> [rcl_app_info:t()].
+-spec names_to_apps([atom()], [rlx_app_info:t()]) -> [rlx_app_info:t()].
names_to_apps(Names, Apps) ->
[find_app_by_name(Name, Apps) || Name <- Names].
--spec find_app_by_name(atom(), [rcl_app_info:t()]) -> rcl_app_info:t().
+-spec find_app_by_name(atom(), [rlx_app_info:t()]) -> rlx_app_info:t().
find_app_by_name(Name, Apps) ->
{ok, App1} =
ec_lists:find(fun(App) ->
- rcl_app_info:name(App) =:= Name
+ rlx_app_info:name(App) =:= Name
end, Apps),
App1.
--spec apps_to_pairs([rcl_app_info:t()]) -> [pair()].
+-spec apps_to_pairs([rlx_app_info:t()]) -> [pair()].
apps_to_pairs(Apps) ->
lists:flatten([app_to_pairs(App) || App <- Apps]).
--spec app_to_pairs(rcl_app_info:t()) -> [pair()].
+-spec app_to_pairs(rlx_app_info:t()) -> [pair()].
app_to_pairs(App) ->
- [{DepApp, rcl_app_info:name(App)} ||
+ [{DepApp, rlx_app_info:name(App)} ||
DepApp <-
- rcl_app_info:active_deps(App) ++
- rcl_app_info:library_deps(App)].
+ rlx_app_info:active_deps(App) ++
+ rlx_app_info:library_deps(App)].
%% @doc Iterate over the system. @private
-spec iterate([pair()], [name()], [name()]) ->
- {ok, [name()]} | relcool:error().
+ {ok, [name()]} | relx:error().
iterate([], L, All) ->
{ok, remove_duplicates(L ++ subtract(All, L))};
iterate(Pairs, L, All) ->
case subtract(lhs(Pairs), rhs(Pairs)) of
[] ->
- ?RCL_ERROR({cycle, Pairs});
+ ?RLX_ERROR({cycle, Pairs});
Lhs ->
iterate(remove_pairs(Lhs, Pairs), L ++ Lhs, All)
end.
@@ -193,8 +193,8 @@ topo_pairs_cycle_test() ->
sort(Pairs)).
topo_apps_cycle_test() ->
- {ok, App1} = rcl_app_info:new(app1, "0.1", "/no-dir", [app2], [stdlib]),
- {ok, App2} = rcl_app_info:new(app2, "0.1", "/no-dir", [app1], []),
+ {ok, App1} = rlx_app_info:new(app1, "0.1", "/no-dir", [app2], [stdlib]),
+ {ok, App2} = rlx_app_info:new(app2, "0.1", "/no-dir", [app1], []),
Apps = [App1, App2],
?assertMatch({error, {_, {cycle, [{app2,app1},{app1,app2}]}}},
sort_apps(Apps)).
@@ -202,16 +202,16 @@ topo_apps_cycle_test() ->
topo_apps_good_test() ->
Apps = [App ||
{ok, App} <-
- [rcl_app_info:new(app1, "0.1", "/no-dir", [app2, zapp1], [stdlib, kernel]),
- rcl_app_info:new(app2, "0.1", "/no-dir", [app3], []),
- rcl_app_info:new(app3, "0.1", "/no-dir", [kernel], []),
- rcl_app_info:new(zapp1, "0.1", "/no-dir", [app2,app3,zapp2], []),
- rcl_app_info:new(stdlib, "0.1", "/no-dir", [], []),
- rcl_app_info:new(kernel, "0.1", "/no-dir", [], []),
- rcl_app_info:new(zapp2, "0.1", "/no-dir", [], [])]],
+ [rlx_app_info:new(app1, "0.1", "/no-dir", [app2, zapp1], [stdlib, kernel]),
+ rlx_app_info:new(app2, "0.1", "/no-dir", [app3], []),
+ rlx_app_info:new(app3, "0.1", "/no-dir", [kernel], []),
+ rlx_app_info:new(zapp1, "0.1", "/no-dir", [app2,app3,zapp2], []),
+ rlx_app_info:new(stdlib, "0.1", "/no-dir", [], []),
+ rlx_app_info:new(kernel, "0.1", "/no-dir", [], []),
+ rlx_app_info:new(zapp2, "0.1", "/no-dir", [], [])]],
{ok, Sorted} = sort_apps(Apps),
?assertMatch([stdlib, kernel, zapp2,
app3, app2, zapp1, app1],
- [rcl_app_info:name(App) || App <- Sorted]).
+ [rlx_app_info:name(App) || App <- Sorted]).
-endif.
diff --git a/src/rcl_util.erl b/src/rlx_util.erl
index 61e1392..c2b2081 100644
--- a/src/rcl_util.erl
+++ b/src/rlx_util.erl
@@ -19,7 +19,7 @@
%%% @copyright (C) 2012 Erlware, LLC.
%%%
%%% @doc Trivial utility file to help handle common tasks
--module(rcl_util).
+-module(rlx_util).
-export([mkdir_p/1,
to_binary/1,
@@ -58,17 +58,20 @@ to_binary(String) when erlang:is_list(String) ->
erlang:iolist_to_binary(String);
to_binary(Bin) when erlang:is_binary(Bin) ->
Bin.
+
+to_string(Binary) when erlang:is_binary(Binary) ->
+ erlang:binary_to_list(Binary);
to_string(Atom) when erlang:is_atom(Atom) ->
erlang:atom_to_list(Atom);
to_string(Else) when erlang:is_list(Else) ->
Else.
-%% @doc get the reason for a particular relcool error
--spec error_reason(relcool:error()) -> any().
+%% @doc get the reason for a particular relx error
+-spec error_reason(relx:error()) -> any().
error_reason({error, {_, Reason}}) ->
Reason.
-%% @doc check to see if the value is a relcool error
--spec is_error(relcool:error() | any()) -> boolean().
+%% @doc check to see if the value is a relx error
+-spec is_error(relx:error() | any()) -> boolean().
is_error({error, _}) ->
true;
is_error(_) ->