aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Wilberding <[email protected]>2013-05-14 20:59:32 -0700
committerJordan Wilberding <[email protected]>2013-05-14 20:59:32 -0700
commit834fc00544e4222e5fe1713c33d16e5192de33fe (patch)
tree1ae9a327feeb420983f9a85fdb6c800900369480
parentd2698281ff1b0a46b2bcf6c2579cc811a3f62500 (diff)
parentc5f0a8c9175b2d152c69f72da15e7ceff411f86b (diff)
downloadrelx-834fc00544e4222e5fe1713c33d16e5192de33fe.tar.gz
relx-834fc00544e4222e5fe1713c33d16e5192de33fe.tar.bz2
relx-834fc00544e4222e5fe1713c33d16e5192de33fe.zip
Merge pull request #2 from ericbmerritt/rename-to-relx
Relup + rename support
-rw-r--r--.gitignore4
-rw-r--r--Makefile4
-rw-r--r--README.md16
-rw-r--r--include/relx.hrl (renamed from include/relcool.hrl)11
-rw-r--r--relx.config (renamed from relcool.config)4
-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
-rw-r--r--test/rlx_command_SUITE.erl (renamed from test/rclt_command_SUITE.erl)26
-rw-r--r--test/rlx_depsolver_tester.erl (renamed from test/rcl_depsolver_tester.erl)18
-rw-r--r--test/rlx_depsolver_tests.erl (renamed from test/rcl_depsolver_tests.erl)106
-rw-r--r--test/rlx_discover_SUITE.erl (renamed from test/rclt_discover_SUITE.erl)30
-rw-r--r--test/rlx_goal_tests.erl (renamed from test/rclt_goal.erl)38
-rw-r--r--test/rlx_release_SUITE.erl (renamed from test/rclt_release_SUITE.erl)278
34 files changed, 1579 insertions, 905 deletions
diff --git a/.gitignore b/.gitignore
index 424df1e..666c837 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,8 +2,8 @@ deps/*
ebin/*
*.beam
.eunit
-.relcool_plt
-relcool
+.relx_plt
+relx
# This is a generated file that should be ignored
src/rcl_goal.erl
logs
diff --git a/Makefile b/Makefile
index 2fc0038..bfbaab8 100644
--- a/Makefile
+++ b/Makefile
@@ -88,9 +88,9 @@ ct: compile clean-common-test-data
-pa $(CURDIR)/deps/*/ebin \
-logdir $(CURDIR)/logs \
-dir $(CURDIR)/test/ \
- -suite rclt_command_SUITE rclt_discover_SUITE -suite rclt_release_SUITE
+ -suite rlx_command_SUITE rlx_discover_SUITE -suite rlx_release_SUITE
-test: compile eunit ct
+test: compile dialyzer eunit ct
$(DEPS_PLT):
@echo Building local erts plt at $(DEPS_PLT)
diff --git a/README.md b/README.md
index b235f37..e7d0655 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,12 @@
-[![Build Status](https://travis-ci.org/erlware/relcool.png)](https://travis-ci.org/erlware/relcool)
+[![Build Status](https://travis-ci.org/erlware/relx.png)](https://travis-ci.org/erlware/relx)
# NAME
-relcool - A release assembler for erlang
+relx - A release assembler for erlang
# SYNOPSIS
-relcool [*options*] [*release-specification-file*]
+relx [*options*] [*release-specification-file*]
# DESCRIPTION
@@ -16,18 +16,18 @@ applications it will generate a release output. That output depends
heavily on what plugins available and what options are defined, but
usually it is simple a well configured release directory.
- relcool -c relcool.config -l ~/my-dirs --relname foo --relvsn 0.0.1 --target-spec myapp --target-spec getopt>=0.5.1 -o output-dir
+ relx -c relx.config -l ~/my-dirs --relname foo --relvsn 0.0.1 --target-spec myapp --target-spec getopt>=0.5.1 -o output-dir
The *release-specification-file* is optional but otherwise contains
additional specification information for releases.
# BUILDING
-To build relcool and generate a standalone escript executable:
+To build relx and generate a standalone escript executable:
$ make
-This creates the executable `relcool`.
+This creates the executable `relx`.
# OPTIONS
@@ -54,7 +54,7 @@ This creates the executable `relcool`.
: The verbosity level of the system. Valid values are 1 - 3
-c *INTEGER*, \--config *INTEGER*
-: The custom config file for the relcool system
+: The custom config file for the relx system
# CONFIGURATION FILES
@@ -64,4 +64,4 @@ Configuration files
`reltool` (1).
-[relcool wiki](https://github.com/erlware/relcool/wiki)
+[relx wiki](https://github.com/erlware/relx/wiki)
diff --git a/include/relcool.hrl b/include/relx.hrl
index 11a0dec..4b78ca6 100644
--- a/include/relcool.hrl
+++ b/include/relx.hrl
@@ -1,3 +1,4 @@
+
%% Copyright 2012 Erlware, LLC. All Rights Reserved.
%%
%% This file is provided to you under the Apache License,
@@ -15,13 +16,13 @@
%% under the License.
%%
--define(RCL_ERROR, 0).
--define(RCL_INFO, 1).
--define(RCL_DEBUG, 2).
+-define(RLX_ERROR, 0).
+-define(RLX_INFO, 1).
+-define(RLX_DEBUG, 2).
-%% This is the default form of error messages for the Relcool
+%% This is the default form of error messages for the Relx
%% system. It is expected that everything that returns an error use
%% this and that they all expose a format_error/1 message that returns
%% an iolist.
--define(RCL_ERROR(Reason),
+-define(RLX_ERROR(Reason),
{error, {?MODULE, Reason}}).
diff --git a/relcool.config b/relx.config
index a86ab3f..7a3d62e 100644
--- a/relcool.config
+++ b/relx.config
@@ -1,3 +1,3 @@
%% -*- mode: Erlang; fill-column: 80; comment-column: 75; -*-
-{release, {relcool, "0.0.1"},
- [relcool]}.
+{release, {relx, "0.0.1"},
+ [relx]}.
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(_) ->
diff --git a/test/rclt_command_SUITE.erl b/test/rlx_command_SUITE.erl
index 9c96005..6f726b4 100644
--- a/test/rclt_command_SUITE.erl
+++ b/test/rlx_command_SUITE.erl
@@ -17,7 +17,7 @@
%%%-------------------------------------------------------------------
%%% @author Eric Merrit <[email protected]>
%%% @copyright (C) 2012, Eric Merrit
--module(rclt_command_SUITE).
+-module(rlx_command_SUITE).
-export([suite/0,
init_per_suite/1,
@@ -48,8 +48,8 @@ normal_passing_case(Config) ->
Lib1 = filename:join([DataDir, <<"lib1">>]),
Lib2 = filename:join([DataDir, <<"lib2">>]),
Outdir = filename:join([DataDir, "outdir"]),
- ok = rcl_util:mkdir_p(Lib1),
- ok = rcl_util:mkdir_p(Lib2),
+ ok = rlx_util:mkdir_p(Lib1),
+ ok = rlx_util:mkdir_p(Lib2),
Goal1 = "app1<=33.33+build4",
Goal2 = "app2:btwn:33.22,45.22+build.21",
@@ -58,36 +58,40 @@ normal_passing_case(Config) ->
RelVsn = "33.222",
CmdLine = ["-V", LogLevel, "-g",Goal1,"-g",Goal2, "-l", Lib1, "-l", Lib2,
"-n", RelName, "-v", RelVsn, "-o", Outdir],
- {ok, State} = rcl_cmd_args:args2state(getopt:parse(relcool:opt_spec_list(), CmdLine)),
+ {ok, {Opts, Targets}} = getopt:parse(relx:opt_spec_list(), CmdLine),
+ {ok, State} = rlx_cmd_args:args2state(Opts, Targets),
?assertMatch([Lib1, Lib2],
- rcl_state:lib_dirs(State)),
- ?assertMatch(Outdir, rcl_state:output_dir(State)),
+ rlx_state:lib_dirs(State)),
+ ?assertMatch(Outdir, rlx_state:output_dir(State)),
?assertMatch([{app1,{{33,33},{[],[<<"build4">>]}},lte},
{app2,
{{33,22},{[],[]}},
{{45,22},{[],[<<"build">>,21]}}, between}],
- rcl_state:goals(State)).
+ rlx_state:goals(State)).
lib_fail_case(Config) ->
DataDir = proplists:get_value(data_dir, Config),
Lib1 = filename:join([DataDir, "lib1"]),
Lib2 = filename:join([DataDir, "lib3333"]),
- ok = rcl_util:mkdir_p(Lib1),
+ ok = rlx_util:mkdir_p(Lib1),
CmdLine = ["-l", Lib1, "-l", Lib2],
+ {ok, {Opts, Targets}} = getopt:parse(relx:opt_spec_list(), CmdLine),
?assertMatch({error, {_, {not_directory, Lib2}}},
- rcl_cmd_args:args2state(getopt:parse(relcool:opt_spec_list(), CmdLine))).
+ rlx_cmd_args:args2state(Opts, Targets)).
spec_parse_fail_case(_Config) ->
Spec = "aaeu:3333:33.22a44",
CmdLine = ["-g", Spec],
+ {ok, {Opts, Targets}} = getopt:parse(relx:opt_spec_list(), CmdLine),
?assertMatch({error, {_, {failed_to_parse, _Spec}}},
- rcl_cmd_args:args2state(getopt:parse(relcool:opt_spec_list(), CmdLine))).
+ rlx_cmd_args:args2state(Opts, Targets)).
config_fail_case(_Config) ->
ConfigFile = "does-not-exist",
CmdLine = ["-c", ConfigFile],
+ {ok, {Opts, Targets}} = getopt:parse(relx:opt_spec_list(), CmdLine),
?assertMatch({error, {_, {invalid_config_file, ConfigFile}}},
- rcl_cmd_args:args2state(getopt:parse(relcool:opt_spec_list(), CmdLine))).
+ rlx_cmd_args:args2state(Opts, Targets)).
diff --git a/test/rcl_depsolver_tester.erl b/test/rlx_depsolver_tester.erl
index 53f5ac0..2dddf76 100644
--- a/test/rcl_depsolver_tester.erl
+++ b/test/rlx_depsolver_tester.erl
@@ -23,7 +23,7 @@
%% Additional testing for depsolver
%% @end
%%-------------------------------------------------------------------
--module(rcl_depsolver_tester).
+-module(rlx_depsolver_tester).
-export([run_data/1, run_log/1]).
-include_lib("eunit/include/eunit.hrl").
@@ -352,7 +352,7 @@ log_ea2d264b_test() ->
versionify(X) when erlang:is_list(X) ->
lists:map(fun versionify/1, X);
versionify({K, V}) ->
- {erlang:list_to_binary(K), rcl_depsolver:parse_version(V)}.
+ {erlang:list_to_binary(K), rlx_depsolver:parse_version(V)}.
fix_rebar_brokenness(Filename) ->
Alt1 = filename:join(["./test", "data", Filename]),
@@ -372,7 +372,7 @@ fix_rebar_brokenness(Filename) ->
run_data_file(Device) ->
Constraints = get_constraints(io:get_line(Device, "")),
- rcl_depsolver:solve(process_packages(read_packages(Device)), Constraints).
+ rlx_depsolver:solve(process_packages(read_packages(Device)), Constraints).
goble_lines(_Device, eof, Acc) ->
lists:reverse(Acc);
@@ -385,14 +385,14 @@ goble_lines(Device) ->
goble_lines(Device, io:get_line(Device, ""), []).
run_log_file(Device) ->
- State0 = rcl_depsolver:new_graph(),
+ State0 = rlx_depsolver:new_graph(),
{Goals, State2} =
lists:foldl(fun(Line, Data) ->
process_add_goal(Line,
process_add_constraint(Line,
process_add_package(Line, Data)))
end, {[], State0}, goble_lines(Device)),
- rcl_depsolver:solve(State2, Goals).
+ rlx_depsolver:solve(State2, Goals).
read_packages(Device) ->
process_line(Device, io:get_line(Device, ""), []).
@@ -424,8 +424,8 @@ process_line(Device, Pkg, Acc) ->
process_packages(Pkgs) ->
lists:foldl(fun({Pkg, Vsn, Constraints}, Dom0) ->
- rcl_depsolver:add_package_version(Dom0, Pkg, Vsn, Constraints)
- end, rcl_depsolver:new_graph(), Pkgs).
+ rlx_depsolver:add_package_version(Dom0, Pkg, Vsn, Constraints)
+ end, rlx_depsolver:new_graph(), Pkgs).
get_constraints(ConLine) ->
AppVsns = string:tokens(ConLine, " \n"),
@@ -446,7 +446,7 @@ process_add_package(Line, {Goals, State0}) ->
{match, [_All, _InstNumber, PkgName, _PkgCount, VersionCount]} ->
{Goals,
lists:foldl(fun(PkgVsn, State1) ->
- rcl_depsolver:add_package_version(State1,
+ rlx_depsolver:add_package_version(State1,
PkgName,
erlang:integer_to_list(PkgVsn),
[])
@@ -460,7 +460,7 @@ process_add_constraint(Line, {Goals, State0}) ->
case re:run(Line, ?ADD_VC, [{capture, all, list}]) of
{match, [_All, _InstNumber, Pkg, Vsn, Dep, _Ignore, DepVsn]} ->
{Goals,
- rcl_depsolver:add_package_version(State0, Pkg, Vsn, [{Dep, DepVsn}])};
+ rlx_depsolver:add_package_version(State0, Pkg, Vsn, [{Dep, DepVsn}])};
_ ->
{Goals, State0}
end.
diff --git a/test/rcl_depsolver_tests.erl b/test/rlx_depsolver_tests.erl
index eae31a4..7cbe831 100644
--- a/test/rcl_depsolver_tests.erl
+++ b/test/rlx_depsolver_tests.erl
@@ -20,7 +20,7 @@
%%
%% @author Eric Merritt <[email protected]>
%%-------------------------------------------------------------------
--module(rcl_depsolver_tests).
+-module(rlx_depsolver_tests).
-include_lib("eunit/include/eunit.hrl").
@@ -29,7 +29,7 @@
%%============================================================================
first_test() ->
- Dom0 = rcl_depsolver:add_packages(rcl_depsolver:new_graph(), [{app1, [{"0.1", [{app2, "0.2+build.33"},
+ Dom0 = rlx_depsolver:add_packages(rlx_depsolver:new_graph(), [{app1, [{"0.1", [{app2, "0.2+build.33"},
{app3, "0.2", '>='}]},
{"0.2", []},
{"0.3", []}]},
@@ -41,7 +41,7 @@ first_test() ->
{"0.3", []}]}]),
- case rcl_depsolver:solve(Dom0, [{app1, "0.1"}]) of
+ case rlx_depsolver:solve(Dom0, [{app1, "0.1"}]) of
{ok,[{app3,{{0,3},{[],[]}}},
{app2,{{0,2},{[],[<<"build">>,33]}}},
{app1,{{0,1},{[],[]}}}]} ->
@@ -52,7 +52,7 @@ first_test() ->
second_test() ->
- Dom0 = rcl_depsolver:add_packages(rcl_depsolver:new_graph(), [{app1, [{"0.1", [{app2, "0.1", '>='},
+ Dom0 = rlx_depsolver:add_packages(rlx_depsolver:new_graph(), [{app1, [{"0.1", [{app2, "0.1", '>='},
{app4, "0.2"},
{app3, "0.2", '>='}]},
{"0.2", []},
@@ -68,7 +68,7 @@ second_test() ->
{app3, "0.3"}]},
{"0.3", []}]}]),
- X = rcl_depsolver:solve(Dom0, [{app1, "0.1"},
+ X = rlx_depsolver:solve(Dom0, [{app1, "0.1"},
{app2, "0.3"}]),
?assertMatch({ok, [{app3,{{0,3},{[],[]}}},
@@ -86,7 +86,7 @@ third_test() ->
Pkg3Deps = [{app5, "2.0.0", '>='}],
Pkg4Deps = [app5],
- Dom0 = rcl_depsolver:add_packages(rcl_depsolver:new_graph(), [{app1, [{"0.1.0", Pkg1Deps},
+ Dom0 = rlx_depsolver:add_packages(rlx_depsolver:new_graph(), [{app1, [{"0.1.0", Pkg1Deps},
{"0.2", Pkg1Deps},
{"3.0", Pkg1Deps}]},
{app2, [{"0.0.1", Pkg2Deps},
@@ -112,7 +112,7 @@ third_test() ->
{app4,{{6,0,0},{[],[]}}},
{app2,{{3,0},{[],[]}}},
{app1,{{3,0},{[],[]}}}]},
- rcl_depsolver:solve(Dom0, [{app1, "3.0"}])),
+ rlx_depsolver:solve(Dom0, [{app1, "3.0"}])),
?assertMatch({ok, [{app5,{{6,0,0},{[],[]}}},
@@ -120,10 +120,10 @@ third_test() ->
{app4,{{6,0,0},{[],[]}}},
{app2,{{3,0},{[],[]}}},
{app1,{{3,0},{[],[]}}}]},
- rcl_depsolver:solve(Dom0, [app1])).
+ rlx_depsolver:solve(Dom0, [app1])).
fail_test() ->
- Dom0 = rcl_depsolver:add_packages(rcl_depsolver:new_graph(),
+ Dom0 = rlx_depsolver:add_packages(rlx_depsolver:new_graph(),
[{app1, [{"0.1", [{app2, "0.2"},
{app3, "0.2", gte}]},
{"0.2", []},
@@ -135,9 +135,9 @@ fail_test() ->
{"0.2", []},
{"0.3", []}]}]),
- Ret = rcl_depsolver:solve(Dom0, [{app1, "0.1"}]),
+ Ret = rlx_depsolver:solve(Dom0, [{app1, "0.1"}]),
%% We do this to make sure all errors can be formated.
- _ = rcl_depsolver:format_error(Ret),
+ _ = rlx_depsolver:format_error(Ret),
?assertMatch({error,
[{[{[{app1,{{0,1},{[],[]}}}],
[{app1,{{0,1},{[],[]}}},[[{app2,{{0,2},{[],[]}}}]]]}],
@@ -154,7 +154,7 @@ conflicting_passing_test() ->
Pkg2Deps = [{app4, "3.0.0", gte}],
Pkg3Deps = [{app5, "2.0.0", '>='}],
- Dom0 = rcl_depsolver:add_packages(rcl_depsolver:new_graph(), [{app1, [{"0.1.0", Pkg1Deps},
+ Dom0 = rlx_depsolver:add_packages(rlx_depsolver:new_graph(), [{app1, [{"0.1.0", Pkg1Deps},
{"0.1.0", Pkg1Deps},
{"0.2", Pkg1Deps},
{"3.0", Pkg1Deps}]},
@@ -181,23 +181,23 @@ conflicting_passing_test() ->
{app4,{{5,0,0},{[],[]}}},
{app2,{{3,0},{[],[]}}},
{app1,{{3,0},{[],[]}}}]},
- rcl_depsolver:solve(Dom0, [{app1, "3.0"}])),
+ rlx_depsolver:solve(Dom0, [{app1, "3.0"}])),
?assertMatch({ok, [{app5,{{2,0,0},{[],[]}}},
{app3,{{0,1,3},{[],[]}}},
{app4,{{5,0,0},{[],[]}}},
{app2,{{3,0},{[],[]}}},
{app1,{{3,0},{[],[]}}}]},
- rcl_depsolver:solve(Dom0, [app1, app2, app5])).
+ rlx_depsolver:solve(Dom0, [app1, app2, app5])).
circular_dependencies_test() ->
- Dom0 = rcl_depsolver:add_packages(rcl_depsolver:new_graph(), [{app1, [{"0.1.0", [app2]}]},
+ Dom0 = rlx_depsolver:add_packages(rlx_depsolver:new_graph(), [{app1, [{"0.1.0", [app2]}]},
{app2, [{"0.0.1", [app1]}]}]),
?assertMatch({ok, [{app1,{{0,1,0},{[],[]}}},{app2,{{0,0,1},{[],[]}}}]},
- rcl_depsolver:solve(Dom0, [{app1, "0.1.0"}])).
+ rlx_depsolver:solve(Dom0, [{app1, "0.1.0"}])).
conflicting_failing_test() ->
Pkg1Deps = [app2,
@@ -208,14 +208,14 @@ conflicting_failing_test() ->
Pkg3Deps = [{app5, "6.0.0"}],
- Dom0 = rcl_depsolver:add_packages(rcl_depsolver:new_graph(), [{app1, [{"3.0", Pkg1Deps}]},
+ Dom0 = rlx_depsolver:add_packages(rlx_depsolver:new_graph(), [{app1, [{"3.0", Pkg1Deps}]},
{app2, [{"0.0.1", Pkg2Deps}]},
{app3, [{"0.1.0", Pkg3Deps}]},
{app4, [{"5.0.0", [{app5, "2.0.0"}]}]},
{app5, [{"2.0.0", []},
{"6.0.0", []}]}]),
- Ret = rcl_depsolver:solve(Dom0, [app1, app3]),
- _ = rcl_depsolver:format_error(Ret),
+ Ret = rlx_depsolver:solve(Dom0, [app1, app3]),
+ _ = rlx_depsolver:format_error(Ret),
?assertMatch({error,
[{[{[app1],
[{app1,{{3,0},{[],[]}}},
@@ -237,7 +237,7 @@ pessimistic_major_minor_patch_test() ->
Pkg3Deps = [{app5, "2.0.0", '>='}],
Pkg4Deps = [app5],
- Dom0 = rcl_depsolver:add_packages(rcl_depsolver:new_graph(), [{app1, [{"0.1.0", Pkg1Deps},
+ Dom0 = rlx_depsolver:add_packages(rlx_depsolver:new_graph(), [{app1, [{"0.1.0", Pkg1Deps},
{"0.2", Pkg1Deps},
{"3.0", Pkg1Deps}]},
{app2, [{"0.0.1", Pkg2Deps},
@@ -264,7 +264,7 @@ pessimistic_major_minor_patch_test() ->
{app4,{{6,0,0},{[],[]}}},
{app2,{{2,1,5},{[],[]}}},
{app1,{{3,0},{[],[]}}}]},
- rcl_depsolver:solve(Dom0, [{app1, "3.0"}])).
+ rlx_depsolver:solve(Dom0, [{app1, "3.0"}])).
pessimistic_major_minor_test() ->
@@ -275,7 +275,7 @@ pessimistic_major_minor_test() ->
Pkg3Deps = [{app5, "2.0.0", '>='}],
Pkg4Deps = [app5],
- Dom0 = rcl_depsolver:add_packages(rcl_depsolver:new_graph(), [{app1, [{"0.1.0", Pkg1Deps},
+ Dom0 = rlx_depsolver:add_packages(rlx_depsolver:new_graph(), [{app1, [{"0.1.0", Pkg1Deps},
{"0.2", Pkg1Deps},
{"3.0", Pkg1Deps}]},
{app2, [{"0.0.1", Pkg2Deps},
@@ -302,7 +302,7 @@ pessimistic_major_minor_test() ->
{app4,{{6,0,0},{[],[]}}},
{app2,{{2,2},{[],[]}}},
{app1,{{3,0},{[],[]}}}]},
- rcl_depsolver:solve(Dom0, [{app1, "3.0"}])).
+ rlx_depsolver:solve(Dom0, [{app1, "3.0"}])).
filter_versions_test() ->
@@ -347,18 +347,18 @@ filter_versions_test() ->
{app4,"6.0.0"},
{app5,"2.0.0"},
{app5,"6.0.0"}]},
- rcl_depsolver:filter_packages(Packages, Cons)),
+ rlx_depsolver:filter_packages(Packages, Cons)),
- Ret = rcl_depsolver:filter_packages(Packages,
+ Ret = rlx_depsolver:filter_packages(Packages,
[{"foo", "1.0.0", '~~~~'} | Cons]),
- _ = rcl_depsolver:format_error(Ret),
+ _ = rlx_depsolver:format_error(Ret),
?assertMatch({error, {invalid_constraints, [{<<"foo">>,{{1,0,0},{[],[]}},'~~~~'}]}}, Ret).
-spec missing_test() -> ok.
missing_test() ->
- Dom0 = rcl_depsolver:add_packages(rcl_depsolver:new_graph(), [{app1, [{"0.1", [{app2, "0.2"},
+ Dom0 = rlx_depsolver:add_packages(rlx_depsolver:new_graph(), [{app1, [{"0.1", [{app2, "0.2"},
{app3, "0.2", '>='},
{app4, "0.2", '='}]},
{"0.2", [{app4, "0.2"}]},
@@ -369,12 +369,12 @@ missing_test() ->
{app3, [{"0.1", []},
{"0.2", []},
{"0.3", []}]}]),
- Ret1 = rcl_depsolver:solve(Dom0, [{app4, "0.1"}, {app3, "0.1"}]),
- _ = rcl_depsolver:format_error(Ret1),
+ Ret1 = rlx_depsolver:solve(Dom0, [{app4, "0.1"}, {app3, "0.1"}]),
+ _ = rlx_depsolver:format_error(Ret1),
?assertMatch({error,{unreachable_package,app4}}, Ret1),
- Ret2 = rcl_depsolver:solve(Dom0, [{app1, "0.1"}]),
- _ = rcl_depsolver:format_error(Ret2),
+ Ret2 = rlx_depsolver:solve(Dom0, [{app1, "0.1"}]),
+ _ = rlx_depsolver:format_error(Ret2),
?assertMatch({error,{unreachable_package,app4}},
Ret2).
@@ -383,11 +383,11 @@ binary_test() ->
World = [{<<"foo">>, [{<<"1.2.3">>, [{<<"bar">>, <<"2.0.0">>, gt}]}]},
{<<"bar">>, [{<<"2.0.0">>, [{<<"foo">>, <<"3.0.0">>, gt}]}]}],
- Ret = rcl_depsolver:solve(rcl_depsolver:add_packages(rcl_depsolver:new_graph(),
+ Ret = rlx_depsolver:solve(rlx_depsolver:add_packages(rlx_depsolver:new_graph(),
World),
[<<"foo">>]),
- _ = rcl_depsolver:format_error(Ret),
+ _ = rlx_depsolver:format_error(Ret),
?assertMatch({error,
[{[{[<<"foo">>],[{<<"foo">>,{{1,2,3},{[],[]}}}]}],
[{{<<"foo">>,{{1,2,3},{[],[]}}},
@@ -406,9 +406,9 @@ binary_test() ->
%%
doesnt_exist_test() ->
Constraints = [{<<"foo">>,[{<<"1.2.3">>, [{<<"bar">>, <<"2.0.0">>, gt}]}]}],
- World = rcl_depsolver:add_packages(rcl_depsolver:new_graph(), Constraints),
- Ret = rcl_depsolver:solve(World, [<<"foo">>]),
- _ = rcl_depsolver:format_error(Ret),
+ World = rlx_depsolver:add_packages(rlx_depsolver:new_graph(), Constraints),
+ Ret = rlx_depsolver:solve(World, [<<"foo">>]),
+ _ = rlx_depsolver:format_error(Ret),
?assertMatch({error,{unreachable_package,<<"bar">>}}, Ret).
%%
@@ -426,9 +426,9 @@ not_new_enough_test() ->
Constraints = [{<<"foo">>, [{<<"1.2.3">>, [{<<"bar">>, <<"2.0.0">>, gt}]}]},
{<<"bar">>, [{<<"2.0.0">>, []}]}],
- World = rcl_depsolver:add_packages(rcl_depsolver:new_graph(), Constraints),
- Ret = rcl_depsolver:solve(World, [<<"foo">>]),
- _ = rcl_depsolver:format_error(Ret),
+ World = rlx_depsolver:add_packages(rlx_depsolver:new_graph(), Constraints),
+ Ret = rlx_depsolver:solve(World, [<<"foo">>]),
+ _ = rlx_depsolver:format_error(Ret),
?assertMatch({error,
[{[{[<<"foo">>],[{<<"foo">>,{{1,2,3},{[],[]}}}]}],
[{{<<"foo">>,{{1,2,3},{[],[]}}},
@@ -445,11 +445,11 @@ not_new_enough_test() ->
%% "most_constrained_cookbooks:["bar = 2.0.0 -> [(foo > 3.0.0)]"]
%%
impossible_dependency_test() ->
- World = rcl_depsolver:add_packages(rcl_depsolver:new_graph(),
+ World = rlx_depsolver:add_packages(rlx_depsolver:new_graph(),
[{<<"foo">>, [{<<"1.2.3">>,[{ <<"bar">>, <<"2.0.0">>, gt}]}]},
{<<"bar">>, [{<<"2.0.0">>, [{ <<"foo">>, <<"3.0.0">>, gt}]}]}]),
- Ret = rcl_depsolver:solve(World, [<<"foo">>]),
- _ = rcl_depsolver:format_error(Ret),
+ Ret = rlx_depsolver:solve(World, [<<"foo">>]),
+ _ = rlx_depsolver:format_error(Ret),
?assertMatch({error,
[{[{[<<"foo">>],[{<<"foo">>,{{1,2,3},{[],[]}}}]}],
[{{<<"foo">>,{{1,2,3},{[],[]}}},
@@ -460,30 +460,30 @@ impossible_dependency_test() ->
%%
format_test_() ->
[{"format constraint",
- [equal_bin_string(<<"foo">>, rcl_depsolver:format_constraint(<<"foo">>)),
- equal_bin_string(<<"foo">>, rcl_depsolver:format_constraint(foo)),
- equal_bin_string(<<"(foo = 1.2.0)">>, rcl_depsolver:format_constraint({<<"foo">>, {{1,2,0}, {[], []}}})),
- equal_bin_string(<<"(foo = 1.2.0)">>, rcl_depsolver:format_constraint({<<"foo">>, {{1,2,0}, {[], []}}, '='})),
+ [equal_bin_string(<<"foo">>, rlx_depsolver:format_constraint(<<"foo">>)),
+ equal_bin_string(<<"foo">>, rlx_depsolver:format_constraint(foo)),
+ equal_bin_string(<<"(foo = 1.2.0)">>, rlx_depsolver:format_constraint({<<"foo">>, {{1,2,0}, {[], []}}})),
+ equal_bin_string(<<"(foo = 1.2.0)">>, rlx_depsolver:format_constraint({<<"foo">>, {{1,2,0}, {[], []}}, '='})),
equal_bin_string(<<"(foo > 1.2.0)">>,
- rcl_depsolver:format_constraint({<<"foo">>, {{1,2,0}, {[], []}}, '>'})),
+ rlx_depsolver:format_constraint({<<"foo">>, {{1,2,0}, {[], []}}, '>'})),
equal_bin_string(<<"(foo > 1.2.0)">>,
- rcl_depsolver:format_constraint({<<"foo">>, {{1,2,0}, {[], []}}, gt})),
+ rlx_depsolver:format_constraint({<<"foo">>, {{1,2,0}, {[], []}}, gt})),
equal_bin_string(<<"(foo between 1.2.0 and 1.3.0)">>,
- rcl_depsolver:format_constraint({<<"foo">>,{{1,2,0}, {[], []}},
+ rlx_depsolver:format_constraint({<<"foo">>,{{1,2,0}, {[], []}},
{{1,3,0}, {[], []}}, between})),
equal_bin_string(<<"(foo > 1.2.0-alpha.1+build.36)">>,
- rcl_depsolver:format_constraint({<<"foo">>,
+ rlx_depsolver:format_constraint({<<"foo">>,
{{1,2,0}, {["alpha", 1], ["build", 36]}}, gt}))
]
},
{"format roots",
[equal_bin_string(<<"(bar = 1.2.0)">>,
- rcl_depsolver:format_roots([ [{<<"bar">>, {{1,2,0},{[],[]}}}] ])),
+ rlx_depsolver:format_roots([ [{<<"bar">>, {{1,2,0},{[],[]}}}] ])),
equal_bin_string(<<"(bar = 1.2.0), foo">>,
- rcl_depsolver:format_roots([[<<"foo">>,
+ rlx_depsolver:format_roots([[<<"foo">>,
{<<"bar">>, {{1,2,0},{[],[]}}}]])),
equal_bin_string(<<"(bar = 1.2.0), foo">>,
- rcl_depsolver:format_roots([[<<"foo">>], [{<<"bar">>, {{1,2,0},{[],[]}}}]]))
+ rlx_depsolver:format_roots([[<<"foo">>], [{<<"bar">>, {{1,2,0},{[],[]}}}]]))
]
}
].
diff --git a/test/rclt_discover_SUITE.erl b/test/rlx_discover_SUITE.erl
index e3a2861..d225ee6 100644
--- a/test/rclt_discover_SUITE.erl
+++ b/test/rlx_discover_SUITE.erl
@@ -17,7 +17,7 @@
%%%-------------------------------------------------------------------
%%% @author Eric Merrit <[email protected]>
%%% @copyright (C) 2012, Eric Merrit
--module(rclt_discover_SUITE).
+-module(rlx_discover_SUITE).
-export([suite/0,
init_per_suite/1,
@@ -44,9 +44,9 @@ init_per_testcase(_, Config) ->
DataDir = proplists:get_value(data_dir, Config),
LibDir1 = filename:join([DataDir, create_random_name("lib_dir1_")]),
LibDir2 = filename:join([DataDir, create_random_name("lib_dir2_")]),
- ok = rcl_util:mkdir_p(LibDir1),
- ok = rcl_util:mkdir_p(LibDir2),
- State = rcl_state:new([{lib_dirs, [LibDir1, LibDir2]}], release),
+ ok = rlx_util:mkdir_p(LibDir1),
+ ok = rlx_util:mkdir_p(LibDir2),
+ State = rlx_state:new([{lib_dirs, [LibDir1, LibDir2]}], release),
[{lib1, LibDir1},
{lib2, LibDir2},
{state, State} | Config].
@@ -72,20 +72,20 @@ normal_case(Config) ->
|| App <-
[{create_random_name("lib_app2_"), create_random_vsn()}
|| _ <- lists:seq(1, 100)]],
- State0 = rcl_state:put(proplists:get_value(state, Config),
+ State0 = rlx_state:put(proplists:get_value(state, Config),
disable_default_libs, true),
- {DiscoverProvider, {ok, State1}} = rcl_provider:new(rcl_prv_discover, State0),
- {ok, State2} = rcl_provider:do(DiscoverProvider, State1),
+ {DiscoverProvider, {ok, State1}} = rlx_provider:new(rlx_prv_discover, State0),
+ {ok, State2} = rlx_provider:do(DiscoverProvider, State1),
lists:foreach(fun(App) ->
- ?assertMatch(true, lists:member(App, rcl_state:available_apps(State2)))
+ ?assertMatch(true, lists:member(App, rlx_state:available_apps(State2)))
end, Apps1),
lists:foreach(fun(App) ->
- ?assertMatch(true, lists:member(App, rcl_state:available_apps(State2)))
+ ?assertMatch(true, lists:member(App, rlx_state:available_apps(State2)))
end, Apps2),
Length = erlang:length(Apps2) +
erlang:length(Apps2),
- ?assertMatch(Length, erlang:length(rcl_state:available_apps(State2))).
+ ?assertMatch(Length, erlang:length(rlx_state:available_apps(State2))).
no_beam_case(Config) ->
%% We silently ignore apps with no beams
@@ -110,10 +110,10 @@ no_beam_case(Config) ->
AppDir = filename:join([LibDir2, BadName]),
write_app_file(AppDir, BadName, BadVsn),
State0 = proplists:get_value(state, Config),
- {DiscoverProvider, {ok, State1}} = rcl_provider:new(rcl_prv_discover, State0),
+ {DiscoverProvider, {ok, State1}} = rlx_provider:new(rlx_prv_discover, State0),
EbinDir = filename:join([LibDir2, BadName, <<"ebin">>]),
?assertMatch({error, {_, [{no_beam_files, EbinDir}]}},
- rcl_provider:do(DiscoverProvider, State1)).
+ rlx_provider:do(DiscoverProvider, State1)).
bad_ebin_case(Config) ->
LibDir1 = proplists:get_value(lib1, Config),
@@ -140,9 +140,9 @@ bad_ebin_case(Config) ->
ok = ec_file:write_term(Filename, get_bad_app_metadata(BadName, BadVsn)),
write_beam_file(AppDir, BadName),
State0 = proplists:get_value(state, Config),
- {DiscoverProvider, {ok, State1}} = rcl_provider:new(rcl_prv_discover, State0),
+ {DiscoverProvider, {ok, State1}} = rlx_provider:new(rlx_prv_discover, State0),
?assertMatch({error, {_, [{invalid_app_file, Filename}]}},
- rcl_provider:do(DiscoverProvider, State1)).
+ rlx_provider:do(DiscoverProvider, State1)).
%%%===================================================================
@@ -152,7 +152,7 @@ create_app(Dir, Name, Vsn) ->
AppDir = filename:join([Dir, Name]),
write_app_file(AppDir, Name, Vsn),
write_beam_file(AppDir, Name),
- {ok, App} = rcl_app_info:new(erlang:list_to_atom(Name), Vsn,
+ {ok, App} = rlx_app_info:new(erlang:list_to_atom(Name), Vsn,
erlang:iolist_to_binary(AppDir),
[kernel, stdlib], []),
App.
diff --git a/test/rclt_goal.erl b/test/rlx_goal_tests.erl
index 20fb5e5..9a99bcb 100644
--- a/test/rclt_goal.erl
+++ b/test/rlx_goal_tests.erl
@@ -18,46 +18,46 @@
%%% @author Eric Merritt <[email protected]>
%%% @copyright (C) 2012 Erlware, LLC.
%%% @doc test for target spec parsing
--module(rclt_goal).
+-module(rlx_goal_tests).
-include_lib("eunit/include/eunit.hrl").
parse_test() ->
?assertMatch({ok, getopt},
- rcl_goal:parse("getopt")),
+ rlx_goal:parse("getopt")),
?assertMatch({ok, {getopt, {{0,5,1},{[],[]}}, '='}},
- rcl_goal:parse("getopt=0.5.1")),
+ rlx_goal:parse("getopt=0.5.1")),
?assertMatch({ok, {getopt, {{0,5,1},{[],[]}}, '='}},
- rcl_goal:parse("getopt:0.5.1")),
+ rlx_goal:parse("getopt:0.5.1")),
?assertMatch({ok, {getopt, {{0,5,1},{[],[]}}, '='}},
- rcl_goal:parse("getopt-0.5.1")),
+ rlx_goal:parse("getopt-0.5.1")),
?assertMatch({ok, {getopt, {{0,5,1},{[],[]}}, gte}},
- rcl_goal:parse("getopt >= 0.5.1")),
+ rlx_goal:parse("getopt >= 0.5.1")),
?assertMatch({ok, {getopt, {{0,5,1},{[],[]}}, gte}},
- rcl_goal:parse("getopt:gte:0.5.1")),
+ rlx_goal:parse("getopt:gte:0.5.1")),
?assertMatch({ok, {getopt, {{0,5,1},{[],[]}}, gt}},
- rcl_goal:parse("getopt>0.5.1")),
+ rlx_goal:parse("getopt>0.5.1")),
?assertMatch({ok, {getopt, {{0,5,1},{[],[]}}, gt}},
- rcl_goal:parse("getopt:gt:0.5.1")),
+ rlx_goal:parse("getopt:gt:0.5.1")),
?assertMatch({ok, {getopt, {{0,5,1},{[],[]}}, lte}},
- rcl_goal:parse("getopt<= 0.5.1")),
+ rlx_goal:parse("getopt<= 0.5.1")),
?assertMatch({ok, {getopt, {{0,5,1},{[],[]}}, lte}},
- rcl_goal:parse("getopt:lte:0.5.1")),
+ rlx_goal:parse("getopt:lte:0.5.1")),
?assertMatch({ok, {getopt, {{0,5,1},{[],[]}}, lt}},
- rcl_goal:parse("getopt<0.5.1")),
+ rlx_goal:parse("getopt<0.5.1")),
?assertMatch({ok, {getopt, {{0,5,1},{[],[]}}, pes}},
- rcl_goal:parse("getopt ~>0.5.1")),
+ rlx_goal:parse("getopt ~>0.5.1")),
?assertMatch({ok, {getopt, {{0,5,1},{[],[]}}, pes}},
- rcl_goal:parse("getopt: pes:0.5.1")),
+ rlx_goal:parse("getopt: pes:0.5.1")),
?assertMatch({ok, {getopt, {{0,5,1},{[],[]}}, {{0,6,1},{[],[]}}, between}},
- rcl_goal:parse("getopt:btwn:0.5.1,0.6.1")),
+ rlx_goal:parse("getopt:btwn:0.5.1,0.6.1")),
?assertMatch({ok, {getopt, {{0,5,1},{[],[]}}, {{0,6,1},{[],[]}}, between}},
- rcl_goal:parse("getopt:between :0.5.1,0.6.1")).
+ rlx_goal:parse("getopt:between :0.5.1,0.6.1")).
fail_test() ->
?assertMatch({fail,_},
- rcl_goal:parse("got:")),
+ rlx_goal:parse("got:")),
?assertMatch({fail,_},
- rcl_goal:parse("between:btwn:0.5")),
+ rlx_goal:parse("between:btwn:0.5")),
?assertMatch({fail,_},
- rcl_goal:parse("between:btwn:0.5,")).
+ rlx_goal:parse("between:btwn:0.5,")).
diff --git a/test/rclt_release_SUITE.erl b/test/rlx_release_SUITE.erl
index f0446d6..ea4b20d 100644
--- a/test/rclt_release_SUITE.erl
+++ b/test/rlx_release_SUITE.erl
@@ -17,7 +17,7 @@
%%%-------------------------------------------------------------------
%%% @author Eric Merrit <[email protected]>
%%% @copyright (C) 2012, Eric Merrit
--module(rclt_release_SUITE).
+-module(rlx_release_SUITE).
-export([suite/0,
init_per_suite/1,
@@ -35,6 +35,7 @@
make_depfree_release/1,
make_invalid_config_release/1,
make_relup_release/1,
+ make_relup_release2/1,
make_one_app_top_level_release/1]).
-include_lib("common_test/include/ct.hrl").
@@ -54,8 +55,8 @@ end_per_suite(_Config) ->
init_per_testcase(_, Config) ->
DataDir = proplists:get_value(data_dir, Config),
LibDir1 = filename:join([DataDir, create_random_name("lib_dir1_")]),
- ok = rcl_util:mkdir_p(LibDir1),
- State = rcl_state:new([{lib_dirs, [LibDir1]}], release),
+ ok = rlx_util:mkdir_p(LibDir1),
+ State = rlx_state:new([{lib_dirs, [LibDir1]}], release),
[{lib1, LibDir1},
{state, State} | Config].
@@ -64,7 +65,7 @@ all() ->
make_skip_app_release,
make_implicit_config_release, make_rerun_overridden_release,
overlay_release, make_goalless_release, make_depfree_release,
- make_invalid_config_release, make_relup_release,
+ make_invalid_config_release, make_relup_release, make_relup_release2,
make_one_app_top_level_release].
make_release(Config) ->
@@ -83,17 +84,17 @@ make_release(Config) ->
create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]),
create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []),
- ConfigFile = filename:join([LibDir1, "relcool.config"]),
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
write_config(ConfigFile,
[{release, {foo, "0.0.1"},
[goal_app_1,
goal_app_2]}]),
OutputDir = filename:join([proplists:get_value(data_dir, Config),
- create_random_name("relcool-output")]),
- {ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2,
+ create_random_name("relx-output")]),
+ {ok, State} = relx:do(undefined, undefined, [], [LibDir1], 2,
OutputDir, ConfigFile),
- [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)),
- AppSpecs = rcl_release:applications(Release),
+ [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
+ AppSpecs = rlx_release:applications(Release),
?assert(lists:keymember(stdlib, 1, AppSpecs)),
?assert(lists:keymember(kernel, 1, AppSpecs)),
?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)),
@@ -118,15 +119,15 @@ make_invalid_config_release(Config) ->
create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]),
create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []),
- ConfigFile = filename:join([LibDir1, "relcool.config"]),
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
ok = ec_file:write(ConfigFile,
"{release, {foo, \"0.0.1\"},
[goal_app_1,
goal_app_2,]}"),
OutputDir = filename:join([proplists:get_value(data_dir, Config),
- create_random_name("relcool-output")]),
- {error, {rcl_prv_config,
- {consult, _, _}}} = relcool:do(undefined, undefined, [], [LibDir1], 2,
+ create_random_name("relx-output")]),
+ {error, {rlx_prv_config,
+ {consult, _, _}}} = relx:do(undefined, undefined, [], [LibDir1], 2,
OutputDir, ConfigFile).
make_scriptless_release(Config) ->
@@ -145,22 +146,22 @@ make_scriptless_release(Config) ->
create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]),
create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []),
- ConfigFile = filename:join([LibDir1, "relcool.config"]),
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
write_config(ConfigFile,
[{generate_start_script, false},
{release, {foo, "0.0.1"},
[goal_app_1,
goal_app_2]}]),
OutputDir = filename:join([proplists:get_value(data_dir, Config),
- create_random_name("relcool-output")]),
- {ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2,
+ create_random_name("relx-output")]),
+ {ok, State} = relx:do(undefined, undefined, [], [LibDir1], 2,
OutputDir, ConfigFile),
?assert(not ec_file:exists(filename:join([OutputDir, "bin", "foo"]))),
?assert(not ec_file:exists(filename:join([OutputDir, "bin", "foo-0.0.1"]))),
- [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)),
- AppSpecs = rcl_release:applications(Release),
+ [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
+ AppSpecs = rlx_release:applications(Release),
?assert(lists:keymember(stdlib, 1, AppSpecs)),
?assert(lists:keymember(kernel, 1, AppSpecs)),
?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)),
@@ -194,20 +195,20 @@ make_overridden_release(Config) ->
create_app(OverrideDir1, OverrideApp, OverrideVsn, [stdlib,kernel], []),
- ConfigFile = filename:join([LibDir1, "relcool.config"]),
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
write_config(ConfigFile,
[{release, {foo, "0.0.1"},
[goal_app_1,
erlang:list_to_atom(OverrideApp),
goal_app_2]}]),
OutputDir = filename:join([proplists:get_value(data_dir, Config),
- create_random_name("relcool-output")]),
+ create_random_name("relx-output")]),
{ok, Cwd} = file:get_cwd(),
- {ok, State} = relcool:do(Cwd, undefined, undefined, [], [LibDir1], 2,
+ {ok, State} = relx:do(Cwd, undefined, undefined, [], [LibDir1], 2,
OutputDir, [{OverrideAppName, OverrideAppDir}],
ConfigFile),
- [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)),
- AppSpecs = rcl_release:applications(Release),
+ [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
+ AppSpecs = rlx_release:applications(Release),
?assert(lists:keymember(stdlib, 1, AppSpecs)),
?assert(lists:keymember(kernel, 1, AppSpecs)),
?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)),
@@ -243,20 +244,20 @@ make_skip_app_release(Config) ->
create_empty_app(SkipAppDir1, SkipAppApp, SkipAppVsn, [stdlib,kernel], []),
- ConfigFile = filename:join([LibDir1, "relcool.config"]),
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
write_config(ConfigFile,
[{release, {foo, "0.0.1"},
[goal_app_1,
goal_app_2]},
{skip_apps, [erlang:list_to_atom(SkipAppApp)]}]),
OutputDir = filename:join([proplists:get_value(data_dir, Config),
- create_random_name("relcool-output")]),
+ create_random_name("relx-output")]),
{ok, Cwd} = file:get_cwd(),
- {ok, State} = relcool:do(Cwd, undefined, undefined, [], [LibDir1], 2,
+ {ok, State} = relx:do(Cwd, undefined, undefined, [], [LibDir1], 2,
OutputDir, [],
ConfigFile),
- [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)),
- AppSpecs = rcl_release:applications(Release),
+ [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
+ AppSpecs = rlx_release:applications(Release),
?assert(lists:keymember(stdlib, 1, AppSpecs)),
?assert(lists:keymember(kernel, 1, AppSpecs)),
?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)),
@@ -284,20 +285,20 @@ make_implicit_config_release(Config) ->
create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]),
create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []),
- ConfigFile = filename:join([LibDir1, "relcool.config"]),
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
write_config(ConfigFile,
[{release, {foo, "0.0.1"},
[goal_app_1,
goal_app_2]}]),
OutputDir = filename:join([proplists:get_value(data_dir, Config),
- create_random_name("relcool-output")]),
+ create_random_name("relx-output")]),
ok = file:set_cwd(FooRoot),
{ok, FooRoot} = file:get_cwd(),
- {ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2,
+ {ok, State} = relx:do(undefined, undefined, [], [LibDir1], 2,
OutputDir, undefined),
- [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)),
+ [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
?assert(ec_file:exists(OutputDir)),
- AppSpecs = rcl_release:applications(Release),
+ AppSpecs = rlx_release:applications(Release),
?assert(lists:keymember(stdlib, 1, AppSpecs)),
?assert(lists:keymember(kernel, 1, AppSpecs)),
?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)),
@@ -331,26 +332,26 @@ make_rerun_overridden_release(Config) ->
create_app(OverrideDir1, OverrideApp, OverrideVsn, [stdlib,kernel], []),
- ConfigFile = filename:join([LibDir1, "relcool.config"]),
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
write_config(ConfigFile,
[{release, {foo, "0.0.1"},
[goal_app_1,
erlang:list_to_atom(OverrideApp),
goal_app_2]}]),
OutputDir = filename:join([proplists:get_value(data_dir, Config),
- create_random_name("relcool-output")]),
+ create_random_name("relx-output")]),
{ok, Cwd} = file:get_cwd(),
- {ok, _} = relcool:do(Cwd, undefined, undefined, [], [LibDir1], 2,
+ {ok, _} = relx:do(Cwd, undefined, undefined, [], [LibDir1], 2,
OutputDir, [{OverrideAppName, OverrideAppDir}],
ConfigFile),
%% Now we run it again to see if it fails.
- {ok, State} = relcool:do(Cwd,undefined, undefined, [], [LibDir1], 2,
+ {ok, State} = relx:do(Cwd,undefined, undefined, [], [LibDir1], 2,
OutputDir, [{OverrideAppName, OverrideAppDir}],
ConfigFile),
- [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)),
- AppSpecs = rcl_release:applications(Release),
+ [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
+ AppSpecs = rlx_release:applications(Release),
?assert(lists:keymember(stdlib, 1, AppSpecs)),
?assert(lists:keymember(kernel, 1, AppSpecs)),
?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)),
@@ -379,7 +380,7 @@ overlay_release(Config) ->
create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]),
create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []),
- ConfigFile = filename:join([LibDir1, "relcool.config"]),
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
OverlayVars = filename:join([LibDir1, "vars.config"]),
Template = filename:join([LibDir1, "test_template"]),
write_config(ConfigFile,
@@ -407,13 +408,13 @@ overlay_release(Config) ->
ok = file:write_file_info(TemplateFile, FileInfo#file_info{mode=8#00777}),
OutputDir = filename:join([proplists:get_value(data_dir, Config),
- create_random_name("relcool-output")]),
+ create_random_name("relx-output")]),
- {ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2,
+ {ok, State} = relx:do(undefined, undefined, [], [LibDir1], 2,
OutputDir, ConfigFile),
- [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)),
- AppSpecs = rcl_release:applications(Release),
+ [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
+ AppSpecs = rlx_release:applications(Release),
?assert(lists:keymember(stdlib, 1, AppSpecs)),
?assert(lists:keymember(kernel, 1, AppSpecs)),
?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)),
@@ -513,14 +514,14 @@ make_goalless_release(Config) ->
create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]),
create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []),
- ConfigFile = filename:join([LibDir1, "relcool.config"]),
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
write_config(ConfigFile,
[{release, {foo, "0.0.1"},
[]}]),
OutputDir = filename:join([proplists:get_value(data_dir, Config),
- create_random_name("relcool-output")]),
- ?assertMatch({error,{rcl_prv_release,no_goals_specified}},
- relcool:do(undefined, undefined, [], [LibDir1], 2,
+ create_random_name("relx-output")]),
+ ?assertMatch({error,{rlx_prv_release,no_goals_specified}},
+ relx:do(undefined, undefined, [], [LibDir1], 2,
OutputDir, ConfigFile)).
make_depfree_release(Config) ->
@@ -539,16 +540,16 @@ make_depfree_release(Config) ->
create_app(LibDir1, "non_goal_1", "0.0.1", [kernel,stdlib], []),
create_app(LibDir1, "non_goal_2", "0.0.1", [kernel,stdlib], []),
- ConfigFile = filename:join([LibDir1, "relcool.config"]),
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
write_config(ConfigFile,
[{release, {foo, "0.0.1"},
[goal_app_1]}]),
OutputDir = filename:join([proplists:get_value(data_dir, Config),
- create_random_name("relcool-output")]),
- {ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2,
+ create_random_name("relx-output")]),
+ {ok, State} = relx:do(undefined, undefined, [], [LibDir1], 2,
OutputDir, ConfigFile),
- [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)),
- AppSpecs = rcl_release:applications(Release),
+ [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
+ AppSpecs = rlx_release:applications(Release),
?assert(lists:keymember(stdlib, 1, AppSpecs)),
?assert(lists:keymember(kernel, 1, AppSpecs)).
@@ -564,48 +565,150 @@ make_relup_release(Config) ->
create_app(LibDir1, "goal_app_1", "0.0.1", [stdlib,kernel,non_goal_1], []),
create_app(LibDir1, "goal_app_1", "0.0.2", [stdlib,kernel,non_goal_1], []),
- create_app(LibDir1, "goal_app_1", "0.0.3", [stdlib,kernel,non_goal_1], []),
+ {ok, GA1} = create_app(LibDir1, "goal_app_1", "0.0.3", [stdlib,kernel,non_goal_1], []),
create_app(LibDir1, "lib_dep_1", "0.0.1", [stdlib,kernel], []),
create_app(LibDir1, "goal_app_2", "0.0.1", [stdlib,kernel,goal_app_1,non_goal_2], []),
create_app(LibDir1, "goal_app_2", "0.0.2", [stdlib,kernel,goal_app_1,non_goal_2], []),
- create_app(LibDir1, "goal_app_2", "0.0.3", [stdlib,kernel,goal_app_1,non_goal_2], []),
+ {ok, GA2} = create_app(LibDir1, "goal_app_2", "0.0.3", [stdlib,kernel,goal_app_1,non_goal_2], []),
create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]),
create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []),
- ConfigFile = filename:join([LibDir1, "relcool.config"]),
+ write_appup_file(GA1, "0.0.2"),
+ write_appup_file(GA2, "0.0.2"),
+
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
write_config(ConfigFile,
[{release, {foo, "0.0.1"},
- [{goal_app_1, "0.0.1"},
+ [sasl,
+ {goal_app_1, "0.0.1"},
{goal_app_2, "0.0.1"}]},
{release, {foo, "0.0.2"},
- [{goal_app_1, "0.0.2"},
+ [sasl,
+ {goal_app_1, "0.0.2"},
{goal_app_2, "0.0.2"}]},
{release, {foo, "0.0.3"},
- [{goal_app_1, "0.0.3"},
+ [sasl,
+ {goal_app_1, "0.0.3"},
{goal_app_2, "0.0.3"}]}]),
OutputDir = filename:join([proplists:get_value(data_dir, Config),
- create_random_name("relcool-output")]),
- {ok, _} = relcool:do(foo, "0.0.1", [], [LibDir1], 2,
+ create_random_name("relx-output")]),
+ {ok, _} = relx:do(foo, "0.0.1", [], [LibDir1], 2,
OutputDir, ConfigFile),
- {ok, _} = relcool:do(foo, "0.0.2", [], [LibDir1], 2,
+ {ok, _} = relx:do(foo, "0.0.2", [], [LibDir1], 2,
OutputDir, ConfigFile),
- {ok, State} = relcool:do(foo, "0.0.3", [], [LibDir1], 2,
- OutputDir, ConfigFile),
+ {ok, State} = relx:do([{relname, foo},
+ {relvsn, "0.0.3"},
+ {goals, []},
+ {lib_dirs, [LibDir1]},
+ {log_level, 2},
+ {output_dir, OutputDir},
+ {config, ConfigFile}], ["relup"]),
+
+ %% we should have one 'resolved' release and three discovered realized_releases.
+ ?assertMatch([{foo, "0.0.1"},
+ {foo, "0.0.2"},
+ {foo, "0.0.3"}],
+ lists:sort(ec_dictionary:keys(rlx_state:realized_releases(State)))),
+ Release = ec_dictionary:get({foo, "0.0.3"}, rlx_state:realized_releases(State)),
+ ?assert(rlx_release:realized(Release)),
+ ?assert(not rlx_release:realized(ec_dictionary:get({foo, "0.0.2"},
+ rlx_state:realized_releases(State)))),
+ ?assert(not rlx_release:realized(ec_dictionary:get({foo, "0.0.1"},
+ rlx_state:realized_releases(State)))),
+
+ ?assertMatch({ok, [{"0.0.3",
+ [{"0.0.2",[],[point_of_no_return]}],
+ [{"0.0.2",[],[point_of_no_return]}]}]},
+ file:consult(filename:join(filename:dirname(rlx_release:relfile(Release)),
+ filename:basename(rlx_release:relfile(Release), ".rel") ++
+ ".relup"))),
+
+ ?assertMatch(foo, rlx_release:name(Release)),
+ ?assertMatch("0.0.3", rlx_release:vsn(Release)),
+ AppSpecs = rlx_release:applications(Release),
+ ?assert(lists:keymember(stdlib, 1, AppSpecs)),
+ ?assert(lists:keymember(kernel, 1, AppSpecs)),
+ ?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({non_goal_2, "0.0.1"}, AppSpecs)),
+ ?assert(lists:member({goal_app_1, "0.0.3"}, AppSpecs)),
+ ?assert(lists:member({goal_app_2, "0.0.3"}, AppSpecs)),
+ ?assert(lists:member({lib_dep_1, "0.0.1", load}, AppSpecs)).
+
+
+make_relup_release2(Config) ->
+ LibDir1 = proplists:get_value(lib1, Config),
+ [(fun({Name, Vsn}) ->
+ create_app(LibDir1, Name, Vsn, [kernel, stdlib], [])
+ end)(App)
+ ||
+ App <-
+ [{create_random_name("lib_app1_"), create_random_vsn()}
+ || _ <- lists:seq(1, 100)]],
- %% we should have one 'resolved' release and three discovered releases.
+ create_app(LibDir1, "goal_app_1", "0.0.1", [stdlib,kernel,non_goal_1], []),
+ create_app(LibDir1, "goal_app_1", "0.0.2", [stdlib,kernel,non_goal_1], []),
+ {ok, GA1} = create_app(LibDir1, "goal_app_1", "0.0.3", [stdlib,kernel,non_goal_1], []),
+ create_app(LibDir1, "lib_dep_1", "0.0.1", [stdlib,kernel], []),
+ create_app(LibDir1, "goal_app_2", "0.0.1", [stdlib,kernel,goal_app_1,non_goal_2], []),
+ create_app(LibDir1, "goal_app_2", "0.0.2", [stdlib,kernel,goal_app_1,non_goal_2], []),
+ {ok, GA2} = create_app(LibDir1, "goal_app_2", "0.0.3", [stdlib,kernel,goal_app_1,non_goal_2], []),
+ create_app(LibDir1, "non_goal_1", "0.0.1", [stdlib,kernel], [lib_dep_1]),
+ create_app(LibDir1, "non_goal_2", "0.0.1", [stdlib,kernel], []),
+
+ write_appup_file(GA1, "0.0.1"),
+ write_appup_file(GA2, "0.0.1"),
+
+ ConfigFile = filename:join([LibDir1, "relx.config"]),
+ write_config(ConfigFile,
+ [{release, {foo, "0.0.1"},
+ [sasl,
+ {goal_app_1, "0.0.1"},
+ {goal_app_2, "0.0.1"}]},
+ {release, {foo, "0.0.2"},
+ [sasl,
+ {goal_app_1, "0.0.2"},
+ {goal_app_2, "0.0.2"}]},
+ {release, {foo, "0.0.3"},
+ [sasl,
+ {goal_app_1, "0.0.3"},
+ {goal_app_2, "0.0.3"}]}]),
+ OutputDir = filename:join([proplists:get_value(data_dir, Config),
+ create_random_name("relx-output")]),
+ {ok, _} = relx:do(foo, "0.0.1", [], [LibDir1], 2,
+ OutputDir, ConfigFile),
+ {ok, _} = relx:do(foo, "0.0.2", [], [LibDir1], 2,
+ OutputDir, ConfigFile),
+ {ok, State} = relx:do([{relname, foo},
+ {relvsn, "0.0.3"},
+ {upfrom, "0.0.1"},
+ {goals, []},
+ {lib_dirs, [LibDir1]},
+ {log_level, 2},
+ {output_dir, OutputDir},
+ {config, ConfigFile}], ["relup"]),
+
+ %% we should have one 'resolved' release and three discovered realized_releases.
?assertMatch([{foo, "0.0.1"},
{foo, "0.0.2"},
{foo, "0.0.3"}],
- lists:sort(ec_dictionary:keys(rcl_state:releases(State)))),
- Release = ec_dictionary:get({foo, "0.0.3"}, rcl_state:releases(State)),
- ?assert(rcl_release:realized(Release)),
- ?assert(not rcl_release:realized(ec_dictionary:get({foo, "0.0.2"},
- rcl_state:releases(State)))),
- ?assert(not rcl_release:realized(ec_dictionary:get({foo, "0.0.1"},
- rcl_state:releases(State)))),
- ?assertMatch(foo, rcl_release:name(Release)),
- ?assertMatch("0.0.3", rcl_release:vsn(Release)),
- AppSpecs = rcl_release:applications(Release),
+ lists:sort(ec_dictionary:keys(rlx_state:realized_releases(State)))),
+ Release = ec_dictionary:get({foo, "0.0.3"}, rlx_state:realized_releases(State)),
+ ?assert(rlx_release:realized(Release)),
+ ?assert(not rlx_release:realized(ec_dictionary:get({foo, "0.0.2"},
+ rlx_state:realized_releases(State)))),
+ ?assert(not rlx_release:realized(ec_dictionary:get({foo, "0.0.1"},
+ rlx_state:realized_releases(State)))),
+
+ ?assertMatch({ok, [{"0.0.3",
+ [{"0.0.1",[],[point_of_no_return]}],
+ [{"0.0.1",[],[point_of_no_return]}]}]},
+ file:consult(filename:join(filename:dirname(rlx_release:relfile(Release)),
+ filename:basename(rlx_release:relfile(Release), ".rel") ++
+ ".relup"))),
+
+ ?assertMatch(foo, rlx_release:name(Release)),
+ ?assertMatch("0.0.3", rlx_release:vsn(Release)),
+ AppSpecs = rlx_release:applications(Release),
?assert(lists:keymember(stdlib, 1, AppSpecs)),
?assert(lists:keymember(kernel, 1, AppSpecs)),
?assert(lists:member({non_goal_1, "0.0.1"}, AppSpecs)),
@@ -618,22 +721,22 @@ make_relup_release(Config) ->
make_one_app_top_level_release(Config) ->
LibDir1 = proplists:get_value(lib1, Config),
{ok, AppInfo} = create_app(LibDir1, "goal_app_1", "0.0.1", [stdlib,kernel], []),
- AppDir = rcl_app_info:dir(AppInfo),
- ConfigFile = filename:join([AppDir, "relcool.config"]),
+ AppDir = rlx_app_info:dir(AppInfo),
+ ConfigFile = filename:join([AppDir, "relx.config"]),
write_config(ConfigFile,
[{release, {foo, "0.0.1"},
[{goal_app_1, "0.0.1"}]}]),
OutputDir = filename:join([AppDir,
- create_random_name("relcool-output")]),
+ create_random_name("relx-output")]),
{ok, Cwd} = file:get_cwd(),
ok = file:set_cwd(AppDir),
- {ok, State} = relcool:do(undefined, undefined, [], [], 2,
+ {ok, State} = relx:do(undefined, undefined, [], [], 2,
OutputDir, ConfigFile),
ok = file:set_cwd(Cwd),
- [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)),
- AppSpecs = rcl_release:applications(Release),
+ [{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rlx_state:realized_releases(State)),
+ AppSpecs = rlx_release:applications(Release),
?assert(lists:keymember(stdlib, 1, AppSpecs)),
?assert(lists:keymember(kernel, 1, AppSpecs)),
?assert(lists:member({goal_app_1, "0.0.1"}, AppSpecs)).
@@ -642,17 +745,18 @@ make_one_app_top_level_release(Config) ->
%%%===================================================================
%%% Helper Functions
%%%===================================================================
+
create_app(Dir, Name, Vsn, Deps, LibDeps) ->
AppDir = filename:join([Dir, Name ++ "-" ++ Vsn]),
write_app_file(AppDir, Name, Vsn, Deps, LibDeps),
write_beam_file(AppDir, Name),
- rcl_app_info:new(erlang:list_to_atom(Name), Vsn, AppDir,
+ rlx_app_info:new(erlang:list_to_atom(Name), Vsn, AppDir,
Deps, []).
create_empty_app(Dir, Name, Vsn, Deps, LibDeps) ->
AppDir = filename:join([Dir, Name ++ "-" ++ Vsn]),
write_app_file(AppDir, Name, Vsn, Deps, LibDeps),
- rcl_app_info:new(erlang:list_to_atom(Name), Vsn, AppDir,
+ rlx_app_info:new(erlang:list_to_atom(Name), Vsn, AppDir,
Deps, []).
write_beam_file(Dir, Name) ->
@@ -660,6 +764,14 @@ write_beam_file(Dir, Name) ->
ok = filelib:ensure_dir(Beam),
ok = ec_file:write_term(Beam, testing_purposes_only).
+write_appup_file(AppInfo, DownVsn) ->
+ Dir = rlx_app_info:dir(AppInfo),
+ Name = rlx_util:to_string(rlx_app_info:name(AppInfo)),
+ Vsn = rlx_app_info:vsn_as_string(AppInfo),
+ Filename = filename:join([Dir, "ebin", Name ++ ".appup"]),
+ ok = filelib:ensure_dir(Filename),
+ ok = ec_file:write_term(Filename, {Vsn, [{DownVsn, []}], [{DownVsn, []}]}).
+
write_app_file(Dir, Name, Version, Deps, LibDeps) ->
Filename = filename:join([Dir, "ebin", Name ++ ".app"]),
ok = filelib:ensure_dir(Filename),