@@ -10,20 +10,74 @@ type VersionSuite struct {
1010var _ = Suite (& VersionSuite {})
1111
1212func (s * VersionSuite ) TestParseVersion (c * C ) {
13- e , u , d := parseVersion ("1.3.4" )
13+ e , u , d , err := parseVersion ("1.3.4" )
1414 c .Check ([]string {e , u , d }, DeepEquals , []string {"" , "1.3.4" , "" })
15+ c .Check (err , Equals , nil )
1516
16- e , u , d = parseVersion ("4:1.3:4" )
17+ e , u , d , err = parseVersion ("4:1.3:4" )
1718 c .Check ([]string {e , u , d }, DeepEquals , []string {"4" , "1.3:4" , "" })
19+ c .Check (err , Equals , nil )
1820
19- e , u , d = parseVersion ("1.3.4-1" )
21+ e , u , d , err = parseVersion ("1.3.4-1" )
2022 c .Check ([]string {e , u , d }, DeepEquals , []string {"" , "1.3.4" , "1" })
23+ c .Check (err , Equals , nil )
2124
22- e , u , d = parseVersion ("1.3-pre4-1" )
23- c .Check ([]string {e , u , d }, DeepEquals , []string {"" , "1.3" , "pre4-1" })
25+ // upstream_version and debian_revision are separated by the LAST
26+ // hyphen, since upstream_version may itself contain hyphens.
27+ e , u , d , err = parseVersion ("1.3-pre4-1" )
28+ c .Check ([]string {e , u , d }, DeepEquals , []string {"" , "1.3-pre4" , "1" })
29+ c .Check (err , Equals , nil )
2430
25- e , u , d = parseVersion ("4:1.3-pre4-1" )
26- c .Check ([]string {e , u , d }, DeepEquals , []string {"4" , "1.3" , "pre4-1" })
31+ e , u , d , err = parseVersion ("4:1.3-pre4-1" )
32+ c .Check ([]string {e , u , d }, DeepEquals , []string {"4" , "1.3-pre4" , "1" })
33+ c .Check (err , Equals , nil )
34+
35+ e , u , d , err = parseVersion ("1:2026.07.07-0325-54-a773b756" )
36+ c .Check ([]string {e , u , d }, DeepEquals , []string {"1" , "2026.07.07-0325-54" , "a773b756" })
37+ c .Check (err , Equals , nil )
38+
39+ e , u , d , err = parseVersion ("1:1.2024-" )
40+ c .Check ([]string {e , u , d }, DeepEquals , []string {"" , "" , "" })
41+ c .Check (err .Error (), Equals , "could not parse version: version string ('1.2024-') includes hyphen without Debian revision" )
42+ }
43+
44+ func (s * VersionSuite ) TestIsValidVersion (c * C ) {
45+ // valid cases
46+ valid := isValidVersion ("1.2.3-abc" )
47+ c .Check (valid , Equals , true )
48+
49+ valid = isValidVersion ("1.0.1337~rc2-3" )
50+ c .Check (valid , Equals , true )
51+
52+ valid = isValidVersion ("1.2.3+fdsfgs" )
53+ c .Check (valid , Equals , true )
54+
55+ valid = isValidVersion ("1:2.3~4-5six" )
56+ c .Check (valid , Equals , true )
57+
58+ // upstream_version containing multiple hyphens (e.g. date/build-number/
59+ // git-sha style versioning) is valid as long as it's split on the LAST
60+ // hyphen for the debian_revision.
61+ valid = isValidVersion ("1:2026.07.07-0325-54-a773b756" )
62+ c .Check (valid , Equals , true )
63+
64+ // invalid cases
65+ valid = isValidVersion ("1:1.2.3-" )
66+ c .Check (valid , Equals , false )
67+
68+ valid = isValidVersion ("42:" )
69+ c .Check (valid , Equals , false )
70+
71+ valid = isValidVersion ("1:a.1.2.3~-4" )
72+ c .Check (valid , Equals , false )
73+
74+ // non-numeric epoch
75+ valid = isValidVersion ("abc:1.2.3" )
76+ c .Check (valid , Equals , false )
77+
78+ // valid upstream_version, but debian_revision contains a disallowed character
79+ valid = isValidVersion ("1.2.3-abc!" )
80+ c .Check (valid , Equals , false )
2781}
2882
2983func (s * VersionSuite ) TestCompareLexicographic (c * C ) {
@@ -100,7 +154,16 @@ func (s *VersionSuite) TestCompareVersions(c *C) {
100154 c .Check (CompareVersions ("1.0-133-avc" , "1.0" ), Equals , 1 )
101155
102156 c .Check (CompareVersions ("5.2.0.3" , "5.2.0.283" ), Equals , - 1 )
103- c .Check (CompareVersions ("4.3.5a" , "4.3.5-rc3-1" ), Equals , 1 )
157+ // upstream_version/debian_revision split on the LAST hyphen: "4.3.5-rc3-1"
158+ // is upstream="4.3.5-rc3", debian="1", so it's actually greater than "4.3.5a"
159+ // (confirmed against `dpkg --compare-versions`).
160+ c .Check (CompareVersions ("4.3.5a" , "4.3.5-rc3-1" ), Equals , - 1 )
161+
162+ // version validation happens independent of CompareVersions, so only testing the
163+ // edge case where a package is missing a Debian version during parseVersion
164+ c .Check (CompareVersions ("1:abc~1.2.3-" , "1:1.2.3~abc-good" ), Equals , 2 )
165+ // same edge case, but with the unparsable version as the second argument
166+ c .Check (CompareVersions ("1:1.2.3~abc-good" , "1:abc~1.2.3-" ), Equals , 2 )
104167}
105168
106169func (s * VersionSuite ) TestParseDependency (c * C ) {
0 commit comments