summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/rebar3.erl2
-rw-r--r--src/rebar_app_utils.erl4
-rw-r--r--src/rebar_file_utils.erl16
-rw-r--r--src/rebar_git_resource.erl4
-rw-r--r--src/rebar_plugins.erl12
-rw-r--r--src/rebar_prv_app_discovery.erl3
-rw-r--r--src/rebar_prv_compile.erl19
-rw-r--r--src/rebar_prv_install_deps.erl5
-rw-r--r--src/rebar_relx.erl12
-rw-r--r--src/rebar_templater.erl25
10 files changed, 85 insertions, 17 deletions
diff --git a/src/rebar3.erl b/src/rebar3.erl
index 9106bb8..84d7c3e 100644
--- a/src/rebar3.erl
+++ b/src/rebar3.erl
@@ -123,7 +123,7 @@ run_aux(State, RawArgs) ->
{ok, Providers} = application:get_env(rebar, providers),
%% Providers can modify profiles stored in opts, so set default after initializing providers
State5 = rebar_state:create_logic_providers(Providers, State4),
- State6 = rebar_plugins:project_apps_install(State5),
+ State6 = rebar_plugins:top_level_install(State5),
State7 = rebar_state:default(State6, rebar_state:opts(State6)),
{Task, Args} = parse_args(RawArgs),
diff --git a/src/rebar_app_utils.erl b/src/rebar_app_utils.erl
index ae1ea1c..d3ef841 100644
--- a/src/rebar_app_utils.erl
+++ b/src/rebar_app_utils.erl
@@ -166,7 +166,9 @@ dep_to_app(Parent, DepsDir, Name, Vsn, Source, IsLock, State) ->
Overrides = rebar_state:get(State, overrides, []),
AppInfo2 = rebar_app_info:set(AppInfo1, overrides, rebar_app_info:get(AppInfo, overrides, [])++Overrides),
AppInfo3 = rebar_app_info:apply_overrides(rebar_app_info:get(AppInfo2, overrides, []), AppInfo2),
- rebar_app_info:is_lock(AppInfo3, IsLock).
+ AppInfo4 = rebar_app_info:apply_profiles(AppInfo3, [default, prod]),
+ AppInfo5 = rebar_app_info:profiles(AppInfo4, [default]),
+ rebar_app_info:is_lock(AppInfo5, IsLock).
update_source(AppInfo, {pkg, PkgName, PkgVsn}, State) ->
{PkgName1, PkgVsn1} = case PkgVsn of
diff --git a/src/rebar_file_utils.erl b/src/rebar_file_utils.erl
index 8c57d19..0f84520 100644
--- a/src/rebar_file_utils.erl
+++ b/src/rebar_file_utils.erl
@@ -262,9 +262,11 @@ path_from_ancestor_(_, _) -> {error, badparent}.
%% reduce a filepath by removing all incidences of `.' and `..'
-spec canonical_path(string()) -> string().
-canonical_path(Dir) -> canonical_path([], filename:split(filename:absname(Dir))).
+canonical_path(Dir) ->
+ Canon = canonical_path([], filename:split(filename:absname(Dir))),
+ filename:nativename(Canon).
-canonical_path([], []) -> filename:nativename("/");
+canonical_path([], []) -> filename:absname("/");
canonical_path(Acc, []) -> filename:join(lists:reverse(Acc));
canonical_path(Acc, ["."|Rest]) -> canonical_path(Acc, Rest);
canonical_path([_|Acc], [".."|Rest]) -> canonical_path(Acc, Rest);
@@ -283,13 +285,19 @@ delete_each_dir_win32([Dir | Rest]) ->
delete_each_dir_win32(Rest).
xcopy_win32(Source,Dest)->
- %% "xcopy \"~s\" \"~s\" /q /y /e 2> nul", Chanegd to robocopy to
+ %% "xcopy \"~s\" \"~s\" /q /y /e 2> nul", Changed to robocopy to
%% handle long names. May have issues with older windows.
Cmd = case filelib:is_dir(Source) of
true ->
+ %% For robocopy, copying /a/b/c/ to /d/e/f/ recursively does not
+ %% create /d/e/f/c/*, but rather copies all files to /d/e/f/*.
+ %% The usage we make here expects the former, not the later, so we
+ %% must manually add the last fragment of a directory to the `Dest`
+ %% in order to properly replicate POSIX platforms
+ NewDest = filename:join([Dest, filename:basename(Source)]),
?FMT("robocopy \"~s\" \"~s\" /e /is 1> nul",
[rebar_utils:escape_double_quotes(filename:nativename(Source)),
- rebar_utils:escape_double_quotes(filename:nativename(Dest))]);
+ rebar_utils:escape_double_quotes(filename:nativename(NewDest))]);
false ->
?FMT("robocopy \"~s\" \"~s\" \"~s\" /e /is 1> nul",
[rebar_utils:escape_double_quotes(filename:nativename(filename:dirname(Source))),
diff --git a/src/rebar_git_resource.erl b/src/rebar_git_resource.erl
index bea74a2..876d047 100644
--- a/src/rebar_git_resource.erl
+++ b/src/rebar_git_resource.erl
@@ -45,7 +45,7 @@ needs_update(Dir, {git, Url, {branch, Branch}}) ->
not ((Current =:= []) andalso compare_url(Dir, Url));
needs_update(Dir, {git, Url, "master"}) ->
needs_update(Dir, {git, Url, {branch, "master"}});
-needs_update(Dir, {git, Url, Ref}) ->
+needs_update(Dir, {git, _, Ref}) ->
{ok, Current} = rebar_utils:sh(?FMT("git rev-parse -q HEAD", []),
[{cd, Dir}]),
Current1 = string:strip(string:strip(Current, both, $\n), both, $\r),
@@ -64,7 +64,7 @@ needs_update(Dir, {git, Url, Ref}) ->
end,
?DEBUG("Comparing git ref ~s with ~s", [Ref1, Current1]),
- not ((Current1 =:= Ref2) andalso compare_url(Dir, Url)).
+ (Current1 =/= Ref2).
compare_url(Dir, Url) ->
{ok, CurrentUrl} = rebar_utils:sh(?FMT("git config --get remote.origin.url", []),
diff --git a/src/rebar_plugins.erl b/src/rebar_plugins.erl
index f2d3977..b4cc3ec 100644
--- a/src/rebar_plugins.erl
+++ b/src/rebar_plugins.erl
@@ -3,7 +3,8 @@
-module(rebar_plugins).
--export([project_apps_install/1
+-export([top_level_install/1
+ ,project_apps_install/1
,install/2
,handle_plugins/3
,handle_plugins/4]).
@@ -14,11 +15,18 @@
%% Public API
%% ===================================================================
+-spec top_level_install(rebar_state:t()) -> rebar_state:t().
+top_level_install(State) ->
+ Profiles = rebar_state:current_profiles(State),
+ lists:foldl(fun(Profile, StateAcc) ->
+ Plugins = rebar_state:get(State, {plugins, Profile}, []),
+ handle_plugins(Profile, Plugins, StateAcc)
+ end, State, Profiles).
+
-spec project_apps_install(rebar_state:t()) -> rebar_state:t().
project_apps_install(State) ->
Profiles = rebar_state:current_profiles(State),
ProjectApps = rebar_state:project_apps(State),
-
lists:foldl(fun(Profile, StateAcc) ->
Plugins = rebar_state:get(State, {plugins, Profile}, []),
StateAcc1 = handle_plugins(Profile, Plugins, StateAcc),
diff --git a/src/rebar_prv_app_discovery.erl b/src/rebar_prv_app_discovery.erl
index 5449f82..1954214 100644
--- a/src/rebar_prv_app_discovery.erl
+++ b/src/rebar_prv_app_discovery.erl
@@ -36,7 +36,8 @@ do(State) ->
LibDirs = rebar_dir:lib_dirs(State),
try
State1 = rebar_app_discover:do(State, LibDirs),
- {ok, State1}
+ State2 = rebar_plugins:project_apps_install(State1),
+ {ok, State2}
catch
throw:{error, {rebar_packages, Error}} ->
{error, {rebar_packages, Error}};
diff --git a/src/rebar_prv_compile.erl b/src/rebar_prv_compile.erl
index d57b82b..30af90b 100644
--- a/src/rebar_prv_compile.erl
+++ b/src/rebar_prv_compile.erl
@@ -247,6 +247,21 @@ resolve_src_dirs(Opts) ->
%% in src_dirs also exist in extra_src_dirs
normalize_src_dirs(SrcDirs, ExtraDirs) ->
S = lists:usort(SrcDirs),
- E = lists:usort(ExtraDirs),
- {S, lists:subtract(E, S)}.
+ E = lists:subtract(lists:usort(ExtraDirs), S),
+ ok = warn_on_problematic_directories(S ++ E),
+ {S, E}.
+
+%% warn when directories called `eunit' and `ct' are added to compile dirs
+warn_on_problematic_directories(AllDirs) ->
+ F = fun(Dir) ->
+ case is_a_problem(Dir) of
+ true -> ?WARN("Possible name clash with directory ~p.", [Dir]);
+ false -> ok
+ end
+ end,
+ lists:foreach(F, AllDirs).
+
+is_a_problem("eunit") -> true;
+is_a_problem("common_test") -> true;
+is_a_problem(_) -> false.
diff --git a/src/rebar_prv_install_deps.erl b/src/rebar_prv_install_deps.erl
index 118d799..a484c5f 100644
--- a/src/rebar_prv_install_deps.erl
+++ b/src/rebar_prv_install_deps.erl
@@ -251,13 +251,12 @@ update_unseen_dep(AppInfo, Profile, Level, Deps, Apps, State, Upgrade, Seen, Loc
-spec handle_dep(rebar_state:t(), atom(), file:filename_all(), rebar_app_info:t(), list(), integer()) -> {rebar_app_info:t(), [rebar_app_info:t()], rebar_state:t()}.
handle_dep(State, Profile, DepsDir, AppInfo, Locks, Level) ->
- Profiles = rebar_state:current_profiles(State),
Name = rebar_app_info:name(AppInfo),
C = rebar_config:consult(rebar_app_info:dir(AppInfo)),
AppInfo0 = rebar_app_info:update_opts(AppInfo, rebar_app_info:opts(AppInfo), C),
AppInfo1 = rebar_app_info:apply_overrides(rebar_app_info:get(AppInfo, overrides, []), AppInfo0),
- AppInfo2 = rebar_app_info:apply_profiles(AppInfo1, Profiles),
+ AppInfo2 = rebar_app_info:apply_profiles(AppInfo1, [default, prod]),
Plugins = rebar_app_info:get(AppInfo2, plugins, []),
AppInfo3 = rebar_app_info:set(AppInfo2, {plugins, Profile}, Plugins),
@@ -269,7 +268,7 @@ handle_dep(State, Profile, DepsDir, AppInfo, Locks, Level) ->
State1 = rebar_plugins:install(State, AppInfo3),
%% Upgrade lock level to be the level the dep will have in this dep tree
- Deps = rebar_app_info:get(AppInfo3, {deps, default}, []),
+ Deps = rebar_app_info:get(AppInfo3, {deps, default}, []) ++ rebar_app_info:get(AppInfo3, {deps, prod}, []),
AppInfo4 = rebar_app_info:deps(AppInfo3, rebar_state:deps_names(Deps)),
%% Keep all overrides from the global config and this dep when parsing its deps
diff --git a/src/rebar_relx.erl b/src/rebar_relx.erl
index cb8fac5..5d29258 100644
--- a/src/rebar_relx.erl
+++ b/src/rebar_relx.erl
@@ -30,8 +30,9 @@ do(Module, Command, Provider, State) ->
relx:main([{lib_dirs, LibDirs}
,{caller, api} | output_dir(OutputDir, Options)], AllOptions);
Config ->
+ Config1 = merge_overlays(Config),
relx:main([{lib_dirs, LibDirs}
- ,{config, Config}
+ ,{config, Config1}
,{caller, api} | output_dir(OutputDir, Options)], AllOptions)
end,
rebar_hooks:run_all_hooks(Cwd, post, Provider, Providers, State),
@@ -49,3 +50,12 @@ format_error(Reason) ->
output_dir(OutputDir, Options) ->
[{output_dir, OutputDir} || not(lists:member("-o", Options))
andalso not(lists:member("--output-dir", Options))].
+
+merge_overlays(Config) ->
+ {Overlays, Others} =
+ lists:partition(fun(C) when element(1, C) =:= overlay -> true;
+ (_) -> false
+ end, Config),
+ %% Have profile overlay entries come before others to match how profiles work elsewhere
+ NewOverlay = lists:reverse(lists:flatmap(fun({overlay, Overlay}) -> Overlay end, Overlays)),
+ [{overlay, NewOverlay} | Others].
diff --git a/src/rebar_templater.erl b/src/rebar_templater.erl
index f687637..2f33bfc 100644
--- a/src/rebar_templater.erl
+++ b/src/rebar_templater.erl
@@ -159,9 +159,34 @@ drop_var_docs([{K,V}|Rest]) -> [{K,V} | drop_var_docs(Rest)].
create({Template, Type, File}, Files, UserVars, Force, State) ->
TemplateTerms = consult(load_file(Files, Type, File)),
Vars = drop_var_docs(override_vars(UserVars, get_template_vars(TemplateTerms, State))),
+ maybe_warn_about_name(Vars),
TemplateCwd = filename:dirname(File),
execute_template(TemplateTerms, Files, {Template, Type, TemplateCwd}, Vars, Force).
+maybe_warn_about_name(Vars) ->
+ Name = proplists:get_value(name, Vars, "valid"),
+ case validate_atom(Name) of
+ invalid ->
+ ?WARN("The 'name' variable is often associated with Erlang "
+ "module names and/or file names. The value submitted "
+ "(~s) isn't an unquoted Erlang atom. Templates "
+ "generated may contain errors.",
+ [Name]);
+ valid ->
+ ok
+ end.
+
+validate_atom(Str) ->
+ case io_lib:fread("~a", unicode:characters_to_list(Str)) of
+ {ok, [Atom], ""} ->
+ case io_lib:write_atom(Atom) of
+ "'" ++ _ -> invalid; % quoted
+ _ -> valid % unquoted
+ end;
+ _ ->
+ invalid
+ end.
+
%% Run template instructions one at a time.
execute_template([], _, {Template,_,_}, _, _) ->
?DEBUG("Template ~s applied", [Template]),