Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow hyphenated ranges in compatability specs #1410

Merged
merged 1 commit into from
Nov 19, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 57 additions & 4 deletions docs/src/compatibility.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,67 @@ PkgG = "~0" # [0.0.0, 1.0.0)

For all versions with a major version of 0 the tilde and caret specifiers are equivalent.

### Equality specifier

Equality can be used to specify an exact version:

```toml
[compat]
PkgA = "= 1.2.3" # [1.2.3, 1.2.3]
```

### Inequality specifiers

Inequalities can also be used to specify version ranges:

```toml
[compat]
PkgA = ">= 1.2.3" # [1.2.3, ∞)
PkgB = "≥ 1.2.3" # [1.2.3, ∞)
PkgC = "= 1.2.3" # [1.2.3, 1.2.3]
PkgD = "< 1.2.3" # [0.0.0, 1.2.2]
PkgB = ">= 1.2.3" # [1.2.3, ∞)
PkgC = "≥ 1.2.3" # [1.2.3, ∞)
PkgD = "< 1.2.3" # [0.0.0, 1.2.3) = [0.0.0, 1.2.2]
```

### Hyphen specifiers

DilumAluthge marked this conversation as resolved.
Show resolved Hide resolved
!!! compat "Julia 1.4"
Hyphen specifiers requires at least Julia 1.4, so it is recomended to also add
```toml
[compat]
julia = "1.4"
```
to the project file when using them.
Hyphen syntax can also be used to specify version ranges. Make sure that you have a space on both sides of the hyphen.

```toml
[compat]
PkgA = "1.2.3 - 4.5.6" # [1.2.3, 4.5.6]
PkgA = "0.2.3 - 4.5.6" # [0.2.3, 4.5.6]
```

Any unspecified trailing numbers in the first end-point are considered to be zero:

```toml
[compat]
PkgA = "1.2 - 4.5.6" # [1.2.0, 4.5.6]
PkgA = "1 - 4.5.6" # [1.0.0, 4.5.6]
PkgA = "0.2 - 4.5.6" # [0.2.0, 4.5.6]
PkgA = "0.2 - 0.5.6" # [0.2.0, 0.5.6]
```

Any unspecified trailing numbers in the second end-point will be considered to be wildcards:

```toml
[compat]
PkgA = "1.2.3 - 4.5" # 1.2.3 - 4.5.* = [1.2.3, 4.6.0)
PkgA = "1.2.3 - 4" # 1.2.3 - 4.*.* = [1.2.3, 5.0.0)
PkgA = "1.2 - 4.5" # 1.2.0 - 4.5.* = [1.2.0, 4.6.0)
PkgA = "1.2 - 4" # 1.2.0 - 4.*.* = [1.2.0, 5.0.0)
PkgA = "1 - 4.5" # 1.0.0 - 4.5.* = [1.0.0, 4.6.0)
PkgA = "1 - 4" # 1.0.0 - 4.*.* = [1.0.0, 5.0.0)
PkgA = "0.2.3 - 4.5" # 0.2.3 - 4.5.* = [0.2.3, 4.6.0)
PkgA = "0.2.3 - 4" # 0.2.3 - 4.*.* = [0.2.3, 5.0.0)
PkgA = "0.2 - 4.5" # 0.2.0 - 4.5.* = [0.2.0, 4.6.0)
PkgA = "0.2 - 4" # 0.2.0 - 4.*.* = [0.2.0, 5.0.0)
PkgA = "0.2 - 0.5" # 0.2.0 - 0.5.* = [0.2.0, 0.6.0)
PkgA = "0.2 - 0" # 0.2.0 - 0.*.* = [0.2.0, 1.0.0)
```
DilumAluthge marked this conversation as resolved.
Show resolved Hide resolved
31 changes: 30 additions & 1 deletion src/versions.jl
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,9 @@ Base.show(io::IO, s::VersionSpec) = print(io, "VersionSpec(\"", s, "\")")
###################

