diff --git a/debian/version.go b/debian/version.go index 3b8d9e58..f66b3843 100644 --- a/debian/version.go +++ b/debian/version.go @@ -1,6 +1,7 @@ package debian import ( + "fmt" "strconv" "strings" "unicode" @@ -168,3 +169,55 @@ func compareVersionPart(part1, part2 string) int { } return 0 } + +// Version relations +const ( + VersionDontCare = iota + VersionLess + VersionLessOrEqual + VersionEqual + VersionGreaterOrEqual + VersionGreater +) + +// parseDependency parses dependency in format "pkg (>= 1.35)" into parts +func parseDependency(dep string) (pkg string, relation int, version string, err error) { + if !strings.HasSuffix(dep, ")") { + pkg = strings.TrimSpace(dep) + relation = VersionDontCare + return + } + + i := strings.Index(dep, "(") + if i == -1 { + err = fmt.Errorf("unable to parse dependency: %s", dep) + return + } + + pkg = strings.TrimSpace(dep[0:i]) + + rel := dep[i+1 : i+2] + if dep[i+2] == '>' || dep[i+2] == '<' || dep[i+2] == '=' { + rel += dep[i+2 : i+3] + version = strings.TrimSpace(dep[i+3 : len(dep)-1]) + } else { + version = strings.TrimSpace(dep[i+2 : len(dep)-1]) + } + + switch rel { + case "<", "<=": + relation = VersionLessOrEqual + case ">", ">=": + relation = VersionGreaterOrEqual + case "<<": + relation = VersionLess + case ">>": + relation = VersionGreater + case "=": + relation = VersionEqual + default: + err = fmt.Errorf("relation unknown: %s", rel) + } + + return +} diff --git a/debian/version_test.go b/debian/version_test.go index d774016f..2f448678 100644 --- a/debian/version_test.go +++ b/debian/version_test.go @@ -97,3 +97,59 @@ func (s *VersionSuite) TestCompareVersions(c *C) { c.Check(CompareVersions("1.0~beta1~svn1245", "1.0~beta1"), Equals, -1) c.Check(CompareVersions("1.0~beta1", "1.0"), Equals, -1) } + +func (s *VersionSuite) TestParseDependency(c *C) { + p, r, v, e := parseDependency("dpkg (>= 1.6)") + c.Check(e, IsNil) + c.Check(p, Equals, "dpkg") + c.Check(r, Equals, VersionGreaterOrEqual) + c.Check(v, Equals, "1.6") + + p, r, v, e = parseDependency("dpkg(>>1.6)") + c.Check(e, IsNil) + c.Check(p, Equals, "dpkg") + c.Check(r, Equals, VersionGreater) + c.Check(v, Equals, "1.6") + + p, r, v, e = parseDependency("dpkg (> 1.6)") + c.Check(e, IsNil) + c.Check(p, Equals, "dpkg") + c.Check(r, Equals, VersionGreaterOrEqual) + c.Check(v, Equals, "1.6") + + p, r, v, e = parseDependency("dpkg (< 1.6)") + c.Check(e, IsNil) + c.Check(p, Equals, "dpkg") + c.Check(r, Equals, VersionLessOrEqual) + c.Check(v, Equals, "1.6") + + p, r, v, e = parseDependency("dpkg (= 1.6)") + c.Check(e, IsNil) + c.Check(p, Equals, "dpkg") + c.Check(r, Equals, VersionEqual) + c.Check(v, Equals, "1.6") + + p, r, v, e = parseDependency("dpkg (<< 1.6)") + c.Check(e, IsNil) + c.Check(p, Equals, "dpkg") + c.Check(r, Equals, VersionLess) + c.Check(v, Equals, "1.6") + + p, r, v, e = parseDependency("dpkg(>>1.6)") + c.Check(e, IsNil) + c.Check(p, Equals, "dpkg") + c.Check(r, Equals, VersionGreater) + c.Check(v, Equals, "1.6") + + p, r, v, e = parseDependency("dpkg ") + c.Check(e, IsNil) + c.Check(p, Equals, "dpkg") + c.Check(r, Equals, VersionDontCare) + c.Check(v, Equals, "") + + p, r, v, e = parseDependency("dpkg(==1.6)") + c.Check(e, ErrorMatches, "relation unknown.*") + + p, r, v, e = parseDependency("dpkg==1.6)") + c.Check(e, ErrorMatches, "unable to parse.*") +}