diff options
author | Tristan Sloughter <[email protected]> | 2014-05-07 19:32:17 -0500 |
---|---|---|
committer | Tristan Sloughter <[email protected]> | 2014-05-14 16:06:09 -0500 |
commit | 7d3626779ce5716055b31eed76feb81a9fcb2210 (patch) | |
tree | 13d5dc9d810489c8bcbaf5470a37f45259f4318e /src | |
parent | 227b1ec27d9b4c186366a64f81628843c8a8cc3e (diff) | |
download | relx-7d3626779ce5716055b31eed76feb81a9fcb2210.tar.gz relx-7d3626779ce5716055b31eed76feb81a9fcb2210.tar.bz2 relx-7d3626779ce5716055b31eed76feb81a9fcb2210.zip |
refactor cli args and config file var merging
Diffstat (limited to 'src')
-rw-r--r-- | src/rlx_cmd_args.erl | 253 | ||||
-rw-r--r-- | src/rlx_prv_assembler.erl | 2 | ||||
-rw-r--r-- | src/rlx_prv_config.erl | 56 | ||||
-rw-r--r-- | src/rlx_state.erl | 101 |
4 files changed, 226 insertions, 186 deletions
diff --git a/src/rlx_cmd_args.erl b/src/rlx_cmd_args.erl index da8f3a0..9233db9 100644 --- a/src/rlx_cmd_args.erl +++ b/src/rlx_cmd_args.erl @@ -33,16 +33,16 @@ {ok, {rlx_state:t(), [string()]}} | relx:error(). args2state(Opts, Targets) -> - RelName = rlx_util:to_atom(proplists:get_value(relname, Opts, undefined)), - RelVsn = proplists:get_value(relvsn, Opts, undefined), case convert_targets(Targets) of {ok, AtomizedTargets} -> - case create_log(Opts, [{relname, RelName}, - {relvsn, RelVsn}]) of + case run_creates(Opts) of Error = {error, _} -> Error; {ok, CommandLineConfig} -> - handle_config(Opts, AtomizedTargets, CommandLineConfig) + RelName = rlx_util:to_atom(proplists:get_value(relname, Opts, undefined)), + RelVsn = proplists:get_value(relvsn, Opts, undefined), + handle_config(Opts, AtomizedTargets, + [{default_release, {RelName, RelVsn}} | CommandLineConfig]) end; Error -> Error @@ -95,7 +95,7 @@ handle_config(Opts, Targets, CommandLineConfig) -> Error = {error, _} -> Error; {ok, Config} -> - {ok, rlx_state:new([{config, Config} | CommandLineConfig], Targets)} + {ok, rlx_state:new(Config, CommandLineConfig, Targets)} end. -spec convert_targets([string()]) -> {ok, release | relup} | relx:error(). @@ -131,40 +131,137 @@ validate_config(Config) -> ?RLX_ERROR({invalid_config_file, Config}) end. --spec create_log([getopt:option()], rlx_state:cmd_args()) -> - {ok, rlx_state:cmd_args()} | relx:error(). -create_log(Opts, Acc) -> +run_creates(Opts) -> + try + Conf = lists:flatten(lists:foldl(fun(X, Acc) -> + [create(X, Opts) | Acc] + end, [], proplists:get_keys(Opts))), + {ok, Conf} + catch + throw:E -> + E + end. + +create(log_level, Opts) -> LogLevel = proplists:get_value(log_level, Opts, 0), if LogLevel >= 0, LogLevel =< 3 -> - create_goals(Opts, [{log, ec_cmd_log:new(LogLevel, command_line)} | Acc]); + {log, ec_cmd_log:new(LogLevel, command_line)}; true -> - ?RLX_ERROR({invalid_log_level, LogLevel}) - end. - --spec create_goals([getopt:option()], rlx_state:cmd_args()) -> - {ok, rlx_state:cmd_args()} | relx:error(). -create_goals(Opts, Acc) -> + throw(?RLX_ERROR({invalid_log_level, LogLevel})) + end; +create(goal, Opts) -> Goals = proplists:get_value(goals, Opts, []) ++ proplists:get_all_values(goal, Opts), case convert_goals(Goals, []) of Error={error, _} -> - Error; + throw(Error); {ok, Specs} -> - create_overrides(Opts, [{goals, Specs} | Acc]) - end. - --spec create_overrides([getopt:option()], rlx_state:cmd_args()) -> - {ok, rlx_state:cmd_args()} | relx:error(). -create_overrides(Opts, Acc) -> + {goals, Specs} + end; +create(goals, Opts) -> + Goals = proplists:get_value(goals, Opts, []) ++ + proplists:get_all_values(goal, Opts), + case convert_goals(Goals, []) of + Error={error, _} -> + throw(Error); + {ok, Specs} -> + {goals, Specs} + end; +create(overrides, Opts) -> 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]); + {overrides, Overrides}; Error -> - Error - end. + throw(Error) + end; +create(output_dir, Opts) -> + OutputDir = proplists:get_value(output_dir, Opts, "./_rel"), + {output_dir, filename:absname(OutputDir)}; +create(lib_dir, Opts) -> + Dirs = proplists:get_all_values(lib_dir, Opts) ++ + proplists:get_value(lib_dirs, Opts, []), + ExpDirs = rlx_util:wildcard_paths(Dirs), + case check_lib_dirs(ExpDirs) of + Error = {error, _} -> + throw(Error); + ok -> + LibDirs = [rlx_util:to_binary(Dir) || Dir <- ExpDirs], + {lib_dirs, LibDirs} + end; +create(lib_dirs, Opts) -> + Dirs = proplists:get_all_values(lib_dir, Opts) ++ + proplists:get_value(lib_dirs, Opts, []), + ExpDirs = rlx_util:wildcard_paths(Dirs), + case check_lib_dirs(ExpDirs) of + Error = {error, _} -> + throw(Error); + ok -> + LibDirs = [rlx_util:to_binary(Dir) || Dir <- ExpDirs], + {lib_dirs, LibDirs} + end; +create(root_dir, Opts) -> + Dir = proplists:get_value(root_dir, Opts, undefined), + case Dir of + undefined -> + {ok, Cwd} = file:get_cwd(), + {root_dir, Cwd}; + _ -> + {root_dir, filename:absname(Dir)} + end; +create(default_libs, Opts) -> + Def = proplists:get_value(default_libs, Opts, true), + {default_libs, Def}; +create(overlay_vars, Opts)-> + OverlayVars = proplists:get_all_values(overlay_vars, Opts), + {overlay_vars, OverlayVars}; +create(sys_config, Opts) -> + SysConfig = proplists:get_value(sys_config, Opts, undefined), + {sys_config, SysConfig}; +create(system_libs, Opts) -> + SystemLibs = proplists:get_value(system_libs, Opts, undefined), + {system_libs, SystemLibs}; +create(upfrom, Opts) -> + case proplists:get_value(upfrom, Opts, undefined) of + undefined -> + []; + UpFrom -> + {upfrom, UpFrom} + end; +create(caller, Opts) -> + case proplists:get_value(caller, Opts, api) of + "command_line" -> + {caller, command_line}; + "commandline" -> + {caller, command_line}; + "api" -> + {caller, api}; + api -> + {caller, api}; + commandline -> + {caller, command_line}; + command_line -> + {caller, command_line}; + Caller -> + ?RLX_ERROR({invalid_caller, Caller}) + end; +create(paths, Opts) -> + Dirs = proplists:get_all_values(path, Opts) ++ + proplists:get_value(paths, Opts, []), + case check_lib_dirs(Dirs) of + Error = {error, _} -> + throw(Error); + ok -> + code:add_pathsa([filename:absname(Path) || Path <- Dirs]), + [] + end; +create(dev_mode, Opts) -> + DevMode = proplists:get_value(dev_mode, Opts, false), + {dev_mode, DevMode}; +create(_, _) -> + []. -spec convert_overrides([{atom(), string() | binary()} | string() | binary()], [{atom(), string() | binary()}]) -> @@ -212,110 +309,6 @@ parse_goal(RawSpec, Rest, Acc) -> ?RLX_ERROR({failed_to_parse, RawSpec}) end. --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()], rlx_state:cmd_args()) -> - {ok, rlx_state:cmd_args()} | relx:error(). -create_lib_dirs(Opts, Acc) -> - Dirs = proplists:get_all_values(lib_dir, Opts) ++ - proplists:get_value(lib_dirs, Opts, []), - ExpDirs = rlx_util:wildcard_paths(Dirs), - case check_lib_dirs(ExpDirs) of - Error = {error, _} -> - Error; - ok -> - create_root_dir(Opts, [{lib_dirs, ExpDirs} | Acc]) - end. - --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 - undefined -> - {ok, Cwd} = file:get_cwd(), - create_disable_default_libs(Opts, [{root_dir, Cwd} | Acc]); - _ -> - create_disable_default_libs(Opts, [{root_dir, Dir} | Acc]) - end. - --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(default_libs, Opts, true), - create_overlay_vars(Opts, [{default_libs, Def} | Acc]). - --spec create_overlay_vars([getopt:option()], rlx_state:cmd_args()) -> - {ok, rlx_state:cmd_args()} | relx:error(). -create_overlay_vars(Opts, Acc) -> - OverlayVars = proplists:get_all_values(overlay_vars, Opts), - create_sys_config(Opts, [{overlay_vars, OverlayVars} | Acc]). - --spec create_sys_config([getopt:option()], rlx_state:cmd_args()) -> - {ok, rlx_state:cmd_args()} | relx:error(). -create_sys_config(Opts, Acc) -> - SysConfig = proplists:get_value(sys_config, Opts, undefined), - create_system_libs(Opts, [{sys_config, SysConfig} | Acc]). - --spec create_system_libs([getopt:option()], rlx_state:cmd_args()) -> - {ok, rlx_state:cmd_args()} | relx:error(). -create_system_libs(Opts, Acc) -> - SystemLibs = proplists:get_value(system_libs, Opts, undefined), - create_upfrom(Opts, [{system_libs, SystemLibs} | Acc]). - --spec create_upfrom([getopt:option()], rlx_state: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" -> - create_paths(Opts, [{caller, command_line} | Acc]); - "commandline" -> - create_paths(Opts, [{caller, command_line} | Acc]); - "api" -> - create_paths(Opts, [{caller, api} | Acc]); - api -> - create_paths(Opts, [{caller, api} | Acc]); - commandline -> - create_paths(Opts, [{caller, command_line} | Acc]); - command_line -> - create_paths(Opts, [{caller, command_line} | Acc]); - Caller -> - ?RLX_ERROR({invalid_caller, Caller}) - end. - --spec create_paths([getopt:option()], rlx_state:cmd_args()) -> - {ok, rlx_state:cmd_args()} | relx:error(). -create_paths(Opts, Acc) -> - Dirs = proplists:get_all_values(path, Opts) ++ - proplists:get_value(paths, Opts, []), - case check_lib_dirs(Dirs) of - Error = {error, _} -> - Error; - ok -> - code:add_pathsa([filename:absname(Path) || Path <- Dirs]), - create_dev_mode(Opts, Acc) - end. - --spec create_dev_mode([getopt:option()], rlx_state:cmd_args()) -> - {ok, rlx_state:cmd_args()} | relx:error(). -create_dev_mode(Opts, Acc) -> - DevMode = proplists:get_value(dev_mode, Opts, false), - {ok, [{dev_mode, DevMode} | Acc]}. - -spec check_lib_dirs([string()]) -> ok | relx:error(). check_lib_dirs([]) -> ok; diff --git a/src/rlx_prv_assembler.erl b/src/rlx_prv_assembler.erl index 47d96aa..1afd18d 100644 --- a/src/rlx_prv_assembler.erl +++ b/src/rlx_prv_assembler.erl @@ -605,7 +605,7 @@ make_upfrom_script(State, Release, UpFrom) -> case make_script(Options, fun(CorrectOptions) -> systools:make_relup(CurrentRel, [UpFromRel], [UpFromRel], CorrectOptions) - end) of + end) of ok -> ec_cmd_log:error(rlx_state:log(State), "relup from ~s to ~s successfully created!", diff --git a/src/rlx_prv_config.erl b/src/rlx_prv_config.erl index 9efd8a0..dd7dc70 100644 --- a/src/rlx_prv_config.erl +++ b/src/rlx_prv_config.erl @@ -114,23 +114,34 @@ load_config(ConfigFile, State) -> {error, Reason} -> ?RLX_ERROR({consult, ConfigFile, Reason}); {ok, Terms} -> - lists:foldl(fun load_terms/2, {ok, State}, Terms) + CliTerms = rlx_state:cli_args(State), + lists:foldl(fun load_terms/2, {ok, State}, merge_configs(CliTerms, Terms)) end, ok = file:set_cwd(CurrentCwd), Result. -spec load_terms(term(), {ok, rlx_state:t()} | relx:error()) -> {ok, rlx_state:t()} | relx:error(). -load_terms({default_release, RelName, RelVsn}, {ok, State}) -> - case rlx_state:default_configured_release(State) of - {undefined, undefined} -> - {ok, rlx_state:default_configured_release(State, RelName, RelVsn)}; - _ -> - {ok, State} - end; +load_terms({default_release, {RelName, RelVsn}}, {ok, State}) -> + {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}; +load_terms({default_libs, DefaultLibs}, {ok, State}) -> + State2 = rlx_state:put(State, + default_libs, + DefaultLibs), + {ok, State2}; +load_terms({system_libs, SystemLibs}, {ok, State}) -> + State2 = rlx_state:put(State, + system_libs, + SystemLibs), + {ok, State2}; +load_terms({overlay_vars, OverlayVars}, {ok, State}) -> + State2 = rlx_state:put(State, + overlay_vars, + list_of_overlay_vars_files(OverlayVars)), + {ok, State2}; load_terms({lib_dirs, Dirs}, {ok, State}) -> State2 = rlx_state:add_lib_dirs(State, @@ -159,6 +170,10 @@ load_terms({overrides, Overrides0}, {ok, State0}) -> {ok, rlx_state:overrides(State0, Overrides0)}; load_terms({dev_mode, DevMode}, {ok, State0}) -> {ok, rlx_state:dev_mode(State0, DevMode)}; +load_terms({goals, Goals}, {ok, State0}) -> + {ok, rlx_state:goals(State0, Goals)}; +load_terms({upfrom, UpFrom}, {ok, State0}) -> + {ok, rlx_state:upfrom(State0, UpFrom)}; load_terms({include_src, IncludeSrc}, {ok, State0}) -> {ok, rlx_state:include_src(State0, IncludeSrc)}; load_terms({release, {RelName, Vsn, {extend, RelName2}}, Applications}, {ok, State0}) -> @@ -199,6 +214,8 @@ load_terms({sys_config, SysConfig}, {ok, State}) -> _ -> {ok, State} end; +load_terms({root_dir, Root}, {ok, State}) -> + {ok, rlx_state:root_dir(State, filename:absname(Root))}; load_terms({output_dir, OutputDir}, {ok, State}) -> {ok, rlx_state:base_output_dir(State, filename:absname(OutputDir))}; load_terms({overlay_vars, OverlayVars}, {ok, State}) -> @@ -232,3 +249,26 @@ list_of_overlay_vars_files([H | _]=FileNames) when erlang:is_list(H) -> FileNames; list_of_overlay_vars_files(FileName) when is_list(FileName) -> [FileName]. + +merge_configs([], ConfigTerms) -> + ConfigTerms; +merge_configs([{_Key, undefined} | CliTerms], ConfigTerms) -> + merge_configs(CliTerms, ConfigTerms); +merge_configs([{_Key, []} | CliTerms], ConfigTerms) -> + merge_configs(CliTerms, ConfigTerms); +merge_configs([{Key, Value} | CliTerms], ConfigTerms) -> + case Key of + X when X =:= lib_dirs + ; X =:= goals + ; X =:= overlay_vars + ; X =:= overrides -> + case lists:keyfind(Key, 1, ConfigTerms) of + {Key, Value2} -> + MergedValue = lists:umerge([Value, Value2]), + merge_configs(CliTerms, lists:keyreplace(Key, 1, ConfigTerms, {Key, MergedValue})); + false -> + merge_configs(CliTerms, [{Key, Value} | ConfigTerms]) + end; + _ -> + merge_configs(CliTerms, [{Key, Value} | ConfigTerms]) + end. diff --git a/src/rlx_state.erl b/src/rlx_state.erl index 5b488c8..c84be78 100644 --- a/src/rlx_state.erl +++ b/src/rlx_state.erl @@ -24,6 +24,7 @@ -module(rlx_state). -export([new/2, + new/3, log/1, actions/1, output_dir/1, @@ -36,8 +37,11 @@ skip_apps/1, skip_apps/2, goals/1, + goals/2, config_file/1, config_file/2, + cli_args/1, + cli_args/2, providers/1, providers/2, vm_args/1, @@ -68,6 +72,7 @@ include_src/1, include_src/2, upfrom/1, + upfrom/2, format/1, format/2]). @@ -84,13 +89,14 @@ output_dir :: file:name(), lib_dirs=[] :: [file:name()], config_file=[] :: file:filename() | undefined, + cli_args=[] :: proplists:proplist(), goals=[] :: [rlx_depsolver:constraint()], providers=[] :: [rlx_provider:t()], available_apps=[] :: [rlx_app_info:t()], - default_configured_release :: {rlx_release:name(), rlx_release:vsn()}, + default_configured_release :: {rlx_release:name(), rlx_release:vsn()} | undefined, vm_args :: file:filename() | undefined, sys_config :: file:filename() | undefined, - overrides :: [{AppName::atom(), Directory::file:filename()}], + overrides=[] :: [{AppName::atom(), Directory::file:filename()}], skip_apps=[] :: [AppName::atom()], configured_releases :: releases(), realized_releases :: releases(), @@ -116,45 +122,37 @@ %%============================================================================ %% API %%============================================================================ -%% @doc Create a new 'log level' for the system --spec new(proplists:proplist(), undefined | [atom()]) -> t(). -new(PropList, undefined) -> - new(PropList, [release]); -new(PropList, Targets) - when erlang:is_list(PropList), +-spec new(string(), undefined | [atom()]) -> t(). +new(Config, Targets) -> + new(Config, [], Targets). + +-spec new(string(), proplists:proplist(), undefined | [atom()]) -> t(). +new(Config, CommandLineConfig, undefined) -> + new(Config, CommandLineConfig, [release]); +new(Config, CommandLineConfig, Targets) + when erlang:is_list(CommandLineConfig), erlang:is_list(Targets) -> {ok, Root} = file:get_cwd(), - Caller = proplists:get_value(caller, PropList, api), - State0 = - #state_t{log = proplists:get_value(log, PropList, ec_cmd_log:new(error, Caller)), - 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), - sys_config=proplists:get_value(sys_config, PropList, undefined), - dev_mode = proplists:get_value(dev_mode, PropList), - actions = Targets, - caller = Caller, - goals=proplists:get_value(goals, PropList, []), - providers = [], - 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 = filename:absname(proplists:get_value(root_dir, PropList, Root)), - upfrom = proplists:get_value(upfrom, PropList, undefined), - default_configured_release={proplists:get_value(relname, PropList, undefined), - proplists:get_value(relvsn, PropList, undefined)}}, - State1 = rlx_state:put(create_logic_providers(State0), - default_libs, - proplists:get_value(default_libs, PropList, true)), - - State2 = rlx_state:put(create_logic_providers(State1), - system_libs, - proplists:get_value(system_libs, PropList, undefined)), - - rlx_state:put(create_logic_providers(State2), - overlay_vars, - proplists:get_value(overlay_vars, PropList, [])). + + Caller = proplists:get_value(caller, CommandLineConfig, api), + Log = proplists:get_value(log, CommandLineConfig, ec_cmd_log:new(error, Caller)), + + State0 = #state_t{log=Log, + config_file=Config, + cli_args=CommandLineConfig, + actions=Targets, + caller=Caller, + root_dir=Root, + output_dir=filename:join(Root, "_rel"), + providers=[], + default_configured_release=undefined, + configured_releases=ec_dictionary:new(ec_dict), + realized_releases=ec_dictionary:new(ec_dict), + config_values=ec_dictionary:new(ec_dict)}, + State1 = rlx_state:put(State0, default_libs, true), + State2 = rlx_state:put(State1, system_libs, undefined), + State3 = rlx_state:put(State2, overlay_vars, []), + create_logic_providers(State3). %% @doc the actions targeted for this system -spec actions(t()) -> [action()]. @@ -210,6 +208,10 @@ add_lib_dirs(State=#state_t{lib_dirs=LibDir}, Dirs) -> goals(#state_t{goals=TS}) -> TS. +-spec goals(t(), [rlx_depsolver:constraint()]) -> t(). +goals(State, Goals) -> + State#state_t{goals=Goals}. + -spec config_file(t()) -> file:filename() | undefined. config_file(#state_t{config_file=ConfigFiles}) -> ConfigFiles. @@ -218,6 +220,14 @@ config_file(#state_t{config_file=ConfigFiles}) -> config_file(State, ConfigFiles) -> State#state_t{config_file=ConfigFiles}. +-spec cli_args(t()) -> proplists:proplist(). +cli_args(#state_t{cli_args=CliArgs}) -> + CliArgs. + +-spec cli_args(t(), proplists:proplist()) -> t(). +cli_args(State, CliArgs) -> + State#state_t{cli_args=CliArgs}. + -spec providers(t()) -> [rlx_provider:t()]. providers(#state_t{providers=Providers}) -> Providers. @@ -356,6 +366,10 @@ include_src(S, IncludeSrc) -> upfrom(#state_t{upfrom=UpFrom}) -> UpFrom. +-spec upfrom(t(), string() | binary() | undefined) -> t(). +upfrom(State, UpFrom) -> + State#state_t{upfrom=UpFrom}. + -spec format(t()) -> iolist(). format(Mod) -> format(Mod, 0). @@ -395,13 +409,6 @@ create_logic_providers(State0) -> State5#state_t{providers=[ConfigProvider, DiscoveryProvider, ReleaseProvider, OverlayProvider, AssemblerProvider]}. -to_binary(Dir) - when erlang:is_list(Dir) -> - erlang:list_to_binary(Dir); -to_binary(Dir) - when erlang:is_binary(Dir) -> - Dir. - %%%=================================================================== %%% Test Functions %%%=================================================================== @@ -411,7 +418,7 @@ to_binary(Dir) new_test() -> LogState = ec_cmd_log:new(error), - RCLState = new([{log, LogState}], [release]), + RCLState = new(LogState, [], [release]), ?assertMatch(LogState, log(RCLState)). -endif. |