function semver_spec(s::String)
s = replace(s, " " => "")
s = replace(s, r"\s-\s" => "→") # replace " - " with "→"
s = replace(s, " " => "") # remove all spaces
s = replace(s, "→" => " - ") # replace "→" with " - "
ranges = VersionRange[]
for ver in split(s, ',')
range = nothing
Expand Down Expand Up @@ -343,9 +345,36 @@ function inequality_interval(m::RegexMatch)
end
end

function hyphen_interval(m::RegexMatch)
@assert length(m.captures) == 6
_lower_major, _lower_minor, _lower_patch, _upper_major, _upper_minor, _upper_patch = m.captures
if isnothing(_lower_minor)
lower_bound = VersionBound(parse(Int, _lower_major))
elseif isnothing(_lower_patch)
lower_bound = VersionBound(parse(Int, _lower_major),
parse(Int, _lower_minor))
else
lower_bound = VersionBound(parse(Int, _lower_major),
parse(Int, _lower_minor),
parse(Int, _lower_patch))
end
if isnothing(_upper_minor)
upper_bound = VersionBound(parse(Int, _upper_major))
elseif isnothing(_upper_patch)
upper_bound = VersionBound(parse(Int, _upper_major),
parse(Int, _upper_minor))
else
upper_bound = VersionBound(parse(Int, _upper_major),
parse(Int, _upper_minor),
parse(Int, _upper_patch))
end
return VersionRange(lower_bound, upper_bound)
end

const version = "v?([0-9]+?)(?:\\.([0-9]+?))?(?:\\.([0-9]+?))?"
const ver_regs =
[
Regex("^([~^]?)?$version\$") => semver_interval, # 0.5 ^0.4 ~0.3.2
Regex("^((?:≥)|(?:>=)|(?:=)|(?:<)|(?:=))v?$version\$") => inequality_interval,# < 0.2 >= 0.5,2
Regex("^[\\s]*$version[\\s]*?\\s-\\s[\\s]*?$version[\\s]*\$") => hyphen_interval, # 0.7 - 1.3
]
52 changes: 52 additions & 0 deletions test/pkg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,58 @@ import Pkg.Types: semver_spec, VersionSpec
@test v"1.2.3" in semver_spec(">=1.2.3")
@test !(v"1.2.2" in semver_spec(">=1.2.3"))

