Browse Source

Add functions to validate OTP release in use

In the spirit of Original Rebar's "require_min_otp_vsn", this adds
rebar_utils:check_min_otp_version/1 (taking a string containing the
minimum version) and rebar_utils:check_blacklisted_otp_versions/1
(taking a list of regular expression strings), as well as tests in
rebar_utils_SUITE. They're currently only called by the tests-
how/where to best place calls to them from non-test code needs to be
determined (at which point two corresponding rebar.config keys can be
supported). For example, the version probably shouldn't be enforced when
just running "rebar3 help".
pull/642/head
Derek Brown 10 years ago
committed by Tristan Sloughter
parent
commit
04fedc7422
2 changed files with 95 additions and 2 deletions
  1. +45
    -1
      src/rebar_utils.erl
  2. +50
    -1
      test/rebar_utils_SUITE.erl

+ 45
- 1
src/rebar_utils.erl View File

@ -60,7 +60,9 @@
set_httpc_options/0, set_httpc_options/0,
escape_chars/1, escape_chars/1,
escape_double_quotes/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 %% for internal use only
-export([otp_release/0]). -export([otp_release/0]).
@ -299,10 +301,52 @@ line_count(PatchLines) ->
Tokenized = string:tokens(PatchLines, "\n"), Tokenized = string:tokens(PatchLines, "\n"),
{ok, length(Tokenized)}. {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(),
{MinMajor, MinMinor} = split_version(MinOtpVersion),
{OtpMajor, OtpMinor} = split_version(OtpRelease),
case {OtpMajor, OtpMinor} >= {MinMajor, MinMinor} of
true ->
?DEBUG("~s satisfies the requirement for minimum OTP version ~s",
[OtpRelease, MinOtpVersion]);
false ->
?ABORT("OTP release ~s or later is required. Verion 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 %% Internal functions
%% ==================================================================== %% ====================================================================
split_version(Version) ->
list_to_tuple(lists:map(
fun(S) -> list_to_integer(S) end,
string:tokens(Version, "."))).
otp_release() -> otp_release() ->
otp_release1(erlang:system_info(otp_release)). otp_release1(erlang:system_info(otp_release)).

+ 50
- 1
test/rebar_utils_SUITE.erl View File

@ -1,6 +1,8 @@
-module(rebar_utils_SUITE). -module(rebar_utils_SUITE).
-export([all/0, -export([all/0,
init_per_testcase/2,
end_per_testcase/2,
groups/0, groups/0,
init_per_group/2, init_per_group/2,
end_per_group/2, end_per_group/2,
@ -22,12 +24,22 @@
task_with_flag_with_commas/1, task_with_flag_with_commas/1,
task_with_multiple_flags/1, task_with_multiple_flags/1,
special_task_do/1, special_task_do/1,
valid_otp_version/1,
valid_otp_version_equal/1,
invalid_otp_version/1,
nonblacklisted_otp_version/1,
blacklisted_otp_version/1,
sh_does_not_miss_messages/1]). sh_does_not_miss_messages/1]).
-include_lib("common_test/include/ct.hrl"). -include_lib("common_test/include/ct.hrl").
-include_lib("eunit/include/eunit.hrl"). -include_lib("eunit/include/eunit.hrl").
-include_lib("kernel/include/file.hrl"). -include_lib("kernel/include/file.hrl").
init_per_testcase(_, Config) ->
rebar_test_utils:init_rebar_state(Config).
end_per_testcase(_, _Config) ->
catch meck:unload().
all() -> all() ->
[{group, args_to_tasks}, [{group, args_to_tasks},
@ -51,7 +63,13 @@ groups() ->
task_with_flag_with_trailing_comma, task_with_flag_with_trailing_comma,
task_with_flag_with_commas, task_with_flag_with_commas,
task_with_multiple_flags, task_with_multiple_flags,
special_task_do]}].
special_task_do,
valid_otp_version,
valid_otp_version_equal,
invalid_otp_version,
nonblacklisted_otp_version,
blacklisted_otp_version
]}].
init_per_group(_, Config) -> Config. init_per_group(_, Config) -> Config.
end_per_group(_, Config) -> Config. end_per_group(_, Config) -> Config.
@ -120,6 +138,37 @@ special_task_do(_Config) ->
"do", "do",
"bar,", "bar,",
"baz"]). "baz"]).
valid_otp_version(_Config) ->
meck:new(rebar_utils, [passthrough]),
meck:expect(rebar_utils, otp_release, fun() -> "42.4" end),
rebar_utils:check_min_otp_version("42.3"),
meck:unload(rebar_utils).
valid_otp_version_equal(_Config) ->
meck:new(rebar_utils, [passthrough]),
meck:expect(rebar_utils, otp_release, fun() -> "42.3" end),
rebar_utils:check_min_otp_version("42.3"),
meck:unload(rebar_utils).
invalid_otp_version(_Config) ->
meck:new(rebar_utils, [passthrough]),
meck:expect(rebar_utils, otp_release, fun() -> "17.4" end),
?assertException(throw, rebar_abort, rebar_utils:check_min_otp_version("42.3")),
meck:unload(rebar_utils).
nonblacklisted_otp_version(_Config) ->
meck:new(rebar_utils, [passthrough]),
meck:expect(rebar_utils, otp_release, fun() -> "42.4" end),
rebar_utils:check_blacklisted_otp_versions(["1\\.2", "42\\.3"]),
meck:unload(rebar_utils).
blacklisted_otp_version(_Config) ->
meck:new(rebar_utils, [passthrough]),
meck:expect(rebar_utils, otp_release, fun() -> "42.4" end),
?assertException(throw, rebar_abort, rebar_utils:check_blacklisted_otp_versions(["1\\.2", "42\\.[1-4]"])),
meck:unload(rebar_utils).
sh_does_not_miss_messages(_Config) -> sh_does_not_miss_messages(_Config) ->
Source = "~nmain(_) ->~n io:format(\"donotmissme\").~n", Source = "~nmain(_) ->~n io:format(\"donotmissme\").~n",
file:write_file("do_not_miss_messages", io_lib:format(Source,[])), file:write_file("do_not_miss_messages", io_lib:format(Source,[])),

Loading…
Cancel
Save