Skip to content

Commit

Permalink
prepend leading 0 if needed
Browse files Browse the repository at this point in the history
  • Loading branch information
stevengj committed Mar 16, 2018
1 parent a9e621a commit ad7099b
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 14 deletions.
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
18 changes: 9 additions & 9 deletions src/VersionParsing.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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.
"""
Expand All @@ -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
Expand Down
4 changes: 3 additions & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ 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"
@test vparse("1.2.3.8-4..b2+9.7++2-0") == v"1.2.3-4.b2+8.9.7.2-0"

# 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"

0 comments on commit ad7099b

Please sign in to comment.