mirror of
https://github.com/aptly-dev/aptly.git
synced 2026-11-12 14:31:02 +00:00
333 lines
11 KiB
Go
333 lines
11 KiB
Go
package deb
|
|
|
|
import (
|
|
. "gopkg.in/check.v1"
|
|
)
|
|
|
|
type VersionSuite struct {
|
|
}
|
|
|
|
var _ = Suite(&VersionSuite{})
|
|
|
|
func (s *VersionSuite) TestParseVersion(c *C) {
|
|
e, u, d, err := parseVersion("1.3.4")
|
|
c.Check([]string{e, u, d}, DeepEquals, []string{"", "1.3.4", ""})
|
|
c.Check(err, Equals, nil)
|
|
|
|
e, u, d, err = parseVersion("4:1.3:4")
|
|
c.Check([]string{e, u, d}, DeepEquals, []string{"4", "1.3:4", ""})
|
|
c.Check(err, Equals, nil)
|
|
|
|
e, u, d, err = parseVersion("1.3.4-1")
|
|
c.Check([]string{e, u, d}, DeepEquals, []string{"", "1.3.4", "1"})
|
|
c.Check(err, Equals, nil)
|
|
|
|
// upstream_version and debian_revision are separated by the LAST
|
|
// hyphen, since upstream_version may itself contain hyphens.
|
|
e, u, d, err = parseVersion("1.3-pre4-1")
|
|
c.Check([]string{e, u, d}, DeepEquals, []string{"", "1.3-pre4", "1"})
|
|
c.Check(err, Equals, nil)
|
|
|
|
e, u, d, err = parseVersion("4:1.3-pre4-1")
|
|
c.Check([]string{e, u, d}, DeepEquals, []string{"4", "1.3-pre4", "1"})
|
|
c.Check(err, Equals, nil)
|
|
|
|
e, u, d, err = parseVersion("1:2026.07.07-0325-54-a773b756")
|
|
c.Check([]string{e, u, d}, DeepEquals, []string{"1", "2026.07.07-0325-54", "a773b756"})
|
|
c.Check(err, Equals, nil)
|
|
|
|
e, u, d, err = parseVersion("1:1.2024-")
|
|
c.Check([]string{e, u, d}, DeepEquals, []string{"", "", ""})
|
|
c.Check(err.Error(), Equals, "could not parse version: version string ('1.2024-') includes hyphen without Debian revision")
|
|
}
|
|
|
|
func (s *VersionSuite) TestIsValidVersion(c *C) {
|
|
// valid cases
|
|
valid := isValidVersion("1.2.3-abc")
|
|
c.Check(valid, Equals, true)
|
|
|
|
valid = isValidVersion("1.0.1337~rc2-3")
|
|
c.Check(valid, Equals, true)
|
|
|
|
valid = isValidVersion("1.2.3+fdsfgs")
|
|
c.Check(valid, Equals, true)
|
|
|
|
valid = isValidVersion("1:2.3~4-5six")
|
|
c.Check(valid, Equals, true)
|
|
|
|
// upstream_version containing multiple hyphens (e.g. date/build-number/
|
|
// git-sha style versioning) is valid as long as it's split on the LAST
|
|
// hyphen for the debian_revision.
|
|
valid = isValidVersion("1:2026.07.07-0325-54-a773b756")
|
|
c.Check(valid, Equals, true)
|
|
|
|
// invalid cases
|
|
valid = isValidVersion("1:1.2.3-")
|
|
c.Check(valid, Equals, false)
|
|
|
|
valid = isValidVersion("42:")
|
|
c.Check(valid, Equals, false)
|
|
|
|
valid = isValidVersion("1:a.1.2.3~-4")
|
|
c.Check(valid, Equals, false)
|
|
|
|
// non-numeric epoch
|
|
valid = isValidVersion("abc:1.2.3")
|
|
c.Check(valid, Equals, false)
|
|
|
|
// valid upstream_version, but debian_revision contains a disallowed character
|
|
valid = isValidVersion("1.2.3-abc!")
|
|
c.Check(valid, Equals, false)
|
|
|
|
e, u, d, err := parseVersion("1.3-pre4-1")
|
|
c.Check(err, IsNil)
|
|
c.Check([]string{e, u, d}, DeepEquals, []string{"", "1.3-pre4", "1"})
|
|
|
|
e, u, d, err = parseVersion("4:1.3-pre4-1")
|
|
c.Check(err, IsNil)
|
|
c.Check([]string{e, u, d}, DeepEquals, []string{"4", "1.3-pre4", "1"})
|
|
}
|
|
|
|
func (s *VersionSuite) TestCompareLexicographic(c *C) {
|
|
c.Check(compareLexicographic("", ""), Equals, 0)
|
|
c.Check(compareLexicographic("pre", "pre"), Equals, 0)
|
|
|
|
c.Check(compareLexicographic("pr", "pre"), Equals, -1)
|
|
c.Check(compareLexicographic("pre", "pr"), Equals, 1)
|
|
|
|
c.Check(compareLexicographic("pra", "prb"), Equals, -1)
|
|
c.Check(compareLexicographic("prb", "pra"), Equals, 1)
|
|
|
|
c.Check(compareLexicographic("prx", "pr+"), Equals, -1)
|
|
c.Check(compareLexicographic("pr+", "prx"), Equals, 1)
|
|
|
|
c.Check(compareLexicographic("pr~", "pra"), Equals, -1)
|
|
c.Check(compareLexicographic("pra", "pr~"), Equals, 1)
|
|
|
|
c.Check(compareLexicographic("~~", "~~a"), Equals, -1)
|
|
c.Check(compareLexicographic("~~a", "~"), Equals, -1)
|
|
c.Check(compareLexicographic("~", ""), Equals, -1)
|
|
|
|
c.Check(compareLexicographic("~~a", "~~"), Equals, 1)
|
|
c.Check(compareLexicographic("~", "~~a"), Equals, 1)
|
|
c.Check(compareLexicographic("", "~"), Equals, 1)
|
|
}
|
|
|
|
func (s *VersionSuite) TestCompareVersionPart(c *C) {
|
|
c.Check(compareVersionPart("", ""), Equals, 0)
|
|
c.Check(compareVersionPart("pre", "pre"), Equals, 0)
|
|
c.Check(compareVersionPart("12", "12"), Equals, 0)
|
|
c.Check(compareVersionPart("1.3.5", "1.3.5"), Equals, 0)
|
|
c.Check(compareVersionPart("1.3.5-pre1", "1.3.5-pre1"), Equals, 0)
|
|
|
|
c.Check(compareVersionPart("1.0~beta1~svn1245", "1.0~beta1"), Equals, -1)
|
|
c.Check(compareVersionPart("1.0~beta1", "1.0"), Equals, -1)
|
|
|
|
c.Check(compareVersionPart("1.0~beta1", "1.0~beta1~svn1245"), Equals, 1)
|
|
c.Check(compareVersionPart("1.0", "1.0~beta1"), Equals, 1)
|
|
|
|
c.Check(compareVersionPart("1.pr", "1.pre"), Equals, -1)
|
|
c.Check(compareVersionPart("1.pre", "1.pr"), Equals, 1)
|
|
|
|
c.Check(compareVersionPart("1.pra", "1.prb"), Equals, -1)
|
|
c.Check(compareVersionPart("1.prb", "1.pra"), Equals, 1)
|
|
|
|
c.Check(compareVersionPart("3.prx", "3.pr+"), Equals, -1)
|
|
c.Check(compareVersionPart("3.pr+", "3.prx"), Equals, 1)
|
|
|
|
c.Check(compareVersionPart("3.pr~", "3.pra"), Equals, -1)
|
|
c.Check(compareVersionPart("3.pra", "3.pr~"), Equals, 1)
|
|
|
|
c.Check(compareVersionPart("2~~", "2~~a"), Equals, -1)
|
|
c.Check(compareVersionPart("2~~a", "2~"), Equals, -1)
|
|
c.Check(compareVersionPart("2~", "2"), Equals, -1)
|
|
|
|
c.Check(compareVersionPart("2~~a", "2~~"), Equals, 1)
|
|
c.Check(compareVersionPart("2~", "2~~a"), Equals, 1)
|
|
c.Check(compareVersionPart("2", "2~"), Equals, 1)
|
|
}
|
|
|
|
func (s *VersionSuite) TestCompareVersions(c *C) {
|
|
check := func(left, right string, expectedCmp int, expectedErr error) {
|
|
cmp, err := CompareVersions(left, right)
|
|
c.Check(cmp, Equals, expectedCmp)
|
|
c.Check(err, Equals, expectedErr)
|
|
}
|
|
|
|
check("3:1.0~beta1~svn1245-1", "3:1.0~beta1~svn1245-1", 0, nil)
|
|
|
|
check("1:1.0~beta1~svn1245-1", "3:1.0~beta1~svn1245-1", -1, nil)
|
|
check("1:1.0~beta1~svn1245-1", "1.0~beta1~svn1245-1", 1, nil)
|
|
check("1.0~beta1~svn1245-1", "1.0~beta1~svn1245-2", -1, nil)
|
|
check("3:1.0~beta1~svn1245-1", "3:1.0~beta1-1", -1, nil)
|
|
|
|
check("1.0~beta1~svn1245", "1.0~beta1", -1, nil)
|
|
check("1.0~beta1", "1.0", -1, nil)
|
|
|
|
check("1.0-133-avc", "1.1", -1, nil)
|
|
check("1.0-133-avc", "1.0", 1, nil)
|
|
|
|
check("5.2.0.3", "5.2.0.283", -1, nil)
|
|
// upstream_version/debian_revision split on the LAST hyphen: "4.3.5-rc3-1"
|
|
// is upstream="4.3.5-rc3", debian="1", so it's actually greater than "4.3.5a"
|
|
// (confirmed against `dpkg --compare-versions`).
|
|
check("4.3.5a", "4.3.5-rc3-1", -1, nil)
|
|
|
|
// Version validation happens independently, so these exercise parse failures.
|
|
check("1:abc~1.2.3-", "1:1.2.3~abc-good", 0, LeftInvalid)
|
|
check("1:1.2.3~abc-good", "1:abc~1.2.3-", 0, RightInvalid)
|
|
check("1:abc~1.2.3-", "2:def~4.5.6-", 0, BothInvalid)
|
|
|
|
// The following tests exercise the last-hyphen split and additional
|
|
// comparison edge cases (added by PR #1646, rebased onto master).
|
|
check("1.6.0-rc1+really1.6.0-0", "1.6.0-rc1-0", 1, nil)
|
|
check("1.2-3-4", "1.2-3-5", -1, nil)
|
|
check("1.0-1-1", "1.0-1", 1, nil)
|
|
check("1.0+1", "1.0", 1, nil)
|
|
check("1.0+a-1", "1.0-a-1", -1, nil)
|
|
check("1.0+1-1", "1.0-1", 1, nil)
|
|
check("1.0-1+b1", "1.0-1", 1, nil)
|
|
check("1.0-1+b1", "1.0-1~bpo1", 1, nil)
|
|
check("1.0-1+b2", "1.0-1+b10", -1, nil)
|
|
check("1.0.1+dfsg-1", "1.0.1-1", 1, nil)
|
|
check("1.0-1+b1", "1.0-2", -1, nil)
|
|
}
|
|
|
|
func (s *VersionSuite) TestParseDependency(c *C) {
|
|
d, e := ParseDependency("dpkg (>= 1.6)")
|
|
c.Check(e, IsNil)
|
|
c.Check(d.Pkg, Equals, "dpkg")
|
|
c.Check(d.Relation, Equals, VersionGreaterOrEqual)
|
|
c.Check(d.Version, Equals, "1.6")
|
|
c.Check(d.Architecture, Equals, "")
|
|
|
|
d, e = ParseDependency("dpkg(>>1.6)")
|
|
c.Check(e, IsNil)
|
|
c.Check(d.Pkg, Equals, "dpkg")
|
|
c.Check(d.Relation, Equals, VersionGreater)
|
|
c.Check(d.Version, Equals, "1.6")
|
|
|
|
d, e = ParseDependency("dpkg(1.6)")
|
|
c.Check(e, IsNil)
|
|
c.Check(d.Pkg, Equals, "dpkg")
|
|
c.Check(d.Relation, Equals, VersionEqual)
|
|
c.Check(d.Version, Equals, "1.6")
|
|
|
|
d, e = ParseDependency("dpkg ( 1.6)")
|
|
c.Check(e, IsNil)
|
|
c.Check(d.Pkg, Equals, "dpkg")
|
|
c.Check(d.Relation, Equals, VersionEqual)
|
|
c.Check(d.Version, Equals, "1.6")
|
|
|
|
d, e = ParseDependency("dpkg (> 1.6)")
|
|
c.Check(e, IsNil)
|
|
c.Check(d.Pkg, Equals, "dpkg")
|
|
c.Check(d.Relation, Equals, VersionGreaterOrEqual)
|
|
c.Check(d.Version, Equals, "1.6")
|
|
|
|
d, e = ParseDependency("dpkg (< 1.6)")
|
|
c.Check(e, IsNil)
|
|
c.Check(d.Pkg, Equals, "dpkg")
|
|
c.Check(d.Relation, Equals, VersionLessOrEqual)
|
|
c.Check(d.Version, Equals, "1.6")
|
|
|
|
d, e = ParseDependency("dpkg (= 1.6)")
|
|
c.Check(e, IsNil)
|
|
c.Check(d.Pkg, Equals, "dpkg")
|
|
c.Check(d.Relation, Equals, VersionEqual)
|
|
c.Check(d.Version, Equals, "1.6")
|
|
|
|
d, e = ParseDependency("dpkg (<< 1.6)")
|
|
c.Check(e, IsNil)
|
|
c.Check(d.Pkg, Equals, "dpkg")
|
|
c.Check(d.Relation, Equals, VersionLess)
|
|
c.Check(d.Version, Equals, "1.6")
|
|
|
|
d, e = ParseDependency("dpkg(>>1.6)")
|
|
c.Check(e, IsNil)
|
|
c.Check(d.Pkg, Equals, "dpkg")
|
|
c.Check(d.Relation, Equals, VersionGreater)
|
|
c.Check(d.Version, Equals, "1.6")
|
|
|
|
d, e = ParseDependency("dpkg (>>1.6) {i386}")
|
|
c.Check(e, IsNil)
|
|
c.Check(d.Pkg, Equals, "dpkg")
|
|
c.Check(d.Relation, Equals, VersionGreater)
|
|
c.Check(d.Version, Equals, "1.6")
|
|
c.Check(d.Architecture, Equals, "i386")
|
|
|
|
d, e = ParseDependency("python:any (>= 2.7~)")
|
|
c.Check(e, IsNil)
|
|
c.Check(d.Pkg, Equals, "python")
|
|
c.Check(d.Relation, Equals, VersionGreaterOrEqual)
|
|
c.Check(d.Version, Equals, "2.7~")
|
|
c.Check(d.Architecture, Equals, "")
|
|
|
|
d, e = ParseDependency("python:amd64 (>= 2.7~)")
|
|
c.Check(e, IsNil)
|
|
c.Check(d.Pkg, Equals, "python")
|
|
c.Check(d.Relation, Equals, VersionGreaterOrEqual)
|
|
c.Check(d.Version, Equals, "2.7~")
|
|
c.Check(d.Architecture, Equals, "amd64")
|
|
|
|
d, e = ParseDependency("dpkg{i386}")
|
|
c.Check(e, IsNil)
|
|
c.Check(d.Pkg, Equals, "dpkg")
|
|
c.Check(d.Relation, Equals, VersionDontCare)
|
|
c.Check(d.Version, Equals, "")
|
|
c.Check(d.Architecture, Equals, "i386")
|
|
|
|
d, e = ParseDependency("dpkg ")
|
|
c.Check(e, IsNil)
|
|
c.Check(d.Pkg, Equals, "dpkg")
|
|
c.Check(d.Relation, Equals, VersionDontCare)
|
|
c.Check(d.Version, Equals, "")
|
|
|
|
d, e = ParseDependency("dpkg(==1.6)")
|
|
c.Check(e, ErrorMatches, "relation unknown.*")
|
|
|
|
d, e = ParseDependency("dpkg==1.6)")
|
|
c.Check(e, ErrorMatches, "unable to parse.*")
|
|
|
|
d, e = ParseDependency("dpkg i386}")
|
|
c.Check(e, ErrorMatches, "unable to parse.*")
|
|
|
|
d, e = ParseDependency("dpkg ) {i386}")
|
|
c.Check(e, ErrorMatches, "unable to parse.*")
|
|
}
|
|
|
|
func (s *VersionSuite) TestParseDependencyVariants(c *C) {
|
|
l, e := ParseDependencyVariants("dpkg (>= 1.6)")
|
|
c.Check(e, IsNil)
|
|
c.Check(l, HasLen, 1)
|
|
c.Check(l[0].Pkg, Equals, "dpkg")
|
|
c.Check(l[0].Relation, Equals, VersionGreaterOrEqual)
|
|
c.Check(l[0].Version, Equals, "1.6")
|
|
|
|
l, e = ParseDependencyVariants("dpkg (>= 1.6) | mailer-agent")
|
|
c.Check(e, IsNil)
|
|
c.Check(l, HasLen, 2)
|
|
c.Check(l[0].Pkg, Equals, "dpkg")
|
|
c.Check(l[0].Relation, Equals, VersionGreaterOrEqual)
|
|
c.Check(l[0].Version, Equals, "1.6")
|
|
c.Check(l[1].Pkg, Equals, "mailer-agent")
|
|
c.Check(l[1].Relation, Equals, VersionDontCare)
|
|
|
|
_, e = ParseDependencyVariants("dpkg(==1.6)")
|
|
c.Check(e, ErrorMatches, "relation unknown.*")
|
|
}
|
|
|
|
func (s *VersionSuite) TestDependencyString(c *C) {
|
|
d, _ := ParseDependency("dpkg(>>1.6)")
|
|
d.Architecture = "i386"
|
|
c.Check(d.String(), Equals, "dpkg (>> 1.6) [i386]")
|
|
|
|
d, _ = ParseDependency("dpkg")
|
|
d.Architecture = "i386"
|
|
c.Check(d.String(), Equals, "dpkg [i386]")
|
|
|
|
d, _ = ParseDependency("dpkg:any")
|
|
c.Check(d.Pkg, Equals, "dpkg")
|
|
c.Check(d.Architecture, Equals, "")
|
|
}
|