diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rebar.hrl | 14 | ||||
-rw-r--r-- | src/rebar_app_discover.erl | 13 | ||||
-rw-r--r-- | src/rebar_git_resource.erl | 28 | ||||
-rw-r--r-- | src/rebar_prv_shell.erl | 43 | ||||
-rw-r--r-- | src/rebar_resource_v2.erl | 3 | ||||
-rw-r--r-- | src/rebar_utils.erl | 14 |
6 files changed, 90 insertions, 25 deletions
diff --git a/src/rebar.hrl b/src/rebar.hrl index f11302d..fedf0d0 100644 --- a/src/rebar.hrl +++ b/src/rebar.hrl @@ -55,23 +55,9 @@ state :: term(), implementation :: rebar_resource | rebar_resource_v2}). --ifdef(namespaced_types). -type rebar_dict() :: dict:dict(). --else. --type rebar_dict() :: dict(). --endif. - --ifdef(namespaced_types). -type rebar_digraph() :: digraph:graph(). --else. --type rebar_digraph() :: digraph(). --endif. - --ifdef(namespaced_types). -type rebar_set() :: sets:set(). --else. --type rebar_set() :: set(). --endif. -ifdef(fun_stacktrace). -define(WITH_STACKTRACE(T, R, S), T:R -> S = erlang:get_stacktrace(),). diff --git a/src/rebar_app_discover.erl b/src/rebar_app_discover.erl index 21dea29..0c97ad7 100644 --- a/src/rebar_app_discover.erl +++ b/src/rebar_app_discover.erl @@ -52,7 +52,7 @@ do(State, LibDirs) -> Name = rebar_app_info:name(AppInfo), case enable(State, AppInfo) of true -> - {AppInfo1, StateAcc1} = merge_opts(AppInfo, StateAcc), + {AppInfo1, StateAcc1} = merge_opts(TopLevelApp, AppInfo, StateAcc), OutDir = filename:join(DepsDir, Name), AppInfo2 = rebar_app_info:out_dir(AppInfo1, OutDir), ProjectDeps1 = lists:delete(Name, ProjectDeps), @@ -91,9 +91,9 @@ format_error({missing_module, Module}) -> %% some configuration like erl_opts must be merged into a subapp's opts %% while plugins and hooks need to be kept defined to only either the %% top level state or an individual application. --spec merge_opts(rebar_app_info:t(), rebar_state:t()) -> +-spec merge_opts(root | binary(), rebar_app_info:t(), rebar_state:t()) -> {rebar_app_info:t(), rebar_state:t()}. -merge_opts(AppInfo, State) -> +merge_opts(TopLevelApp, AppInfo, State) -> %% These steps make sure that hooks and artifacts are run in the context of %% the application they are defined at. If an umbrella structure is used and %% they are defined at the top level they will instead run in the context of @@ -104,7 +104,12 @@ merge_opts(AppInfo, State) -> Name = rebar_app_info:name(AppInfo1), %% We reset the opts here to default so no profiles are applied multiple times - AppInfo2 = rebar_app_info:apply_overrides(rebar_state:get(State1, overrides, []), AppInfo1), + AppInfo2 = case TopLevelApp of + Name -> % don't apply to the root app + AppInfo; + _ -> % apply overrides when in an umbrella project or on deps + rebar_app_info:apply_overrides(rebar_state:get(State1, overrides, []), AppInfo1) + end, AppInfo3 = rebar_app_info:apply_profiles(AppInfo2, CurrentProfiles), %% Will throw an exception if checks fail diff --git a/src/rebar_git_resource.erl b/src/rebar_git_resource.erl index ac1316b..4e81c05 100644 --- a/src/rebar_git_resource.erl +++ b/src/rebar_git_resource.erl @@ -236,7 +236,17 @@ git_vsn_fetch() -> end. make_vsn(AppInfo, _) -> - make_vsn_(rebar_app_info:dir(AppInfo)). + Dir = rebar_app_info:dir(AppInfo), + case rebar_app_info:original_vsn(AppInfo) of + {git, short} -> + git_ref(Dir, "--short"); + {git, long} -> + git_ref(Dir, ""); + _ -> + %% already parsed in rebar_utils to get here so we know it + %% is either for git or "git" + make_vsn_(Dir) + end. make_vsn_(Dir) -> case collect_default_refcount(Dir) of @@ -248,6 +258,19 @@ make_vsn_(Dir) -> %% Internal functions +git_ref(Dir, Arg) -> + case rebar_utils:sh("git rev-parse " ++ Arg ++ " HEAD", + [{use_stdout, false}, + return_on_error, + {cd, Dir}]) of + {error, _} -> + ?WARN("Getting ref of git repo failed in ~ts. " + "Falling back to version 0", [Dir]), + {plain, "0"}; + {ok, String} -> + {plain, rebar_string:trim(String, both, "\n")} + end. + collect_default_refcount(Dir) -> %% Get the tag timestamp and minimal ref from the system. The %% timestamp is really important from an ordering perspective. @@ -256,7 +279,8 @@ collect_default_refcount(Dir) -> return_on_error, {cd, Dir}]) of {error, _} -> - ?WARN("Getting log of git dependency failed in ~ts. Falling back to version 0.0.0", [rebar_dir:get_cwd()]), + ?WARN("Getting log of git repo failed in ~ts. " + "Falling back to version 0.0.0", [Dir]), {plain, "0.0.0"}; {ok, String} -> RawRef = rebar_string:trim(String, both, "\n"), diff --git a/src/rebar_prv_shell.erl b/src/rebar_prv_shell.erl index dd3e6f6..406b90a 100644 --- a/src/rebar_prv_shell.erl +++ b/src/rebar_prv_shell.erl @@ -88,6 +88,9 @@ init(State) -> {start_clean, undefined, "start-clean", boolean, "Cancel any applications in the 'apps' list " "or release."}, + {env_file, undefined, "env-file", string, + "Path to file of os environment variables to setup " + "before expanding vars in config files."}, {user_drv_args, undefined, "user_drv_args", string, "Arguments passed to user_drv start function for " "creating custom shells."}]} @@ -309,6 +312,7 @@ run_script_file(File) -> Result. maybe_boot_apps(State) -> + _ = maybe_set_env_vars(State), case find_apps_to_boot(State) of undefined -> %% try to read in sys.config file @@ -577,6 +581,45 @@ consult_env_config(State, Filename) -> rebar_file_utils:consult_config_terms(State, Terms) end. +maybe_set_env_vars(State) -> + EnvFile =debug_get_value(env_file, rebar_state:get(State, shell, []), undefined, + "Found env_file from config."), + {Opts, _} = rebar_state:command_parsed_args(State), + EnvFile1 = debug_get_value(env_file, Opts, EnvFile, + "Found env_file from command line option."), + + case maybe_read_file(EnvFile1) of + ignore -> + ok; + {error, _} -> + ?WARN("Failed to read file with environment variables: ~p", [EnvFile1]); + {ok, Bin} -> + Lines = string:split(unicode:characters_to_list(Bin), "\n", all), + [handle_env_var_line(Line) || Line <- Lines] + end. + +handle_env_var_line(Line) -> + Trimmed = rebar_string:trim(Line, both, [$\s]), + %% ignore lines starting with # and + %% fail if there are spaces around = + case re:run(Trimmed, "^(?<key>[^#][^\s=]*)=(?<value>[^\s]\.*)", + [{capture, [key, value], list}, unicode]) of + {match, [Key, Value]} -> + os:putenv(Key, Value); + _ -> + case Trimmed of + [$# | _] -> ignore; + [] -> ignore; + Other -> + ?WARN("Unable to parse environment variable from this line: ~ts", [Other]) + end + end. + +maybe_read_file(undefined) -> + ignore; +maybe_read_file(EnvFile) -> + file:read_file(EnvFile). + %% @doc quick and simple variable substitution writeup. %% Supports `${varname}' but not `$varname' nor nested %% values such as `${my_${varname}}'. diff --git a/src/rebar_resource_v2.erl b/src/rebar_resource_v2.erl index b7ee760..537b5f0 100644 --- a/src/rebar_resource_v2.erl +++ b/src/rebar_resource_v2.erl @@ -101,7 +101,8 @@ needs_update(AppInfo, State) -> resource_run(needs_update, rebar_app_info:source(AppInfo), [AppInfo], State). %% this is a special case since it is used for project apps as well, not just deps -make_vsn(AppInfo, VcsType, State) -> +make_vsn(AppInfo, Vsn, State) -> + VcsType = case Vsn of {T, _} -> T; T -> T end, Resources = rebar_state:resources(State), case is_resource_type(VcsType, Resources) of true -> diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index f1e440a..066c673 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -460,7 +460,7 @@ reread_config(ConfigList, Opts) -> %% NB: we attempt to mimic -config here, which survives app reload, %% hence {persistent, true}. SetEnv = case version_tuple(?MODULE:otp_release()) of - {X, _, _} when X =< 17 -> + {X, _, _} when X < 17 -> fun application:set_env/3; _ -> fun (App, Key, Val) -> application:set_env(App, Key, Val, [{persistent, true}]) end @@ -729,7 +729,7 @@ vcs_vsn(AppInfo, Vcs, State) -> {plain, VsnString} -> VsnString; {cmd, CmdString} -> - vcs_vsn_invoke(CmdString, rebar_app_info:dir(AppInfo)); + cmd_vsn_invoke(CmdString, rebar_app_info:dir(AppInfo)); unknown -> ?ABORT("vcs_vsn: Unknown vsn format: ~p", [Vcs]); {error, Reason} -> @@ -743,8 +743,14 @@ vcs_vsn_cmd(AppInfo, VCS, State) when VCS =:= semver ; VCS =:= "semver" -> vcs_vsn_cmd(AppInfo, git, State); vcs_vsn_cmd(_AppInfo, {cmd, _Cmd}=Custom, _) -> Custom; +vcs_vsn_cmd(AppInfo, {file, File}, _) -> + Path = filename:join(rebar_app_info:dir(AppInfo), File), + {ok, Vsn} = file:read_file(Path), + {plain, to_list(rebar_string:trim(Vsn))}; vcs_vsn_cmd(AppInfo, VCS, State) when is_atom(VCS) -> rebar_resource_v2:make_vsn(AppInfo, VCS, State); +vcs_vsn_cmd(AppInfo, {VCS, _}=V, State) when is_atom(VCS) -> + rebar_resource_v2:make_vsn(AppInfo, V, State); vcs_vsn_cmd(AppInfo, VCS, State) when is_list(VCS) -> try list_to_existing_atom(VCS) of AVCS -> @@ -759,7 +765,7 @@ vcs_vsn_cmd(AppInfo, VCS, State) when is_list(VCS) -> vcs_vsn_cmd(_, _, _) -> unknown. -vcs_vsn_invoke(Cmd, Dir) -> +cmd_vsn_invoke(Cmd, Dir) -> {ok, VsnString} = rebar_utils:sh(Cmd, [{cd, Dir}, {use_stdout, false}]), rebar_string:trim(VsnString, trailing, "\n"). @@ -966,7 +972,7 @@ get_proxy_auth() -> {ok, ProxyAuth} -> ProxyAuth end. --spec rebar_utils:is_list_of_strings(term()) -> boolean(). +-spec is_list_of_strings(term()) -> boolean(). is_list_of_strings(List) when not is_list(hd(List)) -> false; is_list_of_strings(List) when is_list(hd(List)) -> |