diff options
author | Fred Hebert <mononcqc@ferd.ca> | 2019-03-22 12:27:11 -0400 |
---|---|---|
committer | Fred Hebert <mononcqc@ferd.ca> | 2019-03-22 12:27:11 -0400 |
commit | 86d261dbf1653a7cc074f7749a19b211e53cca0a (patch) | |
tree | 884b8abe552bbe09f76148aa95e9d0431f22a8d7 /src/rebar_prv_shell.erl | |
parent | cc788f1ff3c2c845cda19f27291309effb94511a (diff) |
Attempt at support sys_config_src in shell
Diffstat (limited to 'src/rebar_prv_shell.erl')
-rw-r--r-- | src/rebar_prv_shell.erl | 76 |
1 files changed, 73 insertions, 3 deletions
diff --git a/src/rebar_prv_shell.erl b/src/rebar_prv_shell.erl index c0cfd6d..dd3e6f6 100644 --- a/src/rebar_prv_shell.erl +++ b/src/rebar_prv_shell.erl @@ -36,6 +36,7 @@ format_error/1]). -include("rebar.hrl"). +-include_lib("providers/include/providers.hrl"). -define(PROVIDER, shell). -define(DEPS, [compile]). @@ -503,7 +504,12 @@ find_config(State) -> no_value -> no_config; Filename when is_list(Filename) -> - rebar_file_utils:consult_config(State, Filename) + case is_src_config(Filename) of + false -> + rebar_file_utils:consult_config(State, Filename); + true -> + consult_env_config(State, Filename) + end end. -spec first_value([Fun], State) -> no_value | Value when @@ -540,5 +546,69 @@ find_config_rebar(State) -> -spec find_config_relx(rebar_state:t()) -> [tuple()] | no_value. find_config_relx(State) -> - debug_get_value(sys_config, rebar_state:get(State, relx, []), no_value, - "Found config from relx."). + %% The order in relx is to load the src version first; + %% we do the same. + RelxCfg = rebar_state:get(State, relx, []), + Src = debug_get_value(sys_config_src, RelxCfg, no_value, + "Found config.src from relx."), + case Src of + no_value -> + debug_get_value(sys_config, RelxCfg, no_value, + "Found config from relx."); + _ -> + Src + end. + +-spec is_src_config(file:filename()) -> boolean(). +is_src_config(Filename) -> + filename:extension(Filename) =:= ".src". + +-spec consult_env_config(rebar_state:t(), file:filename()) -> [[tuple()]]. +consult_env_config(State, Filename) -> + RawString = case file:read_file(Filename) of + {error, _} -> "[]."; + {ok, Bin} -> unicode:characters_to_list(Bin) + end, + ReplacedStr = replace_env_vars(RawString), + case rebar_string:consult(unicode:characters_to_list(ReplacedStr)) of + {error, Reason} -> + throw(?PRV_ERROR({bad_term_file, Filename, Reason})); + [Terms] -> + rebar_file_utils:consult_config_terms(State, Terms) + end. + +%% @doc quick and simple variable substitution writeup. +%% Supports `${varname}' but not `$varname' nor nested +%% values such as `${my_${varname}}'. +%% The variable are also defined as only supporting +%% the form `[a-zA-Z_]+[a-zA-Z0-9_]*' as per the POSIX +%% standard. +-spec replace_env_vars(string()) -> unicode:charlist(). +replace_env_vars("") -> ""; +replace_env_vars("${" ++ Str) -> + case until_var_end(Str) of + {ok, VarName, Rest} -> + replace_varname(VarName) ++ replace_env_vars(Rest); + error -> + "${" ++ replace_env_vars(Str) + end; +replace_env_vars([Char|Str]) -> + [Char | replace_env_vars(Str)]. + +until_var_end(Str) -> + case re:run(Str, "([a-zA-Z_]+[a-zA-Z0-9_]*)}", [{capture, [1], list}]) of + nomatch -> + error; + {match, [Name]} -> + {ok, Name, drop_varname(Name, Str)} + end. + +replace_varname(Var) -> + %% os:getenv(Var, "") is only available in OTP-18.0 + case os:getenv(Var) of + false -> ""; + Val -> Val + end. + +drop_varname("", "}" ++ Str) -> Str; +drop_varname([_|Var], [_|Str]) -> drop_varname(Var, Str). |