@test_throws ErrorException semver_spec("0.1.0-0.2.2")
@test semver_spec("0.1.0 - 0.2.2") == VersionSpec("0.1.0 - 0.2.2")
DilumAluthge marked this conversation as resolved.
Show resolved Hide resolved
@test semver_spec("1.2.3 - 4.5.6") == semver_spec("1.2.3 - 4.5.6") == semver_spec("1.2.3 - 4.5.6") == semver_spec("1.2.3 - 4.5.6")
@test semver_spec("0.0.1 - 0.0.2") == VersionSpec("0.0.1 - 0.0.2")
@test semver_spec("0.0.1 - 0.1.0") == VersionSpec("0.0.1 - 0.1.0")
@test semver_spec("0.0.1 - 0.1") == VersionSpec("0.0.1 - 0.1")
@test semver_spec("0.0.1 - 1") == VersionSpec("0.0.1 - 1")
@test semver_spec("0.1 - 0.2") == VersionSpec("0.1 - 0.2")
@test semver_spec("0.1.0 - 0.2") == VersionSpec("0.1.0 - 0.2")
@test semver_spec("0.1 - 0.2.0") == VersionSpec("0.1 - 0.2.0")
@test semver_spec("0.1.0 - 0.2.0") == VersionSpec("0.1.0 - 0.2.0")
@test semver_spec("0.1.1 - 0.2") == VersionSpec("0.1.1 - 0.2")
@test semver_spec("0.1 - 0.2.1") == VersionSpec("0.1 - 0.2.1")
@test semver_spec("0.1.1 - 0.2.1") == VersionSpec("0.1.1 - 0.2.1")
@test semver_spec("1 - 2") == VersionSpec("1 - 2")
@test semver_spec("1.0 - 2") == VersionSpec("1.0 - 2")
@test semver_spec("1 - 2.0") == VersionSpec("1 - 2.0")
@test semver_spec("1.0 - 2.0") == VersionSpec("1.0 - 2.0")
@test semver_spec("1.0.0 - 2.0") == VersionSpec("1.0.0 - 2.0")
@test semver_spec("1.0 - 2.0.0") == VersionSpec("1.0 - 2.0.0")
@test semver_spec("1.0.0 - 2.0.0") == VersionSpec("1.0.0 - 2.0.0")
@test semver_spec("1.0.1 - 2") == VersionSpec("1.0.1 - 2")
@test semver_spec("1.0.1 - 2.0") == VersionSpec("1.0.1 - 2.0")
@test semver_spec("1.0.1 - 2.0.0") == VersionSpec("1.0.1 - 2.0.0")
@test semver_spec("1.0.1 - 2.0.1") == VersionSpec("1.0.1 - 2.0.1")
@test semver_spec("1.0.1 - 2.1.0") == VersionSpec("1.0.1 - 2.1.0")
@test semver_spec("1.0.1 - 2.1.1") == VersionSpec("1.0.1 - 2.1.1")
@test semver_spec("1.1 - 2") == VersionSpec("1.1 - 2")
@test semver_spec("1.1 - 2.0") == VersionSpec("1.1 - 2.0")
@test semver_spec("1.1 - 2.0.0") == VersionSpec("1.1 - 2.0.0")
@test semver_spec("1.1 - 2.0.1") == VersionSpec("1.1 - 2.0.1")
@test semver_spec("1.1 - 2.1.0") == VersionSpec("1.1 - 2.1.0")
@test semver_spec("1.1 - 2.1.1") == VersionSpec("1.1 - 2.1.1")
@test semver_spec("1.1.0 - 2") == VersionSpec("1.1.0 - 2")
@test semver_spec("1.1.0 - 2.0") == VersionSpec("1.1.0 - 2.0")
@test semver_spec("1.1.0 - 2.0.0") == VersionSpec("1.1.0 - 2.0.0")
@test semver_spec("1.1.0 - 2.0.1") == VersionSpec("1.1.0 - 2.0.1")
@test semver_spec("1.1.0 - 2.1.0") == VersionSpec("1.1.0 - 2.1.0")
@test semver_spec("1.1.0 - 2.1.1") == VersionSpec("1.1.0 - 2.1.1")
@test semver_spec("1.1.1 - 2") == VersionSpec("1.1.1 - 2")
@test semver_spec("1.1.1 - 2.0") == VersionSpec("1.1.1 - 2.0")
@test semver_spec("1.1.1 - 2.0.0") == VersionSpec("1.1.1 - 2.0.0")
@test semver_spec("1.1.1 - 2.0.1") == VersionSpec("1.1.1 - 2.0.1")
@test semver_spec("1.1.1 - 2.1.0") == VersionSpec("1.1.1 - 2.1.0")
@test semver_spec("1.1.1 - 2.1.1") == VersionSpec("1.1.1 - 2.1.1")

@test semver_spec("0.1.0 - 0.2.2, 1.2") == VersionSpec(["0.1.0 - 0.2.2", "1.2.0-1"])
@test semver_spec("0.1.0 - 0.2.2, >=1.2") == VersionSpec(["0.1.0 - 0.2.2", "1.2.0-*"])
@test !(v"0.3" in semver_spec("0.1 - 0.2"))
@test v"0.2.99" in semver_spec("0.1 - 0.2")
@test v"0.3" in semver_spec("0.1 - 0")

@test_throws ErrorException semver_spec("^^0.2.3")
@test_throws ErrorException semver_spec("^^0.2.3.4")
@test_throws ErrorException semver_spec("0.0.0")
Expand Down