aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README.md5
-rw-r--r--src/rcl_cmd_args.erl78
-rw-r--r--src/rcl_state.erl12
-rw-r--r--src/relcool.erl8
-rw-r--r--test/rclt_command_SUITE.erl2
-rw-r--r--test/rclt_discover_SUITE.erl2
-rw-r--r--test/rclt_release_SUITE.erl24
7 files changed, 77 insertions, 54 deletions
diff --git a/README.md b/README.md
index 99fef81..5407002 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ 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 -l ~/my-dirs --relname foo --relvsn 0.0.1 --target-spec myapp --target-spec getopt>=0.5.1 -o output-dir --targz
+ 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
The *release-specification-file* is optional but otherwise contains
additional specification information for releases.
@@ -43,6 +43,9 @@ additional specification information for releases.
-V *INTEGER*, \--verbose *INTEGER*
: The verbosity level of the system. Valid values are 1 - 3
+-c *INTEGER*, \--config *INTEGER*
+: The custom config file for the relcool system
+
# CONFIGURATION FILES
Configuration files
diff --git a/src/rcl_cmd_args.erl b/src/rcl_cmd_args.erl
index 99a3d7d..973abe3 100644
--- a/src/rcl_cmd_args.erl
+++ b/src/rcl_cmd_args.erl
@@ -38,18 +38,17 @@ args2state({ok, {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),
- case create_log(Opts,
- [{relname, RelName},
- {relvsn, RelVsn}]) of
- Error = {error, _} ->
- Error;
- {ok, CommandLineConfig} ->
- case validate_configs(Target) of
+ case convert_target(Target) of
+ {ok, AtomizedTarget} ->
+ case create_log(Opts, [{relname, RelName},
+ {relvsn, RelVsn}]) of
Error = {error, _} ->
Error;
- {ok, Configs} ->
- {ok, rcl_state:new(CommandLineConfig, Configs)}
- end
+ {ok, CommandLineConfig} ->
+ handle_config(Opts, AtomizedTarget, CommandLineConfig)
+ end;
+ Error ->
+ Error
end;
args2state({ok, {_Opts, Targets}}) ->
?RCL_ERROR({invalid_targets, Targets}).
@@ -84,32 +83,47 @@ format_error({not_directory, Dir}) ->
io_lib:format("Library directory does not exist: ~s", [Dir]);
format_error({invalid_log_level, LogLevel}) ->
io_lib:format("Invalid log level specified -V ~p, log level must be in the"
- " range 0..2", [LogLevel]).
+ " range 0..2", [LogLevel]);
+format_error({invalid_target, Target}) ->
+ io_lib:format("Invalid action specified: ~s", [Target]).
+
%%%===================================================================
%%% Internal Functions
%%%===================================================================
--spec validate_configs([file:filename()]) ->
- {ok, [file:filename()]} | relcool:error().
-validate_configs(Configs) ->
- Result =
- lists:foldl(fun(_Config, Err = {error, _}) ->
- Err;
- (Config, Acc) ->
- case filelib:is_regular(Config) of
- true ->
- [filename:absname(Config) | Acc];
- false ->
- ?RCL_ERROR({invalid_config_file, Config})
- end
- end, [], Configs),
- case Result of
- {error, _} ->
- Result;
- _ ->
- %% Order may be important so lets make sure they remain in the same
- %% order they came in as
- {ok, lists:reverse(Result)}
+-spec handle_config([getopt:option()], atom(), proplists:proplist()) ->
+ {ok, {rcl_state:t(), [string()]}} |
+ relcool: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)}
+ end.
+
+-spec convert_target([string()]) -> {ok, release | relup} | relcool:error().
+convert_target([]) ->
+ {ok, release};
+convert_target(["release"]) ->
+ {ok, release};
+convert_target(["relup"]) ->
+ {ok, relup};
+convert_target(Target) ->
+ ?RCL_ERROR({invalid_target, Target}).
+
+-spec validate_config(file:filename() | undefined) ->
+ {ok, file:filename() | undefined} | relcool:error().
+validate_config(undefined) ->
+ {ok, undefined};
+validate_config("") ->
+ {ok, undefined};
+validate_config(Config) ->
+ case filelib:is_regular(Config) of
+ true ->
+ filename:absname(Config);
+ false ->
+ ?RCL_ERROR({invalid_config_file, Config})
end.
-spec create_log([getopt:option()], rcl_state:cmd_args()) ->
diff --git a/src/rcl_state.erl b/src/rcl_state.erl
index a2e6c66..ecf3115 100644
--- a/src/rcl_state.erl
+++ b/src/rcl_state.erl
@@ -62,6 +62,7 @@
-record(state_t, {log :: rcl_log:t(),
root_dir :: file:name(),
caller :: caller(),
+ action :: atom(),
output_dir :: file:name(),
lib_dirs=[] :: [file:name()],
config_file=[] :: file:filename(),
@@ -92,14 +93,17 @@
%% API
%%============================================================================
%% @doc Create a new 'log level' for the system
--spec new(proplists:proplist(), [file:filename()] | file:filename()) -> t().
-new(PropList, Target) when erlang:is_list(PropList) ->
+-spec new(proplists:proplist(), atom()) -> t().
+new(PropList, Target)
+ when erlang:is_list(PropList),
+ erlang:is_atom(Target) ->
{ok, Root} = file:get_cwd(),
State0 =
#state_t{log = proplists:get_value(log, PropList, rcl_log:new(error)),
output_dir=proplists:get_value(output_dir, PropList, ""),
lib_dirs=proplists:get_value(lib_dirs, PropList, ""),
- config_file=Target,
+ config_file=proplists:get_value(config, PropList, ""),
+ action = Target,
goals=proplists:get_value(goals, PropList, []),
providers = [],
releases=ec_dictionary:new(ec_dict),
@@ -286,7 +290,7 @@ create_logic_providers(State0) ->
new_test() ->
LogState = rcl_log:new(error),
- RCLState = new([{log, LogState}], []),
+ RCLState = new([{log, LogState}], release),
?assertMatch(LogState, log(RCLState)).
-endif.
diff --git a/src/relcool.erl b/src/relcool.erl
index 42923c4..83886c5 100644
--- a/src/relcool.erl
+++ b/src/relcool.erl
@@ -48,7 +48,7 @@ main(Args) ->
{ok, State} ->
run_relcool_process(rcl_state:caller(State, command_line));
Error={error, _} ->
- report_error(rcl_state:caller(rcl_state:new([], []),
+ report_error(rcl_state:caller(rcl_state:new([], undefined),
command_line), Error)
end.
@@ -106,8 +106,9 @@ do(RootDir, RelName, RelVsn, Goals, LibDirs, LogLevel, OutputDir, Overrides, Con
{output_dir, OutputDir},
{lib_dirs, LibDirs},
{root_dir, RootDir},
- {log, rcl_log:new(LogLevel)}],
- Config),
+ {log, rcl_log:new(LogLevel)},
+ {config, Config}],
+ release),
run_relcool_process(rcl_state:caller(State, api)).
@@ -127,6 +128,7 @@ 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"},
+ {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().
diff --git a/test/rclt_command_SUITE.erl b/test/rclt_command_SUITE.erl
index 78f05fc..3d06dad 100644
--- a/test/rclt_command_SUITE.erl
+++ b/test/rclt_command_SUITE.erl
@@ -88,6 +88,6 @@ spec_parse_fail_case(_Config) ->
config_fail_case(_Config) ->
ConfigFile = "does-not-exist",
- CmdLine = [ConfigFile],
+ CmdLine = ["-c", ConfigFile],
?assertMatch({error, {_, {invalid_config_file, ConfigFile}}},
rcl_cmd_args:args2state(getopt:parse(relcool:opt_spec_list(), CmdLine))).
diff --git a/test/rclt_discover_SUITE.erl b/test/rclt_discover_SUITE.erl
index f8dc8a3..4b6cb2a 100644
--- a/test/rclt_discover_SUITE.erl
+++ b/test/rclt_discover_SUITE.erl
@@ -46,7 +46,7 @@ init_per_testcase(_, Config) ->
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]}], []),
+ State = rcl_state:new([{lib_dirs, [LibDir1, LibDir2]}], release),
[{lib1, LibDir1},
{lib2, LibDir2},
{state, State} | Config].
diff --git a/test/rclt_release_SUITE.erl b/test/rclt_release_SUITE.erl
index 23cdb9e..95aa385 100644
--- a/test/rclt_release_SUITE.erl
+++ b/test/rclt_release_SUITE.erl
@@ -52,7 +52,7 @@ 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]}], []),
+ State = rcl_state:new([{lib_dirs, [LibDir1]}], release),
[{lib1, LibDir1},
{state, State} | Config].
@@ -86,7 +86,7 @@ make_release(Config) ->
OutputDir = filename:join([proplists:get_value(data_dir, Config),
create_random_name("relcool-output")]),
{ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2,
- OutputDir, [ConfigFile]),
+ OutputDir, ConfigFile),
[{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)),
AppSpecs = rcl_release:applications(Release),
?assert(lists:keymember(stdlib, 1, AppSpecs)),
@@ -122,7 +122,7 @@ make_invalid_config_release(Config) ->
create_random_name("relcool-output")]),
{error, {rcl_prv_config,
{consult, _, _}}} = relcool:do(undefined, undefined, [], [LibDir1], 2,
- OutputDir, [ConfigFile]).
+ OutputDir, ConfigFile).
make_scriptless_release(Config) ->
LibDir1 = proplists:get_value(lib1, Config),
@@ -149,7 +149,7 @@ make_scriptless_release(Config) ->
OutputDir = filename:join([proplists:get_value(data_dir, Config),
create_random_name("relcool-output")]),
{ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2,
- OutputDir, [ConfigFile]),
+ 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"]))),
@@ -200,7 +200,7 @@ make_overridden_release(Config) ->
{ok, Cwd} = file:get_cwd(),
{ok, State} = relcool:do(Cwd, undefined, undefined, [], [LibDir1], 2,
OutputDir, [{OverrideAppName, OverrideAppDir}],
- [ConfigFile]),
+ ConfigFile),
[{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)),
AppSpecs = rcl_release:applications(Release),
?assert(lists:keymember(stdlib, 1, AppSpecs)),
@@ -289,13 +289,13 @@ make_rerun_overridden_release(Config) ->
create_random_name("relcool-output")]),
{ok, Cwd} = file:get_cwd(),
{ok, State} = relcool:do(Cwd, undefined, undefined, [], [LibDir1], 2,
- OutputDir, [{OverrideAppName, OverrideAppDir}],
- [ConfigFile]),
+ OutputDir, [{OverrideAppName, OverrideAppDir}],
+ ConfigFile),
%% Now we run it again to see if it failse.
{ok, State} = relcool:do(Cwd,undefined, undefined, [], [LibDir1], 2,
- OutputDir, [{OverrideAppName, OverrideAppDir}],
- [ConfigFile]),
+ OutputDir, [{OverrideAppName, OverrideAppDir}],
+ ConfigFile),
[{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)),
AppSpecs = rcl_release:applications(Release),
@@ -358,7 +358,7 @@ overlay_release(Config) ->
create_random_name("relcool-output")]),
{ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2,
- OutputDir, [ConfigFile]),
+ OutputDir, ConfigFile),
[{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)),
AppSpecs = rcl_release:applications(Release),
@@ -469,7 +469,7 @@ make_goalless_release(Config) ->
create_random_name("relcool-output")]),
?assertMatch({error,{rcl_prv_release,no_goals_specified}},
relcool:do(undefined, undefined, [], [LibDir1], 2,
- OutputDir, [ConfigFile])).
+ OutputDir, ConfigFile)).
make_depfree_release(Config) ->
LibDir1 = proplists:get_value(lib1, Config),
@@ -494,7 +494,7 @@ make_depfree_release(Config) ->
OutputDir = filename:join([proplists:get_value(data_dir, Config),
create_random_name("relcool-output")]),
{ok, State} = relcool:do(undefined, undefined, [], [LibDir1], 2,
- OutputDir, [ConfigFile]),
+ OutputDir, ConfigFile),
[{{foo, "0.0.1"}, Release}] = ec_dictionary:to_list(rcl_state:releases(State)),
AppSpecs = rcl_release:applications(Release),
?assert(lists:keymember(stdlib, 1, AppSpecs)),