From ad7099be6164c428de5b6c227577047dc0fd865e Mon Sep 17 00:00:00 2001 From: "Steven G. Johnson" Date: Fri, 16 Mar 2018 12:47:06 -0400 Subject: [PATCH] prepend leading 0 if needed --- README.md | 14 ++++++++++---- src/VersionParsing.jl | 18 +++++++++--------- test/runtests.jl | 4 +++- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 488477e..ab96f82 100644 --- a/README.md +++ b/README.md @@ -10,12 +10,18 @@ version-number strings into Julia's built-in `VersionNumber` type, via the `vparse(string)` function. Unlike the `VersionNumber(string)` constructor, `vparse(string)` can -handle version-number strings in a much wider range of formats. For example, +handle version-number strings in a much wider range of formats than +are encompassed by the [semver standard](https://semver.org/). This +is useful in order to support `VersionNumber` comparisons applied +to "foreign" version numbers from external packages. + +For example, -* `major.minor.patch[.+-]something[.+-]something` is converted if possible into the - closest `VersionNumber` equivalent (`something` becomes a prerelease - or build identifier). * Non-numeric prefixes are stripped along with any invalid version characters. * Text following whitespace after the version number is ignored. +* `major.minor.patch.x.y.z` is supported, with `x.y.z` prepended to the + semver build identifier, i.e. it is parsed like `major.minor.patch+x.y.z`. +* Multiple `+x+y` build identifiers are concatenated as if they were `+x.y`. +* A leading `0` is prepended if needed, e.g. `.x` is treated as `0.x`. * When all else fails, everything except the first `major.minor.patch` digits found are ignored. diff --git a/src/VersionParsing.jl b/src/VersionParsing.jl index b33ed32..eb0ac9f 100644 --- a/src/VersionParsing.jl +++ b/src/VersionParsing.jl @@ -15,18 +15,17 @@ export vparse vparse(s::AbstractString) Returns a `VersionNumber` representing as much as possible of the version -information in the string `s`. +information in the string `s`. A much wider range of formats is supported +than the semver styles recognized by `VersionNumber(s)`. -Typically, `s` is a string of the form `"major[.minor.patch]"`, but several -variations on this format are supported, including: +For example, -* `major.minor.patch[.+-]something[.+-]something` is converted if possible into the - closest `VersionNumber` equivalent (`something` becomes a prerelease - or build identifier). * Non-numeric prefixes are stripped along with any invalid version characters. * Text following whitespace after the version number is ignored. -* In Debian-style version numbers `epoch:major.minor.patch-rev`, the "epoch" - is ignored and only the upstream version `major.minor.patch-rev` is used. +* `major.minor.patch.x.y.z` is supported, with `x.y.z` prepended to the + semver build identifier, i.e. it is parsed like `major.minor.patch+x.y.z`. +* Multiple `+x+y` build identifiers are concatenated as if they were `+x.y`. +* A leading `0` is prepended if needed, e.g. `.x` is treated as `0.x`. * When all else fails, everything except the first `major.minor.patch` digits found are ignored. """ @@ -36,8 +35,9 @@ digits2num(s::AbstractString) = all(isdigit, s) ? parse(Int, s) : s splitparts(s::AbstractString) = map(digits2num, filter!(!isempty, split(s, '.'))) function vparse(s_::String) - s = replace(s_, r"^\D+"=>"") # strip non-numeric prefix + s = replace(s_, r"^[^0-9.]+"=>"") # strip non-numeric prefix isempty(s) && throw(ArgumentError("non-numeric version string $s_")) + contains(s, r"^\.\d") && (s = "0" * s) # treat .x as 0.x if contains(s, r"^\d:\d+") # debian-style version number s = replace(s, r"^\d:"=>"") # strip epoch end diff --git a/test/runtests.jl b/test/runtests.jl index 7feea47..f07bdbd 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -8,7 +8,7 @@ using Compat.Test # examples from npm docs (https://docs.npmjs.com/misc/semver) @test_throws ArgumentError vparse("a.b.c") @test vparse(" =v1.2.3 ") == v"1.2.3" -@test vparse("v2") == v"2.0.0" +@test vparse("v2") == vparse("version 2.0") == v"2.0.0" @test vparse("42.6.7.9.3-alpha") == v"42.6.7-alpha+9.3" @test vparse("1.2.3.8-4.2") == v"1.2.3-4.2+8" @@ -16,3 +16,5 @@ using Compat.Test # Debian-style epoch:upstream version numbers @test vparse("4:4.7.4-0ubuntu8") == vparse("0:4.7.4-0ubuntu8") == v"4.7.4-0ubuntu8" + +@test vparse(".3") == v"0.3.0"