diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/rebar3.erl | 2 | ||||
-rw-r--r-- | src/rebar_app_utils.erl | 4 | ||||
-rw-r--r-- | src/rebar_file_utils.erl | 16 | ||||
-rw-r--r-- | src/rebar_git_resource.erl | 4 | ||||
-rw-r--r-- | src/rebar_plugins.erl | 12 | ||||
-rw-r--r-- | src/rebar_prv_app_discovery.erl | 3 | ||||
-rw-r--r-- | src/rebar_prv_compile.erl | 19 | ||||
-rw-r--r-- | src/rebar_prv_install_deps.erl | 5 | ||||
-rw-r--r-- | src/rebar_relx.erl | 12 | ||||
-rw-r--r-- | src/rebar_templater.erl | 25 |
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]), |