diff options
author | Tristan Sloughter <[email protected]> | 2012-12-10 12:19:36 -0800 |
---|---|---|
committer | Tristan Sloughter <[email protected]> | 2012-12-10 12:19:36 -0800 |
commit | 25483b93b6f179b29742451ac65d367ab3b7ca7e (patch) | |
tree | f1fe9d5c6ddcf6626c84b9121ce1d334d776556e /src | |
parent | 69e6bcb71b8ce15556621fc94874bce751b50c50 (diff) | |
parent | c3e728afb67101480d0c7b52c51bc522f08fb08f (diff) | |
download | relx-25483b93b6f179b29742451ac65d367ab3b7ca7e.tar.gz relx-25483b93b6f179b29742451ac65d367ab3b7ca7e.tar.bz2 relx-25483b93b6f179b29742451ac65d367ab3b7ca7e.zip |
Merge pull request #16 from ericbmerritt/next
default relcool.config support
Diffstat (limited to 'src')
-rw-r--r-- | src/rcl_cmd_args.erl | 15 | ||||
-rw-r--r-- | src/rcl_prv_assembler.erl | 33 | ||||
-rw-r--r-- | src/rcl_prv_config.erl | 50 | ||||
-rw-r--r-- | src/rcl_state.erl | 20 | ||||
-rw-r--r-- | src/relcool.erl | 4 |
5 files changed, 99 insertions, 23 deletions
diff --git a/src/rcl_cmd_args.erl b/src/rcl_cmd_args.erl index 68bd9ce..d72bce3 100644 --- a/src/rcl_cmd_args.erl +++ b/src/rcl_cmd_args.erl @@ -75,9 +75,6 @@ format_error({invalid_config_file, Config}) -> io_lib:format("Invalid configuration file specified: ~s", [Config]); format_error({failed_to_parse, Spec}) -> io_lib:format("Unable to parse spec ~s", [Spec]); -format_error({unable_to_create_output_dir, OutputDir}) -> - io_lib:format("Unable to create output directory (possible permissions issue): ~s", - [OutputDir]); format_error({not_directory, Dir}) -> io_lib:format("Library directory does not exist: ~s", [Dir]); format_error({invalid_log_level, LogLevel}) -> @@ -148,17 +145,7 @@ convert_goals([RawSpec | Rest], Acc) -> {ok, rcl_state:cmd_args()} | relcool:error(). create_output_dir(Opts, Acc) -> OutputDir = proplists:get_value(output_dir, Opts, "./_rel"), - case filelib:is_dir(OutputDir) of - false -> - case rcl_util:mkdir_p(OutputDir) of - ok -> - create_lib_dirs(Opts, [{output_dir, OutputDir} | Acc]); - {error, _} -> - ?RCL_ERROR({unable_to_create_output_dir, OutputDir}) - end; - true -> - create_lib_dirs(Opts, [{output_dir, OutputDir} | Acc]) - end. + create_lib_dirs(Opts, [{output_dir, OutputDir} | Acc]). -spec create_lib_dirs([getopt:option()], rcl_state:cmd_args()) -> {ok, rcl_state:cmd_args()} | relcool:error(). diff --git a/src/rcl_prv_assembler.erl b/src/rcl_prv_assembler.erl index c0f65c9..75a54ec 100644 --- a/src/rcl_prv_assembler.erl +++ b/src/rcl_prv_assembler.erl @@ -44,11 +44,16 @@ do(State) -> {RelName, RelVsn} = rcl_state:default_release(State), Release = rcl_state:get_release(State, RelName, RelVsn), OutputDir = rcl_state:output_dir(State), - case rcl_release:realized(Release) of - true -> - copy_app_directories_to_output(State, Release, OutputDir); - false -> - ?RCL_ERROR({unresolved_release, RelName, RelVsn}) + case create_output_dir(OutputDir) of + ok -> + case rcl_release:realized(Release) of + true -> + copy_app_directories_to_output(State, Release, OutputDir); + false -> + ?RCL_ERROR({unresolved_release, RelName, RelVsn}) + end; + Error -> + Error end. -spec format_error(ErrorDetail::term()) -> iolist(). @@ -69,6 +74,9 @@ format_error({release_script_generation_error, RelFile}) -> format_error({release_script_generation_warning, Module, Warnings}) -> ["Warnings generating release \s", rcl_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)]. @@ -76,6 +84,21 @@ format_error({release_script_generation_error, Module, Errors}) -> %%%=================================================================== %%% Internal Functions %%%=================================================================== +-spec create_output_dir(file:name()) -> + ok | {error, Reason::term()}. +create_output_dir(OutputDir) -> + case filelib:is_dir(OutputDir) of + false -> + case rcl_util:mkdir_p(OutputDir) of + ok -> + ok; + {error, _} -> + ?RCL_ERROR({unable_to_create_output_dir, OutputDir}) + end; + true -> + ok + end. + copy_app_directories_to_output(State, Release, OutputDir) -> LibDir = filename:join([OutputDir, "lib"]), ok = ec_file:mkdir_p(LibDir), diff --git a/src/rcl_prv_config.erl b/src/rcl_prv_config.erl index ee1c770..7ea9a77 100644 --- a/src/rcl_prv_config.erl +++ b/src/rcl_prv_config.erl @@ -29,8 +29,12 @@ init(State) -> %% populating the state as a result. -spec do(rcl_state:t()) ->{ok, rcl_state:t()} | relcool:error(). do(State) -> - ConfigFiles = rcl_state:config_files(State), - lists:foldl(fun load_config/2, {ok, State}, ConfigFiles). + case rcl_state:config_files(State) of + [] -> + search_for_dominating_config(State); + ConfigFiles -> + lists:foldl(fun load_config/2, {ok, State}, ConfigFiles) + end. -spec format_error(Reason::term()) -> iolist(). format_error({consult, ConfigFile, Reason}) -> @@ -42,6 +46,48 @@ format_error({invalid_term, Term}) -> %%%=================================================================== %%% Internal Functions %%%=================================================================== +search_for_dominating_config({ok, Cwd}) -> + ConfigFile = filename:join(Cwd, "relcool.config"), + case ec_file:exists(ConfigFile) of + true -> + {ok, ConfigFile}; + false -> + search_for_dominating_config(parent_dir(Cwd)) + end; +search_for_dominating_config({error, _}) -> + no_config; +search_for_dominating_config(State0) -> + {ok, Cwd} = file:get_cwd(), + case search_for_dominating_config({ok, Cwd}) of + {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, {ok, rcl_state:config_files(State1, [Config])}); + no_config -> + {ok, State0} + end. + +%% @doc Given a directory returns the name of the parent directory. +-spec parent_dir(Filename::string()) -> + {ok, DirName::string()} | {error, no_parent_dir}. +parent_dir(Filename) -> + parent_dir(filename:split(Filename), []). + +%% @doc Given list of directories, splits the list and returns all dirs but the +%% last as a path. +-spec parent_dir([string()], [string()]) -> + {ok, DirName::string()} | {error, no_parent_dir}. +parent_dir([_H], []) -> + {error, no_parent_dir}; +parent_dir([], []) -> + {error, no_parent_dir}; +parent_dir([_H], Acc) -> + {ok, filename:join(lists:reverse(Acc))}; +parent_dir([H | T], Acc) -> + parent_dir(T, [H | Acc]). + + -spec load_config(file:filename(), {ok, rcl_state:t()} | relcool:error()) -> {ok, rcl_state:t()} | relcool:error(). load_config(_, Err = {error, _}) -> diff --git a/src/rcl_state.erl b/src/rcl_state.erl index 7397e6f..bd26a47 100644 --- a/src/rcl_state.erl +++ b/src/rcl_state.erl @@ -31,10 +31,13 @@ overrides/2, goals/1, config_files/1, + config_files/2, providers/1, providers/2, sys_config/1, sys_config/2, + root_dir/1, + root_dir/2, add_release/2, get_release/3, update_release/2, @@ -57,6 +60,7 @@ cmd_args/0]). -record(state_t, {log :: rcl_log:t(), + root_dir :: file:name(), caller :: caller(), output_dir :: file:name(), lib_dirs=[] :: [file:name()], @@ -90,9 +94,10 @@ %% @doc Create a new 'log level' for the system -spec new(proplists:proplist(), [file:filename()] | file:filename()) -> t(). new(PropList, Targets) when erlang:is_list(PropList) -> + {ok, Root} = file:get_cwd(), State0 = #state_t{log = proplists:get_value(log, PropList, rcl_log:new(error)), - output_dir=filename:absname(proplists:get_value(output_dir, PropList, "")), + output_dir=proplists:get_value(output_dir, PropList, ""), lib_dirs=get_lib_dirs(proplists:get_value(lib_dirs, PropList, [])), config_files=process_config_files(Targets), goals=proplists:get_value(goals, PropList, []), @@ -100,6 +105,7 @@ new(PropList, Targets) when erlang:is_list(PropList) -> 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), proplists:get_value(relvsn, PropList, undefined)}}, create_logic_providers(State0). @@ -135,6 +141,10 @@ goals(#state_t{goals=TS}) -> config_files(#state_t{config_files=ConfigFiles}) -> ConfigFiles. +-spec config_files(t(), [file:filename()]) -> t(). +config_files(State, ConfigFiles) -> + State#state_t{config_files=ConfigFiles}. + -spec providers(t()) -> [rcl_provider:t()]. providers(#state_t{providers=Providers}) -> Providers. @@ -147,6 +157,14 @@ sys_config(#state_t{sys_config=SysConfig}) -> sys_config(State, SysConfig) -> State#state_t{sys_config=SysConfig}. +-spec root_dir(t()) -> file:filename() | undefined. +root_dir(#state_t{root_dir=RootDir}) -> + RootDir. + +-spec root_dir(t(), file:filename()) -> t(). +root_dir(State, RootDir) -> + State#state_t{root_dir=RootDir}. + -spec providers(t(), [rcl_provider:t()]) -> t(). providers(M, NewProviders) -> M#state_t{providers=NewProviders}. diff --git a/src/relcool.erl b/src/relcool.erl index 0d75c62..c6747ca 100644 --- a/src/relcool.erl +++ b/src/relcool.erl @@ -93,7 +93,7 @@ opt_spec_list() -> "usually the OTP"}, {output_dir, $o, "output-dir", string, "The output directory for the release. This is `./` by default."}, {lib_dir, $l, "lib-dir", string, "Additional dirs that should be searched for OTP Apps"}, - {log_level, $V, "verbose", {integer, 2}, "Verbosity level, maybe between 0 and 2"} + {log_level, $V, "verbose", {integer, 0}, "Verbosity level, maybe between 0 and 2"} ]. -spec format_error(Reason::term()) -> iolist(). @@ -126,6 +126,8 @@ run_providers(State0) -> Err = {error, _} -> Err; {ok, State1} -> + RootDir = rcl_state:root_dir(State1), + ok = file:set_cwd(RootDir), Providers = rcl_state:providers(State1), Result = run_providers(ConfigProvider, Providers, State1), handle_output(State1, rcl_state:caller(State1), Result) |