Skip to content

Commit

Permalink
semver2 allows hyphens anywhere as alphanumeric; fixed empty and nega…
Browse files Browse the repository at this point in the history
…tive segments
  • Loading branch information
viktor-svub committed Feb 14, 2018
1 parent 38a64a1 commit a4ee610
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 24 deletions.
36 changes: 14 additions & 22 deletions src/Paket.Core/Versioning/SemVer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -200,26 +200,26 @@ module SemVer =
/// Matches if str is convertible to Int and not less than zero, and returns the value as UInt.
let inline private (|Int|_|) str =
match Int32.TryParse (str, NumberStyles.Integer, null) with
| true, num when num > -1 -> Some num
| true, num -> Some num // ALLOW negative as we need to fail
| _ -> None

/// Matches if str is convertible to big int and not less than zero, and returns the bigint value.
let inline private (|Big|_|) str =
match BigInteger.TryParse (str, NumberStyles.Integer, null) with
| true, big when big > -1I -> Some big
| true, big when big > -1I -> Some big // positive, or fallback as prerelease
| _ -> None

/// Splits the given version string by possible delimiters but keeps them as parts of resulting list.
let private expand delimiter (text : string) =
let sb = Text.StringBuilder()
let res = seq {
for ch in text do
for ch in text do // no subsequent delims
match List.contains ch delimiter with
| true ->
| true when sb.Length > 0 ->
yield sb.ToString()
sb.Clear() |> ignore
yield ch.ToString()
| false ->
| _ ->
sb.Append(ch) |> ignore
if sb.Length > 0 then
yield sb.ToString()
Expand All @@ -240,15 +240,7 @@ module SemVer =
/// parse "1.5.0-beta.2" > parse "1.5.0-rc.1" // false
let Parse =
memoize <| fun (version : string) ->
try

/// sanity check to make sure that all of the integers in the string are positive.
/// because we use raw substrings with dashes this is very complex :(
for s in version.Split([|'.'|]) do
match Int32.TryParse s with
| true, s when s < 0 -> failwith "no negatives!"
| _ -> ignore () // non-numeric parts are valid

try // negative numbers are handled diffently for mandatory and optional segments
if version.Contains("!") then
failwithf "Invalid character found in %s" version
if version.Contains("..") then
Expand Down Expand Up @@ -285,15 +277,15 @@ module SemVer =
//| [] | _ -> 0, 0, 0, 0I, []

/// recreate the remaining string to parse as prerelease segments
let prerelease =
let prerelease() =
if suffix.IsEmpty || suffix.Tail.IsEmpty then ""
else String.Concat(suffix.Tail).TrimEnd([|'.'; '-'|])

{ Major = uint32 major
Minor = uint32 minor
Patch = uint32 patch
Build = revision
PreRelease = PreRelease.TryParse prerelease
else String.Concat(suffix.Tail).TrimEnd([|'.'|])
{ Major = Checked.uint32 major
Minor = Checked.uint32 minor
Patch = Checked.uint32 patch
Build = revision // unchecked: positive or pre
PreRelease = PreRelease.TryParse (prerelease())
BuildMetaData = buildmeta
Original = Some version }

Expand Down
16 changes: 14 additions & 2 deletions tests/Paket.Tests/Versioning/SemVerSpecs.fs
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,20 @@ let ``can normalize versions``() =
(SemVer.Parse "1.2.3-alpha.3").Normalize() |> shouldEqual ((SemVer.Parse "1.2.3-alpha.3").ToString())
(SemVer.Parse "1.0.0-alpha").Normalize() |> shouldEqual ((SemVer.Parse "1.0.0-alpha").ToString())
(SemVer.Parse "1.0.0-alpha.1").Normalize() |> shouldEqual ((SemVer.Parse "1.0.0-alpha.1").ToString())
(SemVer.Parse "3.0.0-alpha-0008").Normalize().ToString() |> shouldEqual "3.0.0-alpha-0008"
(SemVer.Parse "3.0.0-alpha123ci-0008").Normalize().ToString() |> shouldEqual "3.0.0-alpha123ci-0008"
(SemVer.Parse "3.0.0-alpha-0008").Normalize() |> shouldEqual "3.0.0-alpha-0008"
(SemVer.Parse "3.0.0-alpha123ci-0008").Normalize() |> shouldEqual "3.0.0-alpha123ci-0008"

[<TestCase("3.0.0--")>][<TestCase("3.0.0---")>]
[<TestCase("3.0.0-.-")>][<TestCase("3.0.0-1-")>]
[<TestCase("3.0.0-rc-")>][<TestCase("3.0.0-rc1")>]
[<TestCase("3.0.0-rc-1")>][<TestCase("3.0.0-rc1-")>]
[<TestCase("3.0.0-rc.1")>][<TestCase("3.0.0-1.rc")>]
[<TestCase("3.0.0-rc.1-")>][<TestCase("3.0.0-1.rc-")>]
[<TestCase("3.0.0-rc.-1-")>][<TestCase("3.0.0-1-.rc-")>]
[<TestCase("3.0.0-rc.-1.1")>][<TestCase("3.0.0-1-.rc.1")>]
[<TestCase("3.0.0-rc.-1.1-")>][<TestCase("3.0.0-1-.rc.-1")>]
let ``can normalize semver prereleases`` version =
(SemVer.Parse version).Normalize() |> shouldEqual version

[<Test>]
let ``can normalize build zeros``() =
Expand Down

0 comments on commit a4ee610

Please sign in to comment.