summaryrefslogtreecommitdiff
path: root/src/rebar_prv_shell.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/rebar_prv_shell.erl')
-rw-r--r--src/rebar_prv_shell.erl76
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).