From 67bf54d04d332bbff961ab4e8ab730858bcdce7a Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Sun, 1 Nov 2015 13:41:46 -0800 Subject: add an option to soft purge rather than purge old code at the cost of some SASL warnings this prevents rebar3 from terminating processes when reloading their code before running tests --- src/rebar_utils.erl | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src/rebar_utils.erl') diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index d00a46f..ea60e42 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -47,6 +47,7 @@ deprecated/4, indent/1, update_code/1, + update_code/2, remove_from_code_path/1, cleanup_code_path/1, args_to_tasks/1, @@ -644,7 +645,9 @@ indent(Amount) when erlang:is_integer(Amount) -> %% Replace code paths with new paths for existing apps and %% purge code of the old modules from those apps. -update_code(Paths) -> +update_code(Paths) -> update_code(Paths, []). + +update_code(Paths, Opts) -> lists:foreach(fun(Path) -> Name = filename:basename(Path, "/ebin"), App = list_to_atom(Name), @@ -654,19 +657,18 @@ update_code(Paths) -> code:add_patha(Path), ok; {ok, Modules} -> - %% stick rebar ebin dir before purging to prevent - %% inadvertent termination - RebarBin = code:lib_dir(rebar, ebin), - ok = code:stick_dir(RebarBin), %% replace_path causes problems when running %% tests in projects like erlware_commons that rebar3 %% also includes %code:replace_path(App, Path), code:del_path(App), code:add_patha(Path), - [begin code:purge(M), code:delete(M) end || M <- Modules], - %% unstick rebar dir - ok = code:unstick_dir(RebarBin) + case lists:member(soft_purge, Opts) of + true -> + [begin code:soft_purge(M), code:delete(M) end || M <- Modules]; + false -> + [begin code:purge(M), code:delete(M) end || M <- Modules] + end end end, Paths). -- cgit v1.1 From f0876ae8c751b4083eadb81a14d000dcd59eeeb7 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sun, 6 Dec 2015 11:38:15 -0500 Subject: Fix tuple umerging - proper segregation of comparison between tuple terms and non-tuple terms. Guards weren't specific enough and that meant the wrong clauses of guards would be triggered - proper deduplication of entries in the list. An additional N passes are required (we co-opt the reverse step to be more efficient) because while the original lists:umerge easily removes dupes, this is requiring more logic here since `[a,{a,b},{a,b,c},a,{a,b,c}]` is a possible interleaving and we'd want `[a,{a,b},{a,b,c}]` -- comparison of direct neighbours isn't enough. --- src/rebar_utils.erl | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) (limited to 'src/rebar_utils.erl') diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index ea60e42..9fe22ea 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -285,7 +285,18 @@ tup_umerge(NewList, OldList) -> tup_umerge_([], Olds) -> Olds; tup_umerge_([New|News], Olds) -> - lists:reverse(umerge(News, Olds, [], New)). + tup_umerge_dedup_(umerge(News, Olds, [], New), []). + +%% removes 100% identical duplicate elements so that +%% `[a,{a,b},a,{a,c},a]' returns `[a,{a,b},{a,c}]'. +%% Operates on a reverted list that gets reversed as part of this pass +tup_umerge_dedup_([], Acc) -> + Acc; +tup_umerge_dedup_([H|T], Acc) -> + case lists:member(H,T) of + true -> tup_umerge_dedup_(T, Acc); + false -> tup_umerge_dedup_(T, [H|Acc]) + end. tup_find(_Elem, []) -> false; @@ -304,9 +315,9 @@ tup_find(Elem, [_Elem | Elems]) -> %% This is equivalent to umerge2_2 in the stdlib, except we use the expanded %% value/key only to compare umerge(News, [Old|Olds], Merged, Cmp) when element(1, Cmp) == element(1, Old); - element(1, Cmp) == Old; - Cmp == element(1, Old); - Cmp =< Old -> + element(1, Cmp) == Old andalso not is_tuple(Old); + Cmp == element(1, Old) andalso not is_tuple(Cmp); + Cmp =< Old andalso not is_tuple(Cmp) andalso not is_tuple(Old) -> umerge(News, Olds, [Cmp | Merged], Cmp, Old); umerge(News, [Old|Olds], Merged, Cmp) -> umerge(News, Olds, [Old | Merged], Cmp); @@ -320,9 +331,9 @@ umerge(News, [], Merged, Cmp) -> umerge([New|News], Olds, Merged, CmpMerged, Cmp) when CmpMerged == Cmp -> umerge(News, Olds, Merged, New); umerge([New|News], Olds, Merged, _CmpMerged, Cmp) when element(1,New) == element(1, Cmp); - element(1,New) == Cmp; - New == element(1, Cmp); - New =< Cmp -> + element(1,New) == Cmp andalso not is_tuple(Cmp); + New == element(1, Cmp) andalso not is_tuple(New); + New =< Cmp andalso not is_tuple(New) andalso not is_tuple(Cmp) -> umerge(News, Olds, [New | Merged], New, Cmp); umerge([New|News], Olds, Merged, _CmpMerged, Cmp) -> % > umerge(News, Olds, [Cmp | Merged], New); -- cgit v1.1 From 769e14c54253a881992dcfcc2ac0ee3367b9a667 Mon Sep 17 00:00:00 2001 From: Fred Hebert Date: Sun, 6 Dec 2015 19:28:07 -0500 Subject: Actually fix tuple merging. Full rewrite, code should be understandable now. --- src/rebar_utils.erl | 83 ++++++++++++++++++++++++++++++++++------------------- 1 file changed, 53 insertions(+), 30 deletions(-) (limited to 'src/rebar_utils.erl') diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 9fe22ea..fb651c3 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -285,7 +285,7 @@ tup_umerge(NewList, OldList) -> tup_umerge_([], Olds) -> Olds; tup_umerge_([New|News], Olds) -> - tup_umerge_dedup_(umerge(News, Olds, [], New), []). + tup_umerge_dedup_(umerge(new, News, Olds, [], New), []). %% removes 100% identical duplicate elements so that %% `[a,{a,b},a,{a,c},a]' returns `[a,{a,b},{a,c}]'. @@ -312,35 +312,58 @@ tup_find(Elem, [Elem1 | Elems]) when is_tuple(Elem1) -> tup_find(Elem, [_Elem | Elems]) -> tup_find(Elem, Elems). -%% This is equivalent to umerge2_2 in the stdlib, except we use the expanded -%% value/key only to compare -umerge(News, [Old|Olds], Merged, Cmp) when element(1, Cmp) == element(1, Old); - element(1, Cmp) == Old andalso not is_tuple(Old); - Cmp == element(1, Old) andalso not is_tuple(Cmp); - Cmp =< Old andalso not is_tuple(Cmp) andalso not is_tuple(Old) -> - umerge(News, Olds, [Cmp | Merged], Cmp, Old); -umerge(News, [Old|Olds], Merged, Cmp) -> - umerge(News, Olds, [Old | Merged], Cmp); -umerge(News, [], Merged, Cmp) -> - lists:reverse(News, [Cmp | Merged]). - -%% Similar to stdlib's umerge2_1 in the stdlib, except that when the expanded -%% value/keys compare equal, we check if the element is a full dupe to clear it -%% (like the stdlib function does) or otherwise keep the duplicate around in -%% an order that prioritizes 'New' elements. -umerge([New|News], Olds, Merged, CmpMerged, Cmp) when CmpMerged == Cmp -> - umerge(News, Olds, Merged, New); -umerge([New|News], Olds, Merged, _CmpMerged, Cmp) when element(1,New) == element(1, Cmp); - element(1,New) == Cmp andalso not is_tuple(Cmp); - New == element(1, Cmp) andalso not is_tuple(New); - New =< Cmp andalso not is_tuple(New) andalso not is_tuple(Cmp) -> - umerge(News, Olds, [New | Merged], New, Cmp); -umerge([New|News], Olds, Merged, _CmpMerged, Cmp) -> % > - umerge(News, Olds, [Cmp | Merged], New); -umerge([], Olds, Merged, CmpMerged, Cmp) when CmpMerged == Cmp -> - lists:reverse(Olds, Merged); -umerge([], Olds, Merged, _CmpMerged, Cmp) -> - lists:reverse(Olds, [Cmp | Merged]). +-spec umerge(new|old, News, Olds, Acc, Current) -> Merged when + News :: [term()], + Olds :: [term()], + Acc :: [term()], + Current :: term(), + Merged :: [term()]. +umerge(_, [], [], Acc, Current) -> + [Current | Acc]; +umerge(new, News, [], Acc, Current) -> + %% only news left + lists:reverse(News, [Current|Acc]); +umerge(old, [], Olds, Acc, Current) -> + %% only olds left + lists:reverse(Olds, [Current|Acc]); +umerge(new, News, [Old|Olds], Acc, Current) -> + {Dir, Merged, NewCurrent} = compare({new, Current}, {old, Old}), + umerge(Dir, News, Olds, [Merged|Acc], NewCurrent); +umerge(old, [New|News], Olds, Acc, Current) -> + {Dir, Merged, NewCurrent} = compare({new, New}, {old, Current}), + umerge(Dir, News, Olds, [Merged|Acc], NewCurrent). + +-spec compare({Priority, term()}, {Secondary, term()}) -> + {NextPriority, Merged, Larger} when + Priority :: new | old, + Secondary :: new | old, + NextPriority :: new | old, + Merged :: term(), + Larger :: term(). +compare({Priority, A}, {Secondary, B}) when is_tuple(A), is_tuple(B) -> + KA = element(1,A), + KB = element(1,B), + if KA == KB -> {Secondary, A, B}; + KA < KB -> {Secondary, A, B}; + KA > KB -> {Priority, B, A} + end; +compare({Priority, A}, {Secondary, B}) when not is_tuple(A), not is_tuple(B) -> + if A == B -> {Secondary, A, B}; + A < B -> {Secondary, A, B}; + A > B -> {Priority, B, A} + end; +compare({Priority, A}, {Secondary, B}) when is_tuple(A), not is_tuple(B) -> + KA = element(1,A), + if KA == B -> {Secondary, A, B}; + KA < B -> {Secondary, A, B}; + KA > B -> {Priority, B, A} + end; +compare({Priority, A}, {Secondary, B}) when not is_tuple(A), is_tuple(B) -> + KB = element(1,B), + if A == KB -> {Secondary, A, B}; + A < KB -> {Secondary, A, B}; + A > KB -> {Priority, B, A} + end. %% Implements wc -l functionality used to determine patchcount from git output line_count(PatchLines) -> -- cgit v1.1 From c4c7ca42447e0bbe3b50347d064ce51fb5c4eff7 Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Tue, 17 Nov 2015 10:31:05 -0600 Subject: support temporary cdn change with HEX_CDN os var --- src/rebar_utils.erl | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/rebar_utils.erl') diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index fb651c3..746c57a 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -61,6 +61,7 @@ tup_find/2, line_count/1, set_httpc_options/0, + url_append_path/2, escape_chars/1, escape_double_quotes/1, escape_double_quotes_weak/1, @@ -798,6 +799,15 @@ set_httpc_options(Scheme, Proxy) -> {ok, {_, _, Host, Port, _, _}} = http_uri:parse(Proxy), httpc:set_options([{Scheme, {{Host, Port}, []}}], rebar). +url_append_path(Url, ExtraPath) -> + case http_uri:parse(Url) of + {ok, {Scheme, UserInfo, Host, Port, Path, Query}} -> + {ok, lists:append([atom_to_list(Scheme), "://", UserInfo, Host, ":", integer_to_list(Port), + filename:join(Path, ExtraPath), "?", Query])}; + _ -> + error + end. + %% escape\ as\ a\ shell\? escape_chars(Str) when is_atom(Str) -> escape_chars(atom_to_list(Str)); -- cgit v1.1 From 4e0de56b90b318e580884daf1d8f56ab3944b914 Mon Sep 17 00:00:00 2001 From: alisdair sullivan Date: Wed, 13 Jan 2016 20:39:43 -0800 Subject: check at runtime instead of compile time for presence of `file:list_dir_all/1` this is slower than the compile time check but i guess packaging rebars with repos is still a thing and i think only the eunit and ct providers call it anyways --- src/rebar_utils.erl | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'src/rebar_utils.erl') diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 746c57a..07bf789 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -828,8 +828,11 @@ info_useless(Old, New) -> not lists:member(Name, New)], ok. --ifdef(no_list_dir_all). -list_dir(Dir) -> file:list_dir(Dir). --else. -list_dir(Dir) -> file:list_dir_all(Dir). --endif. +list_dir(Dir) -> + %% `list_dir_all` returns raw files which are unsupported + %% prior to R16 so just fall back to `list_dir` if running + %% on an earlier vm + case erlang:function_exported(file, list_dir_all, 1) of + true -> file:list_dir_all(Dir); + false -> file:list_dir(Dir) + end. -- cgit v1.1 From 9cf84e5379273a49f8e0942d7b2c291c1ee7deba Mon Sep 17 00:00:00 2001 From: Tristan Sloughter Date: Sun, 31 Jan 2016 16:03:39 -0600 Subject: add user-agent to http request headers --- src/rebar_utils.erl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/rebar_utils.erl') diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 07bf789..56a3940 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -68,7 +68,8 @@ check_min_otp_version/1, check_blacklisted_otp_versions/1, info_useless/2, - list_dir/1]). + list_dir/1, + user_agent/0]). %% for internal use only -export([otp_release/0]). @@ -407,6 +408,10 @@ abort_if_blacklisted(BlacklistedRegex, OtpRelease) -> [OtpRelease, BlacklistedRegex]) end. +user_agent() -> + {ok, Vsn} = application:get_key(rebar, vsn), + ?FMT("Rebar/~s (OTP/~s)", [Vsn, otp_release()]). + %% ==================================================================== %% Internal functions %% ==================================================================== -- cgit v1.1