diff options
Diffstat (limited to 'src/rebar_utils.erl')
-rw-r--r-- | src/rebar_utils.erl | 69 |
1 files changed, 68 insertions, 1 deletions
diff --git a/src/rebar_utils.erl b/src/rebar_utils.erl index 6eb4f4b..c729b58 100644 --- a/src/rebar_utils.erl +++ b/src/rebar_utils.erl @@ -56,11 +56,14 @@ wordsize/0, tup_umerge/2, tup_sort/1, + tup_find/2, line_count/1, set_httpc_options/0, escape_chars/1, escape_double_quotes/1, - escape_double_quotes_weak/1]). + escape_double_quotes_weak/1, + check_min_otp_version/1, + check_blacklisted_otp_versions/1]). %% for internal use only -export([otp_release/0]). @@ -264,6 +267,20 @@ tup_umerge([], Olds) -> tup_umerge([New|News], Olds) -> lists:reverse(umerge(News, Olds, [], New)). +tup_find(_Elem, []) -> + false; +tup_find(Elem, [Elem | _Elems]) -> + Elem; +tup_find(Elem, [Elem1 | Elems]) when is_tuple(Elem1) -> + case element(1, Elem1) =:= Elem of + true -> + Elem1; + false -> + tup_find(Elem, Elems) + end; +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); @@ -299,9 +316,57 @@ line_count(PatchLines) -> Tokenized = string:tokens(PatchLines, "\n"), {ok, length(Tokenized)}. +check_min_otp_version(undefined) -> + ok; +check_min_otp_version(MinOtpVersion) -> + %% Fully-qualify with ?MODULE so the function can be meck'd in rebar_utils_SUITE + OtpRelease = ?MODULE:otp_release(), + ParsedMin = version_tuple(MinOtpVersion), + ParsedVsn = version_tuple(OtpRelease), + + case ParsedVsn >= ParsedMin of + true -> + ?DEBUG("~s satisfies the requirement for minimum OTP version ~s", + [OtpRelease, MinOtpVersion]); + false -> + ?ABORT("OTP release ~s or later is required. Version in use: ~s", + [MinOtpVersion, OtpRelease]) + end. + +check_blacklisted_otp_versions(undefined) -> + ok; +check_blacklisted_otp_versions(BlacklistedRegexes) -> + %% Fully-qualify with ?MODULE so the function can be meck'd in rebar_utils_SUITE + OtpRelease = ?MODULE:otp_release(), + lists:foreach( + fun(BlacklistedRegex) -> abort_if_blacklisted(BlacklistedRegex, OtpRelease) end, + BlacklistedRegexes). + +abort_if_blacklisted(BlacklistedRegex, OtpRelease) -> + case re:run(OtpRelease, BlacklistedRegex, [{capture, none}]) of + match -> + ?ABORT("OTP release ~s matches blacklisted version ~s", + [OtpRelease, BlacklistedRegex]); + nomatch -> + ?DEBUG("~s does not match blacklisted OTP version ~s", + [OtpRelease, BlacklistedRegex]) + end. + + %% ==================================================================== %% Internal functions %% ==================================================================== +version_tuple(OtpRelease) -> + case re:run(OtpRelease, "R?(\\d+)B?.?-?(\\d+)?.?-?(\\d+)?", [{capture, all, list}]) of + {match, [_Full, Maj, Min, Patch]} -> + {list_to_integer(Maj), list_to_integer(Min), list_to_integer(Patch)}; + {match, [_Full, Maj, Min]} -> + {list_to_integer(Maj), list_to_integer(Min), 0}; + {match, [_Full, Maj]} -> + {list_to_integer(Maj), 0, 0}; + nomatch -> + ?ABORT("Minimum OTP release unable to be parsed: ~s", [OtpRelease]) + end. otp_release() -> otp_release1(erlang:system_info(otp_release)). @@ -689,6 +754,8 @@ set_httpc_options(Scheme, Proxy) -> httpc:set_options([{Scheme, {{Host, Port}, []}}], rebar). %% escape\ as\ a\ shell\? +escape_chars(Str) when is_atom(Str) -> + escape_chars(atom_to_list(Str)); escape_chars(Str) -> re:replace(Str, "([ ()?`!$])", "\\\\&", [global, {return, list}]). |