Merge pull request #587 from lrascao/fix/require_vsn

rebar_require_vsn: Update regexp to account for newer OTP versions
diff --git a/src/rebar_require_vsn.erl b/src/rebar_require_vsn.erl
index 5eecf74..684578a 100644
--- a/src/rebar_require_vsn.erl
+++ b/src/rebar_require_vsn.erl
@@ -31,7 +31,8 @@
 -include("rebar.hrl").
 
 -export([compile/2,
-         eunit/2]).
+         eunit/2,
+         version_tuple/1]).
 
 %% for internal use only
 -export([info/2,
@@ -103,12 +104,12 @@
     case rebar_config:get(Config, require_min_otp_vsn, undefined) of
         undefined -> ?DEBUG("Min OTP version unconfigured~n", []);
         MinOtpVsn ->
-            {MinMaj, MinMin} = version_tuple(ShouldAbort, MinOtpVsn,
+            {MinMaj, MinMin, MinPatch} = version_tuple(ShouldAbort, MinOtpVsn,
                                              "configured"),
-            {OtpMaj, OtpMin} = version_tuple(ShouldAbort,
+            {OtpMaj, OtpMin, OtpPatch} = version_tuple(ShouldAbort,
                                              erlang:system_info(otp_release),
                                              "OTP Release"),
-            case {OtpMaj, OtpMin} >= {MinMaj, MinMin} of
+            case {OtpMaj, OtpMin, OtpPatch} >= {MinMaj, MinMin, MinPatch} of
                 true ->
                     ?DEBUG("~s satisfies the requirement for vsn ~s~n",
                            [erlang:system_info(otp_release),
@@ -122,12 +123,17 @@
             end
     end.
 
+version_tuple(OtpRelease) ->
+    version_tuple(keep_going, OtpRelease, "").
+
 version_tuple(ShouldAbort, OtpRelease, Type) ->
-    case re:run(OtpRelease, "R?(\\d+)B?-?(\\d+)?", [{capture, all, list}]) of
+    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)};
+            {list_to_integer(Maj), list_to_integer(Min), 0};
         {match, [_Full, Maj]} ->
-            {list_to_integer(Maj), 0};
+            {list_to_integer(Maj), 0, 0};
         nomatch ->
             maybe_abort(ShouldAbort,
                         "Cannot parse ~s version string: ~s~n",
diff --git a/test/rebar_require_vsn_tests.erl b/test/rebar_require_vsn_tests.erl
index a487586..a934e8e 100644
--- a/test/rebar_require_vsn_tests.erl
+++ b/test/rebar_require_vsn_tests.erl
@@ -8,17 +8,32 @@
 
 version_tuple_test_() ->
     [%% typical cases
-     ?_assert(check("R15B", "eunit") =:= {15, 0}),
-     ?_assert(check("R15B01", "eunit") =:= {15, 1}),
-     ?_assert(check("R15B02", "eunit") =:= {15, 2}),
-     ?_assert(check("R15B03-1", "eunit") =:= {15, 3}),
-     ?_assert(check("R15B03", "eunit") =:= {15, 3}),
-     ?_assert(check("R16B", "eunit") =:= {16, 0}),
-     ?_assert(check("R16B01", "eunit") =:= {16, 1}),
-     ?_assert(check("R16B02", "eunit") =:= {16, 2}),
-     ?_assert(check("R16B03", "eunit") =:= {16, 3}),
-     ?_assert(check("R16B03-1", "eunit") =:= {16, 3}),
-     ?_assert(check("17", "eunit") =:= {17, 0}),
+     ?_assert(check("R14A", "eunit") =:= {14, 0, 0}),
+     ?_assert(check("R14B", "eunit") =:= {14, 0, 0}),
+     ?_assert(check("R14B01", "eunit") =:= {14, 1, 0}),
+     ?_assert(check("R14B02", "eunit") =:= {14, 2, 0}),
+     ?_assert(check("R14B03", "eunit") =:= {14, 3, 0}),
+     ?_assert(check("R14B04", "eunit") =:= {14, 4, 0}),
+     ?_assert(check("R15B", "eunit") =:= {15, 0, 0}),
+     ?_assert(check("R15B01", "eunit") =:= {15, 1, 0}),
+     ?_assert(check("R15B02", "eunit") =:= {15, 2, 0}),
+     ?_assert(check("R15B03-1", "eunit") =:= {15, 3, 1}),
+     ?_assert(check("R15B03", "eunit") =:= {15, 3, 0}),
+     ?_assert(check("R16B", "eunit") =:= {16, 0, 0}),
+     ?_assert(check("R16B01", "eunit") =:= {16, 1, 0}),
+     ?_assert(check("R16B02", "eunit") =:= {16, 2, 0}),
+     ?_assert(check("R16B03", "eunit") =:= {16, 3, 0}),
+     ?_assert(check("R16B03-1", "eunit") =:= {16, 3, 1}),
+     ?_assert(check("17", "eunit") =:= {17, 0, 0}),
+     ?_assert(check("17.0", "eunit") =:= {17, 0, 0}),
+     ?_assert(check("17.1", "eunit") =:= {17, 1, 0}),
+     ?_assert(check("17.3", "eunit") =:= {17, 3, 0}),
+     ?_assert(check("17.4", "eunit") =:= {17, 4, 0}),
+     ?_assert(check("17.5", "eunit") =:= {17, 5, 0}),
+     ?_assert(check("18.0", "eunit") =:= {18, 0, 0}),
+     ?_assert(check("18.1", "eunit") =:= {18, 1, 0}),
+     ?_assert(check("18.2", "eunit") =:= {18, 2, 0}),
+     ?_assert(check("18.2.1", "eunit") =:= {18, 2, 1}),
      %% error cases
      ?_assertException(throw, rebar_abort, check("", "eunit")),
      ?_assertException(throw, rebar_abort, check("abc", "eunit"))