Browse Source

Replace gopkgbuild with go-srcinfo (#528)

* Prefer vercmp over gopkgbuild

* Replace gopkgbuild with go-srcinfo
Anna 6 years ago
parent
commit
d6b862357d

+ 7 - 7
Gopkg.lock

@@ -3,25 +3,25 @@
 
 [[projects]]
   branch = "master"
-  name = "github.com/jguer/go-alpm"
+  name = "github.com/Morganamilo/go-srcinfo"
   packages = ["."]
-  revision = "1114f773cdfb05f577438f7a0538eccabc9cf012"
+  revision = "368edc79b2c53cd9c065818fd4e65843ef3e9e11"
 
 [[projects]]
   branch = "master"
-  name = "github.com/mikkeloscar/aur"
+  name = "github.com/jguer/go-alpm"
   packages = ["."]
-  revision = "837b260b8e90895c45737e2e72313fe5bce6f2c4"
+  revision = "1114f773cdfb05f577438f7a0538eccabc9cf012"
 
 [[projects]]
   branch = "master"
-  name = "github.com/mikkeloscar/gopkgbuild"
+  name = "github.com/mikkeloscar/aur"
   packages = ["."]
-  revision = "2bb4f1f1db67f81fe50f9c1c4ad9db4f20fd6b22"
+  revision = "837b260b8e90895c45737e2e72313fe5bce6f2c4"
 
 [solve-meta]
   analyzer-name = "dep"
   analyzer-version = 1
-  inputs-digest = "456465ee334310996a51a2282bf4cfe9f6269db508479c962474d61a4ce0a08c"
+  inputs-digest = "2a7c6ddb680b62cd3f3cf47a0dfdad617e4a42e29204c75ecf5be3271feda5e1"
   solver-name = "gps-cdcl"
   solver-version = 1

+ 1 - 1
Gopkg.toml

@@ -13,4 +13,4 @@
 
 [[constraint]]
   branch = "master"
-  name = "github.com/mikkeloscar/gopkgbuild"
+  name = "github.com/Morganamilo/go-srcinfo"

+ 0 - 1
depCheck.go

@@ -6,7 +6,6 @@ import (
 	"sync"
 
 	alpm "github.com/jguer/go-alpm"
-	//	gopkg "github.com/mikkeloscar/gopkgbuild"
 )
 
 func (dp *depPool) checkInnerConflict(name string, conflict string, conflicts mapStringSet) {

+ 11 - 15
install.go

@@ -8,9 +8,9 @@ import (
 	"strconv"
 	"strings"
 
+	gosrc "github.com/Morganamilo/go-srcinfo"
 	alpm "github.com/jguer/go-alpm"
 	rpc "github.com/mikkeloscar/aur"
-	gopkg "github.com/mikkeloscar/gopkgbuild"
 )
 
 // Install handles package installs
@@ -25,7 +25,7 @@ func install(parser *arguments) error {
 	warnings := &aurWarnings{}
 
 	removeMake := false
-	srcinfosStale := make(map[string]*gopkg.PKGBUILD)
+	srcinfosStale := make(map[string]*gosrc.Srcinfo)
 
 	//remotenames: names of all non repo packages on the system
 	_, _, localNames, remoteNames, err := filterPackages()
@@ -407,7 +407,7 @@ func install(parser *arguments) error {
 	return nil
 }
 
-func getIncompatible(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD, bases map[string][]*rpc.Pkg) (stringSet, error) {
+func getIncompatible(pkgs []*rpc.Pkg, srcinfos map[string]*gosrc.Srcinfo, bases map[string][]*rpc.Pkg) (stringSet, error) {
 	incompatible := make(stringSet)
 	alpmArch, err := alpmHandle.Arch()
 	if err != nil {
@@ -711,14 +711,14 @@ func editPkgBuilds(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg) error {
 	return nil
 }
 
-func parseSRCINFOFiles(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD, bases map[string][]*rpc.Pkg) error {
+func parseSRCINFOFiles(pkgs []*rpc.Pkg, srcinfos map[string]*gosrc.Srcinfo, bases map[string][]*rpc.Pkg) error {
 	for k, pkg := range pkgs {
 		dir := filepath.Join(config.BuildDir, pkg.PackageBase)
 
 		str := bold(cyan("::") + " Parsing SRCINFO (%d/%d): %s\n")
 		fmt.Printf(str, k+1, len(pkgs), cyan(formatPkgbase(pkg, bases)))
 
-		pkgbuild, err := gopkg.ParseSRCINFO(filepath.Join(dir, ".SRCINFO"))
+		pkgbuild, err := gosrc.ParseFile(filepath.Join(dir, ".SRCINFO"))
 		if err != nil {
 			return fmt.Errorf("%s: %s", pkg.Name, err)
 		}
@@ -729,14 +729,14 @@ func parseSRCINFOFiles(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD, bas
 	return nil
 }
 
-func tryParsesrcinfosFile(pkgs []*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD, bases map[string][]*rpc.Pkg) {
+func tryParsesrcinfosFile(pkgs []*rpc.Pkg, srcinfos map[string]*gosrc.Srcinfo, bases map[string][]*rpc.Pkg) {
 	for k, pkg := range pkgs {
 		dir := filepath.Join(config.BuildDir, pkg.PackageBase)
 
 		str := bold(cyan("::") + " Parsing SRCINFO (%d/%d): %s\n")
 		fmt.Printf(str, k+1, len(pkgs), cyan(formatPkgbase(pkg, bases)))
 
-		pkgbuild, err := gopkg.ParseSRCINFO(filepath.Join(dir, ".SRCINFO"))
+		pkgbuild, err := gosrc.ParseFile(filepath.Join(dir, ".SRCINFO"))
 		if err != nil {
 			fmt.Printf("cannot parse %s skipping: %s\n", pkg.Name, err)
 			continue
@@ -752,15 +752,11 @@ func pkgBuildsToSkip(pkgs []*rpc.Pkg, targets stringSet) stringSet {
 	for _, pkg := range pkgs {
 		if config.ReDownload == "no" || (config.ReDownload == "yes" && !targets.get(pkg.Name)) {
 			dir := filepath.Join(config.BuildDir, pkg.PackageBase, ".SRCINFO")
-			pkgbuild, err := gopkg.ParseSRCINFO(dir)
+			pkgbuild, err := gosrc.ParseFile(dir)
 
 			if err == nil {
-				versionRPC, errR := gopkg.NewCompleteVersion(pkg.Version)
-				versionPKG, errP := gopkg.NewCompleteVersion(pkgbuild.Version())
-				if errP == nil && errR == nil {
-					if !versionRPC.Newer(versionPKG) {
-						toSkip.set(pkg.PackageBase)
-					}
+				if alpm.VerCmp(pkgbuild.Version(), pkg.Version) > 0 {
+					toSkip.set(pkg.PackageBase)
 				}
 			}
 		}
@@ -833,7 +829,7 @@ func downloadPkgBuildsSources(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, inco
 	return
 }
 
-func buildInstallPkgBuilds(dp *depPool, do *depOrder, srcinfos map[string]*gopkg.PKGBUILD, parser *arguments, incompatible stringSet, conflicts mapStringSet) error {
+func buildInstallPkgBuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc.Srcinfo, parser *arguments, incompatible stringSet, conflicts mapStringSet) error {
 	for _, pkg := range do.Aur {
 		dir := filepath.Join(config.BuildDir, pkg.PackageBase)
 		built := true

+ 3 - 3
keys.go

@@ -7,8 +7,8 @@ import (
 	"os/exec"
 	"strings"
 
+	gosrc "github.com/Morganamilo/go-srcinfo"
 	rpc "github.com/mikkeloscar/aur"
-	gopkg "github.com/mikkeloscar/gopkgbuild"
 )
 
 // pgpKeySet maps a PGP key with a list of PKGBUILDs that require it.
@@ -41,7 +41,7 @@ func (set pgpKeySet) get(key string) bool {
 
 // checkPgpKeys iterates through the keys listed in the PKGBUILDs and if needed,
 // asks the user whether yay should try to import them.
-func checkPgpKeys(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, srcinfos map[string]*gopkg.PKGBUILD) error {
+func checkPgpKeys(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, srcinfos map[string]*gosrc.Srcinfo) error {
 	// Let's check the keys individually, and then we can offer to import
 	// the problematic ones.
 	problematic := make(pgpKeySet)
@@ -51,7 +51,7 @@ func checkPgpKeys(pkgs []*rpc.Pkg, bases map[string][]*rpc.Pkg, srcinfos map[str
 	for _, pkg := range pkgs {
 		srcinfo := srcinfos[pkg.PackageBase]
 
-		for _, key := range srcinfo.Validpgpkeys {
+		for _, key := range srcinfo.ValidPGPKeys {
 			// If key already marked as problematic, indicate the current
 			// PKGBUILD requires it.
 			if problematic.get(key) {

+ 17 - 9
keys_test.go

@@ -11,8 +11,8 @@ import (
 	"regexp"
 	"testing"
 
+	gosrc "github.com/Morganamilo/go-srcinfo"
 	rpc "github.com/mikkeloscar/aur"
-	gopkg "github.com/mikkeloscar/gopkgbuild"
 )
 
 const (
@@ -124,6 +124,14 @@ func TestImportKeys(t *testing.T) {
 	}
 }
 
+func makeSrcinfo(pkgbase string, pgpkeys ...string) *gosrc.Srcinfo {
+	srcinfo := gosrc.Srcinfo{}
+	srcinfo.Pkgbase = pkgbase
+	srcinfo.ValidPGPKeys = pgpkeys
+
+	return &srcinfo
+}
+
 func TestCheckPgpKeys(t *testing.T) {
 	keyringDir, err := ioutil.TempDir("/tmp", "yay-test-keyring")
 	if err != nil {
@@ -139,7 +147,7 @@ func TestCheckPgpKeys(t *testing.T) {
 
 	casetests := []struct {
 		pkgs      []*rpc.Pkg
-		srcinfos  map[string]*gopkg.PKGBUILD
+		srcinfos  map[string]*gosrc.Srcinfo
 		bases     map[string][]*rpc.Pkg
 		wantError bool
 	}{
@@ -147,7 +155,7 @@ func TestCheckPgpKeys(t *testing.T) {
 		// 487EACC08557AD082088DABA1EB2638FF56C0C53: Dave Reisner.
 		{
 			pkgs:      []*rpc.Pkg{newPkg("cower")},
-			srcinfos:  map[string]*gopkg.PKGBUILD{"cower": {Pkgbase: "cower", Validpgpkeys: []string{"487EACC08557AD082088DABA1EB2638FF56C0C53"}}},
+			srcinfos:  map[string]*gosrc.Srcinfo{"cower": makeSrcinfo("cower", "487EACC08557AD082088DABA1EB2638FF56C0C53")},
 			bases:     map[string][]*rpc.Pkg{"cower": {newPkg("cower")}},
 			wantError: false,
 		},
@@ -156,7 +164,7 @@ func TestCheckPgpKeys(t *testing.T) {
 		// B6C8F98282B944E3B0D5C2530FC3042E345AD05D: Hans Wennborg.
 		{
 			pkgs:      []*rpc.Pkg{newPkg("libc++")},
-			srcinfos:  map[string]*gopkg.PKGBUILD{"libc++": {Pkgbase: "libc++", Validpgpkeys: []string{"11E521D646982372EB577A1F8F0871F202119294", "B6C8F98282B944E3B0D5C2530FC3042E345AD05D"}}},
+			srcinfos:  map[string]*gosrc.Srcinfo{"libc++": makeSrcinfo("libc++", "11E521D646982372EB577A1F8F0871F202119294", "B6C8F98282B944E3B0D5C2530FC3042E345AD05D")},
 			bases:     map[string][]*rpc.Pkg{"libc++": {newPkg("libc++")}},
 			wantError: false,
 		},
@@ -164,7 +172,7 @@ func TestCheckPgpKeys(t *testing.T) {
 		// ABAF11C65A2970B130ABE3C479BE3E4300411886: Linus Torvalds.
 		{
 			pkgs:      []*rpc.Pkg{newPkg("dummy-1"), newPkg("dummy-2")},
-			srcinfos:  map[string]*gopkg.PKGBUILD{"dummy-1": {Pkgbase: "dummy-1", Validpgpkeys: []string{"ABAF11C65A2970B130ABE3C479BE3E4300411886"}}, "dummy-2": {Pkgbase: "dummy-2", Validpgpkeys: []string{"ABAF11C65A2970B130ABE3C479BE3E4300411886"}}},
+			srcinfos:  map[string]*gosrc.Srcinfo{"dummy-1": makeSrcinfo("dummy-1", "ABAF11C65A2970B130ABE3C479BE3E4300411886"), "dummy-2": makeSrcinfo("dummy-2", "ABAF11C65A2970B130ABE3C479BE3E4300411886")},
 			bases:     map[string][]*rpc.Pkg{"dummy-1": {newPkg("dummy-1")}, "dummy-2": {newPkg("dummy-2")}},
 			wantError: false,
 		},
@@ -174,21 +182,21 @@ func TestCheckPgpKeys(t *testing.T) {
 		// C52048C0C0748FEE227D47A2702353E0F7E48EDB: Thomas Dickey.
 		{
 			pkgs:      []*rpc.Pkg{newPkg("dummy-3")},
-			srcinfos:  map[string]*gopkg.PKGBUILD{"dummy-3": {Pkgbase: "dummy-3", Validpgpkeys: []string{"11E521D646982372EB577A1F8F0871F202119294", "C52048C0C0748FEE227D47A2702353E0F7E48EDB"}}},
+			srcinfos:  map[string]*gosrc.Srcinfo{"dummy-3": makeSrcinfo("dummy-3", "11E521D646982372EB577A1F8F0871F202119294", "C52048C0C0748FEE227D47A2702353E0F7E48EDB")},
 			bases:     map[string][]*rpc.Pkg{"dummy-3": {newPkg("dummy-3")}},
 			wantError: false,
 		},
 		// Two dummy packages with existing keys.
 		{
 			pkgs:      []*rpc.Pkg{newPkg("dummy-4"), newPkg("dummy-5")},
-			srcinfos:  map[string]*gopkg.PKGBUILD{"dummy-4": {Pkgbase: "dummy-4", Validpgpkeys: []string{"11E521D646982372EB577A1F8F0871F202119294"}}, "dummy-5": {Pkgbase: "dummy-5", Validpgpkeys: []string{"C52048C0C0748FEE227D47A2702353E0F7E48EDB"}}},
+			srcinfos:  map[string]*gosrc.Srcinfo{"dummy-4": makeSrcinfo("dummy-4", "11E521D646982372EB577A1F8F0871F202119294"), "dummy-5": makeSrcinfo("dummy-5", "C52048C0C0748FEE227D47A2702353E0F7E48EDB")},
 			bases:     map[string][]*rpc.Pkg{"dummy-4": {newPkg("dummy-4")}, "dummy-5": {newPkg("dummy-5")}},
 			wantError: false,
 		},
 		// Dummy package with invalid key, should fail.
 		{
 			pkgs:      []*rpc.Pkg{newPkg("dummy-7")},
-			srcinfos:  map[string]*gopkg.PKGBUILD{"dummy-7": {Pkgbase: "dummy-7", Validpgpkeys: []string{"THIS-SHOULD-FAIL"}}},
+			srcinfos:  map[string]*gosrc.Srcinfo{"dummy-7": makeSrcinfo("dummy-7", "THIS-SHOULD-FAIL")},
 			bases:     map[string][]*rpc.Pkg{"dummy-7": {newPkg("dummy-7")}},
 			wantError: true,
 		},
@@ -196,7 +204,7 @@ func TestCheckPgpKeys(t *testing.T) {
 		// A314827C4E4250A204CE6E13284FC34C8E4B1A25: Thomas Bächler.
 		{
 			pkgs:      []*rpc.Pkg{newPkg("dummy-8")},
-			srcinfos:  map[string]*gopkg.PKGBUILD{"dummy-8": {Pkgbase: "dummy-8", Validpgpkeys: []string{"A314827C4E4250A204CE6E13284FC34C8E4B1A25", "THIS-SHOULD-FAIL"}}},
+			srcinfos:  map[string]*gosrc.Srcinfo{"dummy-8": makeSrcinfo("dummy-8", "A314827C4E4250A204CE6E13284FC34C8E4B1A25", "THIS-SHOULD-FAIL")},
 			bases:     map[string][]*rpc.Pkg{"dummy-8": {newPkg("dummy-8")}},
 			wantError: true,
 		},

+ 30 - 46
upgrade.go

@@ -9,7 +9,6 @@ import (
 
 	alpm "github.com/jguer/go-alpm"
 	rpc "github.com/mikkeloscar/aur"
-	pkgb "github.com/mikkeloscar/gopkgbuild"
 )
 
 // upgrade type describes a system upgrade.
@@ -63,63 +62,48 @@ func (u upSlice) Less(i, j int) bool {
 
 }
 
-func getVersionDiff(oldVersion, newversion string) (left, right string) {
-	old, errOld := pkgb.NewCompleteVersion(oldVersion)
-	new, errNew := pkgb.NewCompleteVersion(newversion)
-
-	if errOld != nil {
-		left = red("Invalid Version")
-	}
-	if errNew != nil {
-		right = red("Invalid Version")
+func getVersionDiff(oldVersion, newVersion string) (left, right string) {
+	if oldVersion == newVersion {
+		return oldVersion, newVersion
 	}
 
-	if errOld == nil && errNew == nil {
-		oldVersion := old.String()
-		newVersion := new.String()
-
-		if oldVersion == newVersion {
-			return oldVersion, newVersion
-		}
-
-		diffPosition := 0
+	diffPosition := 0
 
-		checkWords := func(str string, index int, words ...string) bool {
-			for _, word := range words {
-				wordLength := len(word)
-				nextIndex := index + 1
-				if (index < len(str)-wordLength) &&
-					(str[nextIndex:(nextIndex+wordLength)] == word) {
-					return true
-				}
+	checkWords := func(str string, index int, words ...string) bool {
+		for _, word := range words {
+			wordLength := len(word)
+			nextIndex := index + 1
+			if (index < len(str)-wordLength) &&
+				(str[nextIndex:(nextIndex+wordLength)] == word) {
+				return true
 			}
-			return false
 		}
+		return false
+	}
 
-		for index, char := range oldVersion {
-			charIsSpecial := !(unicode.IsLetter(char) || unicode.IsNumber(char))
+	for index, char := range oldVersion {
+		charIsSpecial := !(unicode.IsLetter(char) || unicode.IsNumber(char))
 
-			if (index >= len(newVersion)) || (char != rune(newVersion[index])) {
-				if charIsSpecial {
-					diffPosition = index
-				}
-				break
+		if (index >= len(newVersion)) || (char != rune(newVersion[index])) {
+			if charIsSpecial {
+				diffPosition = index
 			}
+			break
+		}
 
-			if charIsSpecial ||
-				(((index == len(oldVersion)-1) || (index == len(newVersion)-1)) &&
-					((len(oldVersion) != len(newVersion)) ||
-						(oldVersion[index] == newVersion[index]))) ||
-				checkWords(oldVersion, index, "rc", "pre", "alpha", "beta") {
-				diffPosition = index + 1
-			}
+		if charIsSpecial ||
+			(((index == len(oldVersion)-1) || (index == len(newVersion)-1)) &&
+				((len(oldVersion) != len(newVersion)) ||
+					(oldVersion[index] == newVersion[index]))) ||
+			checkWords(oldVersion, index, "rc", "pre", "alpha", "beta") {
+			diffPosition = index + 1
 		}
+	}
 
-		samePart := oldVersion[0:diffPosition]
+	samePart := oldVersion[0:diffPosition]
 
-		left = samePart + red(oldVersion[diffPosition:])
-		right = samePart + green(newVersion[diffPosition:])
-	}
+	left = samePart + red(oldVersion[diffPosition:])
+	right = samePart + green(newVersion[diffPosition:])
 
 	return
 }

+ 4 - 4
vcs.go

@@ -9,8 +9,8 @@ import (
 	"strings"
 	"time"
 
+	gosrc "github.com/Morganamilo/go-srcinfo"
 	rpc "github.com/mikkeloscar/aur"
-	gopkg "github.com/mikkeloscar/gopkgbuild"
 )
 
 // Info contains the last commit sha of a repo
@@ -25,7 +25,7 @@ type shaInfo struct {
 // createDevelDB forces yay to create a DB of the existing development packages
 func createDevelDB() error {
 	infoMap := make(map[string]*rpc.Pkg)
-	srcinfosStale := make(map[string]*gopkg.PKGBUILD)
+	srcinfosStale := make(map[string]*gosrc.Srcinfo)
 
 	_, _, _, remoteNames, err := filterPackages()
 	if err != nil {
@@ -103,7 +103,7 @@ func parseSource(source string) (url string, branch string, protocols []string)
 	return
 }
 
-func updateVCSData(pkgName string, sources []string) {
+func updateVCSData(pkgName string, sources []gosrc.ArchString) {
 	if savedInfo == nil {
 		savedInfo = make(vcsInfo)
 	}
@@ -111,7 +111,7 @@ func updateVCSData(pkgName string, sources []string) {
 	info := make(shaInfos)
 
 	for _, source := range sources {
-		url, branch, protocols := parseSource(source)
+		url, branch, protocols := parseSource(source.Value)
 		if url == "" || branch == "" {
 			continue
 		}

vendor/github.com/mikkeloscar/gopkgbuild/LICENSE → vendor/github.com/Morganamilo/go-srcinfo/LICENSE


+ 38 - 0
vendor/github.com/Morganamilo/go-srcinfo/line_error.go

@@ -0,0 +1,38 @@
+package srcinfo
+
+import (
+	"fmt"
+)
+
+// LineError is an error type that stores the line number at which an error
+// occurred as well the full Line that cased the error and an error string.
+type LineError struct {
+	LineNumber int    // The line number at which the error occurred
+	Line       string // The line that caused the error
+	ErrorStr   string // An error string
+}
+
+// Error Returns an error string in the format:
+// "Line <LineNumber>: <ErrorStr>: <Line>".
+func (le LineError) Error() string {
+	return fmt.Sprintf("Line %d: %s: %s", le.LineNumber, le.ErrorStr, le.Line)
+}
+
+// Error Returns a new LineError
+func Error(LineNumber int, Line string, ErrorStr string) *LineError {
+	return &LineError{
+		LineNumber,
+		Line,
+		ErrorStr,
+	}
+}
+
+// Errorf Returns a new LineError using the same formatting rules as
+// fmt.Printf.
+func Errorf(LineNumber int, Line string, ErrorStr string, args ...interface{}) *LineError {
+	return &LineError{
+		LineNumber,
+		Line,
+		fmt.Sprintf(ErrorStr, args...),
+	}
+}

+ 310 - 0
vendor/github.com/Morganamilo/go-srcinfo/parser.go

@@ -0,0 +1,310 @@
+package srcinfo
+
+import (
+	"fmt"
+	"io/ioutil"
+	"strings"
+)
+
+// parser is used to track our current state as we parse the srcinfo.
+type parser struct {
+	// srcinfo is a Pointer to the Srcinfo we are currently building.
+	srcinfo *Srcinfo
+
+	// seenPkgnames is a set of pkgnames we have seen
+	seenPkgnames map[string]struct{}
+}
+
+func (psr *parser) currentPackage() (*Package, error) {
+	if psr.srcinfo.Pkgbase == "" {
+		return nil, fmt.Errorf("Not in pkgbase or pkgname")
+	} else if len(psr.srcinfo.Packages) == 0 {
+		return &psr.srcinfo.Package, nil
+	} else {
+		return &psr.srcinfo.Packages[len(psr.srcinfo.Packages) - 1], nil
+	}
+}
+
+func (psr *parser) setHeaderOrField(key, value string) error {
+	pkgbase := &psr.srcinfo.PackageBase
+
+	switch key {
+	case "pkgbase":
+		if psr.srcinfo.Pkgbase != "" {
+			return fmt.Errorf("key \"%s\" can not occur after pkgbase or pkgname", key)
+		}
+
+		pkgbase.Pkgbase = value
+		return nil
+	case "pkgname":
+		if psr.srcinfo.Pkgbase == "" {
+			return fmt.Errorf("key \"%s\" can not occur before pkgbase", key)
+		}
+		if _, ok := psr.seenPkgnames[value]; ok {
+			return fmt.Errorf("pkgname \"%s\" can not occur more than once", value)
+		}
+		psr.seenPkgnames[value] = struct{}{}
+
+		psr.srcinfo.Packages = append(psr.srcinfo.Packages, Package{Pkgname: value})
+		return nil
+	}
+
+	if psr.srcinfo.Pkgbase == "" {
+		return fmt.Errorf("key \"%s\" can not occur before pkgbase or pkgname", key)
+	}
+
+	return psr.setField(key, value)
+}
+
+func (psr *parser) setField(archKey, value string) error {
+	pkg, err := psr.currentPackage()
+	if err != nil {
+		return err
+	}
+
+	pkgbase := &psr.srcinfo.PackageBase
+	key, arch := splitArchFromKey(archKey)
+	err = checkArch(psr.srcinfo.Arch, archKey, arch)
+	if err != nil {
+		return err
+	}
+
+	if value == "" {
+		value = EmptyOverride
+	}
+
+	// pkgbase only + not arch dependent
+	found := true
+	switch archKey {
+	case "pkgver":
+		pkgbase.Pkgver = value
+	case "pkgrel":
+		pkgbase.Pkgrel = value
+	case "epoch":
+		pkgbase.Epoch = value
+	case "validpgpkeys":
+		pkgbase.ValidPGPKeys = append(pkgbase.ValidPGPKeys, value)
+	case "noextract":
+		pkgbase.NoExtract = append(pkgbase.NoExtract, value)
+	default:
+		found = false
+	}
+
+	if found {
+		if len(psr.srcinfo.Packages) > 0 {
+			return fmt.Errorf("key \"%s\" can not occur after pkgname", archKey)
+		}
+
+		return nil
+	}
+
+	// pkgbase only + arch dependent
+	found = true
+	switch key {
+	case "source":
+		pkgbase.Source = append(pkgbase.Source, ArchString{arch, value})
+	case "md5sums":
+		pkgbase.MD5Sums = append(pkgbase.MD5Sums, ArchString{arch, value})
+	case "sha1sums":
+		pkgbase.SHA1Sums = append(pkgbase.SHA1Sums, ArchString{arch, value})
+	case "sha224sums":
+		pkgbase.SHA224Sums = append(pkgbase.SHA224Sums, ArchString{arch, value})
+	case "sha256sums":
+		pkgbase.SHA256Sums = append(pkgbase.SHA256Sums, ArchString{arch, value})
+	case "sha384sums":
+		pkgbase.SHA384Sums = append(pkgbase.SHA384Sums, ArchString{arch, value})
+	case "sha512sums":
+		pkgbase.SHA512Sums = append(pkgbase.SHA512Sums, ArchString{arch, value})
+	case "makedepends":
+		pkgbase.MakeDepends = append(pkgbase.MakeDepends, ArchString{arch, value})
+	case "checkdepends":
+		pkgbase.CheckDepends = append(pkgbase.CheckDepends, ArchString{arch, value})
+	default:
+		found = false
+	}
+
+	if found {
+		if len(psr.srcinfo.Packages) > 0 {
+			return fmt.Errorf("key \"%s\" can not occur after pkgname", archKey)
+		}
+
+		return nil
+	}
+
+	// pkgbase or pkgname + not arch dependent
+	found = true
+	switch archKey {
+	case "pkgdesc":
+		pkg.Pkgdesc = value
+	case "url":
+		pkg.URL = value
+	case "license":
+		pkg.License = append(pkg.License, value)
+	case "install":
+		pkg.Install = value
+	case "changelog":
+		pkg.Changelog = value
+	case "groups":
+		pkg.Groups = append(pkg.Groups, value)
+	case "arch":
+		pkg.Arch = append(pkg.Arch, value)
+	case "backup":
+		pkg.Backup = append(pkg.Backup, value)
+	case "options":
+		pkg.Options = append(pkg.Options, value)
+	default:
+		found = false
+	}
+
+	if found {
+		return nil
+	}
+
+	// pkgbase or pkgname + arch dependent
+	switch key {
+	case "depends":
+		pkg.Depends = append(pkg.Depends, ArchString{arch, value})
+	case "optdepends":
+		pkg.OptDepends = append(pkg.OptDepends, ArchString{arch, value})
+	case "conflicts":
+		pkg.Conflicts = append(pkg.Conflicts, ArchString{arch, value})
+	case "provides":
+		pkg.Provides = append(pkg.Provides, ArchString{arch, value})
+	case "replaces":
+		pkg.Replaces = append(pkg.Replaces, ArchString{arch, value})
+	default:
+		return fmt.Errorf("Unknown key: \"%s\"", archKey)
+	}
+
+	return nil
+}
+
+func parse(data string) (*Srcinfo, error) {
+	psr := &parser{
+		&Srcinfo{},
+		make(map[string]struct{}),
+	}
+
+	lines := strings.Split(data, "\n")
+
+	for n, line := range lines {
+		line = strings.TrimSpace(line)
+
+		if line == "" || strings.HasPrefix(line, "#") {
+			continue
+		}
+
+		key, value, err := splitPair(line)
+		if err != nil {
+			return nil, Error(n+1, line, err.Error())
+		}
+
+		err = psr.setHeaderOrField(key, value)
+		if err != nil {
+			return nil, Error(n+1, line, err.Error())
+		}
+	}
+
+	if psr.srcinfo.Pkgbase == "" {
+		return nil, fmt.Errorf("No pkgbase field")
+	}
+
+	if len(psr.srcinfo.Packages) == 0 {
+		return nil, fmt.Errorf("No pkgname field")
+	}
+
+	if psr.srcinfo.Pkgver == "" {
+		return nil, fmt.Errorf("No pkgver field")
+	}
+
+	if psr.srcinfo.Pkgrel == "" {
+		return nil, fmt.Errorf("No pkgrel field")
+	}
+
+	if len(psr.srcinfo.Arch) == 0 {
+		return nil, fmt.Errorf("No arch field")
+	}
+
+	return psr.srcinfo, nil
+}
+
+// splitPair splits a key value string in the form of "key = value",
+// whitespace being ignored. The key and the value is returned.
+func splitPair(line string) (string, string, error) {
+	split := strings.SplitN(line, "=", 2)
+
+	if len(split) != 2 {
+		return "", "", fmt.Errorf("Line does not contain =")
+	}
+
+	key := strings.TrimSpace(split[0])
+	value := strings.TrimSpace(split[1])
+
+	if key == "" {
+		return "", "", fmt.Errorf("Key is empty")
+	}
+
+	return key, value, nil
+}
+
+// splitArchFromKey splits up architecture dependent field names, separating
+// the field name from the architecture they depend on.
+func splitArchFromKey(key string) (string, string) {
+	split := strings.SplitN(key, "_", 2)
+	if len(split) == 2 {
+		return split[0], split[1]
+	}
+
+	return split[0], ""
+}
+
+// checkArg checks that the arch from an arch dependent string is actually
+// defined inside of the srcinfo and speicifly disallows the arch "any" as it
+// is not a real arch
+func checkArch(arches []string, key string, arch string) error {
+	if arch == "" {
+		return nil
+	}
+
+	if arch == "any" {
+		return fmt.Errorf("Invalid key \"%s\" arch \"%s\" is not allowed", key, arch)
+	}
+
+	for _, a := range arches {
+		if a == arch {
+			return nil
+		}
+	}
+
+	return fmt.Errorf("Invalid key \"%s\" unsupported arch \"%s\"", key, arch)
+}
+
+// ParseFile parses a srcinfo file as specified by path.
+func ParseFile(path string) (*Srcinfo, error) {
+	file, err := ioutil.ReadFile(path)
+	if err != nil {
+		return nil, fmt.Errorf("Unable to read file: %s: %s", path, err.Error())
+	}
+
+	return Parse(string(file))
+}
+
+// Parse parses a srcinfo in string form. Parsing will fail if:
+//	A srcinfo does not contain all required fields
+//	The same pkgname is specified more then once
+//	arch is missing
+//	pkgver is mising
+//	pkgrel is missing
+//	An architecture specific field is defined for an architecture that does not exist
+//	An unknown key is specified
+//	An empty value is specified
+//
+// Required fields are:
+//	pkgbase
+//	pkname
+//	arch
+//	pkgrel
+//	pkgver
+func Parse(data string) (*Srcinfo, error) {
+	return parse(data)
+}

+ 155 - 0
vendor/github.com/Morganamilo/go-srcinfo/printsrcinfo.go

@@ -0,0 +1,155 @@
+package srcinfo
+
+import (
+	"bytes"
+)
+
+func appendHeader(buffer *bytes.Buffer, key string, value string) {
+	if value == "" {
+		return
+	}
+
+	buffer.WriteString(key + " = " + value + "\n")
+}
+
+func appendValue(buffer *bytes.Buffer, key string, value string) {
+	if value == "" {
+		return
+	}
+
+	if value == EmptyOverride {
+		value = ""
+	}
+
+	buffer.WriteString("\t" + key + " = " + value + "\n")
+}
+
+func appendMultiValue(buffer *bytes.Buffer, key string, values []string) {
+	for _, value := range values {
+		if value == EmptyOverride {
+			value = ""
+		}
+
+		buffer.WriteString("\t" + key + " = " + value + "\n")
+	}
+}
+
+func appendMultiArchValue(buffer *bytes.Buffer, key string, values []ArchString) {
+	for _, value := range values {
+		if value.Value == EmptyOverride {
+			value.Value = ""
+		}
+
+		if value.Arch == "" {
+			buffer.WriteString("\t" + key + " = " + value.Value + "\n")
+		} else {
+			buffer.WriteString("\t" + key + "_" + value.Arch + " = " + value.Value + "\n")
+		}
+	}
+}
+
+//String generates a string that should be similar to the srcinfo data used to
+//create this Srcinfo struct. Fields will be printed in order and with the same
+//whitespcae rules that `makepkg --printsrcinfo` uses.
+//
+// The order of each global field is as follows:
+//	pkgdesc
+//	pkgver
+//	pkgrel
+//	epoch
+//	url
+//	install
+//	changelog
+//	arch
+//	groups
+//	license
+//	checkdepends
+//	makedepends
+//	depends
+//	optdepends
+//	provides
+//	conflicts
+//	replaces
+//	noextract
+//	options
+//	backup
+//	source
+//	validpgpkeys
+//	md5suns
+//	sha1sums
+//	sha224sums
+//	sha256sums
+//	sha384sums
+//	sha512sums
+//
+// The order of each overwritten field is as follows:
+//	pkgdesc
+//	url
+//	install
+//	changelog
+//	arch
+//	groups
+//	license
+//	checkdepends
+//	depends
+//	optdepends
+//	provides
+//	conflicts
+//	replaces
+//	options
+//	backup
+func (si *Srcinfo) String() string {
+	var buffer bytes.Buffer
+
+	appendHeader(&buffer, "pkgbase", si.Pkgbase)
+
+	appendValue(&buffer, "pkgdesc", si.Pkgdesc)
+	appendValue(&buffer, "pkgver", si.Pkgver)
+	appendValue(&buffer, "pkgrel", si.Pkgrel)
+	appendValue(&buffer, "epoch", si.Epoch)
+	appendValue(&buffer, "url", si.URL)
+	appendValue(&buffer, "install", si.Install)
+	appendValue(&buffer, "changelog", si.Changelog)
+	appendMultiValue(&buffer, "arch", si.Arch)
+	appendMultiValue(&buffer, "groups", si.Groups)
+	appendMultiValue(&buffer, "license", si.License)
+	appendMultiArchValue(&buffer, "checkdepends", si.CheckDepends)
+	appendMultiArchValue(&buffer, "makedepends", si.MakeDepends)
+	appendMultiArchValue(&buffer, "depends", si.Depends)
+	appendMultiArchValue(&buffer, "optdepends", si.OptDepends)
+	appendMultiArchValue(&buffer, "provides", si.Provides)
+	appendMultiArchValue(&buffer, "conflicts", si.Conflicts)
+	appendMultiArchValue(&buffer, "replaces", si.Replaces)
+	appendMultiValue(&buffer, "noextract", si.NoExtract)
+	appendMultiValue(&buffer, "options", si.Options)
+	appendMultiValue(&buffer, "backup", si.Backup)
+	appendMultiValue(&buffer, "validpgpkeys", si.ValidPGPKeys)
+	appendMultiArchValue(&buffer, "source", si.Source)
+	appendMultiArchValue(&buffer, "md5sums", si.MD5Sums)
+	appendMultiArchValue(&buffer, "sha1sums", si.SHA1Sums)
+	appendMultiArchValue(&buffer, "sha224sums", si.SHA224Sums)
+	appendMultiArchValue(&buffer, "sha256sums", si.SHA256Sums)
+	appendMultiArchValue(&buffer, "sha384sums", si.SHA384Sums)
+	appendMultiArchValue(&buffer, "sha512sums", si.SHA512Sums)
+
+	for n, pkg := range si.Packages {
+		appendHeader(&buffer, "\npkgname", si.Packages[n].Pkgname)
+
+		appendValue(&buffer, "pkgdesc", pkg.Pkgdesc)
+		appendValue(&buffer, "url", pkg.URL)
+		appendValue(&buffer, "install", pkg.Install)
+		appendValue(&buffer, "changelog", pkg.Changelog)
+		appendMultiValue(&buffer, "arch", pkg.Arch)
+		appendMultiValue(&buffer, "groups", pkg.Groups)
+		appendMultiValue(&buffer, "license", pkg.License)
+		appendMultiArchValue(&buffer, "depends", pkg.Depends)
+		appendMultiArchValue(&buffer, "optdepends", pkg.OptDepends)
+		appendMultiArchValue(&buffer, "provides", pkg.Provides)
+		appendMultiArchValue(&buffer, "conflicts", pkg.Conflicts)
+		appendMultiArchValue(&buffer, "replaces", pkg.Replaces)
+		appendMultiValue(&buffer, "options", pkg.Options)
+		appendMultiValue(&buffer, "backup", pkg.Backup)
+	}
+
+	return buffer.String()
+}

+ 215 - 0
vendor/github.com/Morganamilo/go-srcinfo/srcinfo.go

@@ -0,0 +1,215 @@
+// Package srcinfo is a parser for srcinfo files. Typically generated by
+// makepkg, part of the pacman package manager.
+//
+// Split packages and architecture dependent fields are fully supported.
+//
+// This Package aimes to parse srcinfos but not interpret them in any way.
+// All values are fundamentally strings, other tools should be used for
+// things such as dependency parsing, validity checking etc.
+package srcinfo
+
+import (
+	"fmt"
+)
+
+// ArchString describes string values that may be architecture dependent.
+// For Example depends_x86_64.
+// If Arch is an empty string then the field is not architecture dependent.
+type ArchString struct {
+	Arch  string // Architecture name
+	Value string // Value
+}
+
+// Package describes the fields of a pkgbuild that may be overwritten by
+// in build_<pkgname> function.
+type Package struct {
+	Pkgname    string
+	Pkgdesc    string
+	Arch       []string
+	URL        string
+	License    []string
+	Groups     []string
+	Depends    []ArchString
+	OptDepends []ArchString
+	Provides   []ArchString
+	Conflicts  []ArchString
+	Replaces   []ArchString
+	Backup     []string
+	Options    []string
+	Install    string
+	Changelog  string
+}
+
+// PackageBase describes the fields of a pkgbuild that may not be overwritten
+// in package_<pkgname> function.
+type PackageBase struct {
+	Pkgbase      string
+	Pkgver       string
+	Pkgrel       string
+	Epoch        string
+	Source       []ArchString
+	ValidPGPKeys []string
+	NoExtract    []string
+	MD5Sums      []ArchString
+	SHA1Sums     []ArchString
+	SHA224Sums   []ArchString
+	SHA256Sums   []ArchString
+	SHA384Sums   []ArchString
+	SHA512Sums   []ArchString
+	MakeDepends  []ArchString
+	CheckDepends []ArchString
+}
+
+// Srcinfo represents a full srcinfo. All global fields are defined here while
+// fields overwritten in the package_<pkgname> function are defined in the
+// Packages field.
+//
+// Note: The Packages field only contains the values that each package
+// overrides, global fields will be missing. A Package containing both global
+// and overwritten fields can be generated using the SplitPackage function.
+type Srcinfo struct {
+	PackageBase           // Fields that only apply to the package base
+	Package               // Fields that apply to the package globally
+	Packages    []Package // Fields for each package this package base contains
+}
+
+// EmptyOverride is used to signal when a value has been overridden with an
+// empty value. An empty ovrride is when a value is defined in the pkgbuild but
+// then overridden inside the package function to be empty.
+//
+// For example "pkgdesc=''" is an empty override on the pkgdesc which would
+// lead to the line "pkgdesc=" in the srcinfo.
+//
+// This value is used internally to store empty overrides, mainly to avoid
+// using string pointers. It is possible to check for empty overrides using
+// the Packages slice in Packagebase.
+//
+// During normal use with the SplitPackage function this value will be
+// converted back to an empty string, or removed entirely for slice values.
+// This means the this value can be completley ignored unless you are
+// explicitly looking for empty overrides.
+const EmptyOverride = "\x00"
+
+// Version formats a version string from the epoch, pkgver and pkgrel of the
+// srcinfo. In the format [epoch:]pkgver-pkgrel.
+func (si *Srcinfo) Version() string {
+	if si.Epoch == "" {
+		return si.Pkgver + "-" + si.Pkgrel
+	}
+
+	return si.Epoch + ":" + si.Pkgver + "-" + si.Pkgrel
+}
+
+// SplitPackages generates a splice of all packages that are part of this
+// srcinfo. This is equivalent to calling SplitPackage on every pkgname.
+func (si *Srcinfo) SplitPackages() []*Package {
+	pkgs := make([]*Package, 0, len(si.Packages))
+
+	for _, pkg := range si.Packages {
+		pkgs = append(pkgs, mergeSplitPackage(&si.Package, &pkg))
+	}
+
+	return pkgs
+}
+
+// SplitPackage generates a Package that contains all fields that the specified
+// pkgname has. But will fall back on global fields if they are not defined in
+// the Package.
+//
+// Note slice values will be passed by reference, it is not recommended you
+// modify this struct after it is returned.
+func (si *Srcinfo) SplitPackage(pkgname string) (*Package, error) {
+	for n := range si.Packages {
+		if si.Packages[n].Pkgname == pkgname {
+			return mergeSplitPackage(&si.Package, &si.Packages[n]), nil
+		}
+	}
+
+	return nil, fmt.Errorf("Package \"%s\" is not part of the package base \"%s\"", pkgname, si.Pkgbase)
+}
+
+func mergeArchSlice(global, override []ArchString) []ArchString {
+	overridden := make(map[string]struct{})
+	merged := make([]ArchString, 0, len(override))
+
+	for _, v := range override {
+		overridden[v.Arch] = struct{}{}
+		if v.Value == EmptyOverride {
+			continue
+		}
+		merged = append(merged, v)
+	}
+
+	for _, v := range global {
+		if _, ok := overridden[v.Arch]; !ok {
+			merged = append(merged, v)
+		}
+	}
+
+	return merged
+}
+
+func mergeSplitPackage(base, split *Package) *Package {
+	pkg := &Package{}
+	*pkg = *base
+
+	pkg.Pkgname = split.Pkgname
+
+	if split.Pkgdesc != "" {
+		pkg.Pkgdesc = split.Pkgdesc
+	}
+
+	if len(split.Arch) != 0 {
+		pkg.Arch = split.Arch
+	}
+
+	if split.URL != "" {
+		pkg.URL = split.URL
+	}
+
+	if len(split.License) != 0 {
+		pkg.License = split.License
+	}
+
+	if len(split.Groups) != 0 {
+		pkg.Groups = split.Groups
+	}
+
+	if len(split.Depends) != 0 {
+		pkg.Depends = mergeArchSlice(pkg.Depends, split.Depends)
+	}
+
+	if len(split.OptDepends) != 0 {
+		pkg.OptDepends = mergeArchSlice(pkg.OptDepends, split.OptDepends)
+	}
+
+	if len(split.Provides) != 0 {
+		pkg.Provides = mergeArchSlice(pkg.Provides, split.Provides)
+	}
+
+	if len(split.Conflicts) != 0 {
+		pkg.Conflicts = mergeArchSlice(pkg.Conflicts, split.Conflicts)
+	}
+
+	if len(split.Replaces) != 0 {
+		pkg.Replaces = mergeArchSlice(pkg.Replaces, split.Replaces)
+	}
+
+	if len(split.Backup) != 0 {
+		pkg.Backup = split.Backup
+	}
+
+	if len(split.Options) != 0 {
+		pkg.Options = split.Options
+	}
+
+	if split.Changelog != "" {
+		pkg.Changelog = split.Changelog
+	}
+
+	if split.Install != "" {
+		pkg.Install = split.Install
+	}
+
+	return pkg
+}

+ 0 - 283
vendor/github.com/mikkeloscar/gopkgbuild/lex.go

@@ -1,283 +0,0 @@
-// Copyright 2011 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// based on the lexer from: src/pkg/text/template/parse/lex.go (golang source)
-
-package pkgbuild
-
-import (
-	"fmt"
-	"strings"
-	"unicode"
-	"unicode/utf8"
-)
-
-// pos is a position in input being scanned
-type pos int
-
-type item struct {
-	typ itemType
-	pos pos
-	val string
-}
-
-func (i item) String() string {
-	switch {
-	case i.typ == itemEOF:
-		return "EOF"
-	case i.typ == itemError:
-		return i.val
-	case len(i.val) > 10:
-		return fmt.Sprintf("%.10q...", i.val)
-	}
-	return fmt.Sprintf("%q", i.val)
-}
-
-type itemType int
-
-const (
-	itemError itemType = iota
-	itemEOF
-	itemVariable
-	itemValue
-	itemEndSplit
-	// PKGBUILD variables
-	itemPkgname      // pkgname variable
-	itemPkgver       // pkgver variable
-	itemPkgrel       // pkgrel variable
-	itemPkgdir       // pkgdir variable
-	itemEpoch        // epoch variable
-	itemPkgbase      // pkgbase variable
-	itemPkgdesc      // pkgdesc variable
-	itemArch         // arch variable
-	itemURL          // url variable
-	itemLicense      // license variable
-	itemGroups       // groups variable
-	itemDepends      // depends variable
-	itemOptdepends   // optdepends variable
-	itemMakedepends  // makedepends variable
-	itemCheckdepends // checkdepends variable
-	itemProvides     // provides variable
-	itemConflicts    // conflicts variable
-	itemReplaces     // replaces variable
-	itemBackup       // backup variable
-	itemOptions      // options variable
-	itemInstall      // install variable
-	itemChangelog    // changelog variable
-	itemSource       // source variable
-	itemNoextract    // noextract variable
-	itemMd5sums      // md5sums variable
-	itemSha1sums     // sha1sums variable
-	itemSha224sums   // sha224sums variable
-	itemSha256sums   // sha256sums variable
-	itemSha384sums   // sha384sums variable
-	itemSha512sums   // sha512sums variable
-	itemValidpgpkeys // validpgpkeys variable
-)
-
-// PKGBUILD variables
-var variables = map[string]itemType{
-	"pkgname":      itemPkgname,
-	"pkgver":       itemPkgver,
-	"pkgrel":       itemPkgrel,
-	"pkgdir":       itemPkgdir,
-	"epoch":        itemEpoch,
-	"pkgbase":      itemPkgbase,
-	"pkgdesc":      itemPkgdesc,
-	"arch":         itemArch,
-	"url":          itemURL,
-	"license":      itemLicense,
-	"groups":       itemGroups,
-	"depends":      itemDepends,
-	"optdepends":   itemOptdepends,
-	"makedepends":  itemMakedepends,
-	"checkdepends": itemCheckdepends,
-	"provides":     itemProvides,
-	"conflicts":    itemConflicts,
-	"replaces":     itemReplaces,
-	"backup":       itemBackup,
-	"options":      itemOptions,
-	"install":      itemInstall,
-	"changelog":    itemChangelog,
-	"source":       itemSource,
-	"noextract":    itemNoextract,
-	"md5sums":      itemMd5sums,
-	"sha1sums":     itemSha1sums,
-	"sha224sums":   itemSha224sums,
-	"sha256sums":   itemSha256sums,
-	"sha384sums":   itemSha384sums,
-	"sha512sums":   itemSha512sums,
-	"validpgpkeys": itemValidpgpkeys,
-}
-
-const eof = -1
-
-// stateFn represents the state of the scanner as a function that returns the next state
-type stateFn func(*lexer) stateFn
-
-// lexer holds the state of the scanner
-type lexer struct {
-	input   string
-	state   stateFn
-	pos     pos
-	start   pos
-	width   pos
-	lastPos pos
-	items   chan item // channel of scanned items
-}
-
-// next returns the next rune in the input
-func (l *lexer) next() rune {
-	if int(l.pos) >= len(l.input) {
-		l.width = 0
-		return eof
-	}
-	r, w := utf8.DecodeRuneInString(l.input[l.pos:])
-	l.width = pos(w)
-	l.pos += l.width
-	return r
-}
-
-// peek returns but does not consume the next rune in the input
-func (l *lexer) peek() rune {
-	r := l.next()
-	l.backup()
-	return r
-}
-
-// backup steps back one rune. Can only be called once per call of next
-func (l *lexer) backup() {
-	l.pos -= l.width
-}
-
-// emit passes an item back to the client
-func (l *lexer) emit(t itemType) {
-	l.items <- item{t, l.start, l.input[l.start:l.pos]}
-	l.start = l.pos
-}
-
-// ignore skips over the pending input before this point
-func (l *lexer) ignore() {
-	l.start = l.pos
-}
-
-// errorf returns an error token and terminates the scan by passing
-// back a nil pointer that will be the next state, terminating l.nextItem.
-func (l *lexer) errorf(format string, args ...interface{}) stateFn {
-	l.items <- item{itemError, l.start, fmt.Sprintf(format, args...)}
-	return nil
-}
-
-// nextItem returns the next item from the input.
-func (l *lexer) nextItem() item {
-	item := <-l.items
-	l.lastPos = item.pos
-	return item
-}
-
-func lex(input string) *lexer {
-	l := &lexer{
-		input: input,
-		items: make(chan item),
-	}
-	go l.run()
-	return l
-}
-
-func (l *lexer) run() {
-	for l.state = lexEnv; l.state != nil; {
-		l.state = l.state(l)
-	}
-}
-
-func lexEnv(l *lexer) stateFn {
-	var r rune
-	for {
-		switch r = l.next(); {
-		case r == eof:
-			l.emit(itemEOF)
-			return nil
-		case isAlphaNumericUnderscore(r):
-			return lexVariable
-		case r == '\n':
-			buffer := l.input[l.start:l.pos]
-			if buffer == "\n" {
-				if l.peek() == '\n' {
-					l.next()
-					l.emit(itemEndSplit)
-				}
-				l.ignore()
-			}
-		case r == '\t':
-			l.ignore()
-		case r == ' ':
-			l.ignore()
-		case r == '#':
-			return lexComment
-		default:
-			l.errorf("unable to parse character: %c", r)
-		}
-	}
-}
-
-func lexComment(l *lexer) stateFn {
-	for {
-		switch l.next() {
-		case '\n':
-			l.ignore()
-			return lexEnv
-		case eof:
-			l.emit(itemEOF)
-			return nil
-		}
-	}
-}
-
-func lexVariable(l *lexer) stateFn {
-	for {
-		switch r := l.next(); {
-		case isAlphaNumericUnderscore(r):
-			// absorb
-		case r == ' ' && l.peek() == '=':
-			l.backup()
-			variable := l.input[l.start:l.pos]
-
-			// strip arch from source_arch like constructs
-			witharch := strings.SplitN(variable, "_", 2)
-			if len(witharch) == 2 {
-				variable = witharch[0]
-			}
-
-			if _, ok := variables[variable]; ok {
-				l.emit(variables[variable])
-				// TODO to cut off ' = '
-				l.next()
-				l.next()
-				l.next()
-				l.ignore()
-				return lexValue
-			}
-			return l.errorf("invalid variable: %s", variable)
-		default:
-			pattern := l.input[l.start:l.pos]
-			return l.errorf("invalid pattern: %s", pattern)
-		}
-	}
-}
-
-func lexValue(l *lexer) stateFn {
-	for {
-		switch l.next() {
-		case '\n':
-			l.backup()
-			l.emit(itemValue)
-			return lexEnv
-		}
-	}
-}
-
-// isAlphaNumericUnderscore reports whether r is an alphabetic, digit, or underscore.
-func isAlphaNumericUnderscore(r rune) bool {
-	return r == '_' || unicode.IsLetter(r) || unicode.IsDigit(r)
-}

+ 0 - 625
vendor/github.com/mikkeloscar/gopkgbuild/pkgbuild.go

@@ -1,625 +0,0 @@
-package pkgbuild
-
-import (
-	"bytes"
-	"fmt"
-	"io/ioutil"
-	"strconv"
-	"strings"
-)
-
-// Dependency describes a dependency with min and max version, if any.
-type Dependency struct {
-	Name   string           // dependency name
-	MinVer *CompleteVersion // min version
-	sgt    bool             // defines if min version is strictly greater than
-	MaxVer *CompleteVersion // max version
-	slt    bool             // defines if max version is strictly less than
-}
-
-// Restrict merges two dependencies together into a new dependency where the
-// conditions of both a and b are met
-func (a *Dependency) Restrict(b *Dependency) *Dependency {
-	newDep := &Dependency{
-		Name: a.Name,
-	}
-
-	if a.MaxVer != nil || b.MaxVer != nil {
-		newDep.MaxVer = &CompleteVersion{}
-
-		if a.MaxVer == nil {
-			*newDep.MaxVer = *b.MaxVer
-			newDep.slt = b.slt
-		} else if b.MaxVer == nil {
-			*newDep.MaxVer = *a.MaxVer
-			newDep.slt = a.slt
-		} else {
-			cmpMax := a.MaxVer.cmp(b.MaxVer)
-			if cmpMax >= 1 {
-				*newDep.MaxVer = *b.MaxVer
-				newDep.slt = b.slt
-			} else if cmpMax <= -1 {
-				*newDep.MaxVer = *a.MaxVer
-				newDep.slt = a.slt
-			} else if cmpMax == 0 {
-				if len(a.MaxVer.Pkgrel) > len(b.MaxVer.Pkgrel) {
-					*newDep.MaxVer = *a.MaxVer
-				} else {
-					*newDep.MaxVer = *b.MaxVer
-				}
-				if a.slt != b.slt {
-					newDep.slt = true
-				} else {
-					newDep.slt = a.slt
-				}
-			}
-		}
-	}
-
-	if a.MinVer != nil || b.MinVer != nil {
-		newDep.MinVer = &CompleteVersion{}
-
-		if a.MinVer == nil {
-			*newDep.MinVer = *b.MinVer
-			newDep.sgt = b.slt
-		} else if b.MinVer == nil {
-			*newDep.MinVer = *a.MinVer
-			newDep.sgt = a.sgt
-		} else {
-			cmpMin := a.MinVer.cmp(b.MinVer)
-			if cmpMin >= 1 {
-				*newDep.MinVer = *a.MinVer
-				newDep.sgt = a.sgt
-			} else if cmpMin <= -1 {
-				*newDep.MinVer = *b.MinVer
-				newDep.sgt = b.sgt
-			} else if cmpMin == 0 {
-				if len(a.MinVer.Pkgrel) > len(b.MinVer.Pkgrel) {
-					*newDep.MinVer = *a.MinVer
-				} else {
-					*newDep.MinVer = *b.MinVer
-				}
-				if a.sgt != b.sgt {
-					newDep.sgt = true
-				} else {
-					newDep.sgt = a.sgt
-				}
-			}
-		}
-	}
-
-	return newDep
-}
-
-func (dep *Dependency) String() string {
-	str := ""
-	greaterThan := ">"
-	lessThan := "<"
-
-	if !dep.sgt {
-		greaterThan = ">="
-	}
-
-	if !dep.slt {
-		lessThan = "<="
-	}
-
-	if dep.MinVer != nil {
-		str += dep.Name + greaterThan + dep.MinVer.String()
-
-		if dep.MaxVer != nil {
-			str += " "
-		}
-	}
-
-	if dep.MaxVer != nil {
-		str += dep.Name + lessThan + dep.MaxVer.String()
-	}
-
-	return str
-}
-
-// PKGBUILD is a struct describing a parsed PKGBUILD file.
-// Required fields are:
-//	pkgname
-//	pkgver
-//	pkgrel
-//	arch
-//	(license) - not required but recommended
-//
-// parsing a PKGBUILD file without these fields will fail
-type PKGBUILD struct {
-	Pkgnames     []string
-	Pkgver       Version // required
-	Pkgrel       Version // required
-	Pkgdir       string
-	Epoch        int
-	Pkgbase      string
-	Pkgdesc      string
-	Arch         []string // required
-	URL          string
-	License      []string // recommended
-	Groups       []string
-	Depends      []*Dependency
-	Optdepends   []string
-	Makedepends  []*Dependency
-	Checkdepends []*Dependency
-	Provides     []string
-	Conflicts    []string
-	Replaces     []string
-	Backup       []string
-	Options      []string
-	Install      string
-	Changelog    string
-	Source       []string
-	Noextract    []string
-	Md5sums      []string
-	Sha1sums     []string
-	Sha224sums   []string
-	Sha256sums   []string
-	Sha384sums   []string
-	Sha512sums   []string
-	Validpgpkeys []string
-}
-
-// Newer is true if p has a higher version number than p2
-func (p *PKGBUILD) Newer(p2 *PKGBUILD) bool {
-	if p.Epoch < p2.Epoch {
-		return false
-	}
-
-	if p.Pkgver.bigger(p2.Pkgver) {
-		return true
-	}
-
-	if p2.Pkgver.bigger(p.Pkgver) {
-		return false
-	}
-
-	return p.Pkgrel > p2.Pkgrel
-}
-
-// Older is true if p has a smaller version number than p2
-func (p *PKGBUILD) Older(p2 *PKGBUILD) bool {
-	if p.Epoch < p2.Epoch {
-		return true
-	}
-
-	if p2.Pkgver.bigger(p.Pkgver) {
-		return true
-	}
-
-	if p.Pkgver.bigger(p2.Pkgver) {
-		return false
-	}
-
-	return p.Pkgrel < p2.Pkgrel
-}
-
-// Version returns the full version of the PKGBUILD (including epoch and rel)
-func (p *PKGBUILD) Version() string {
-	if p.Epoch > 0 {
-		return fmt.Sprintf("%d:%s-%s", p.Epoch, p.Pkgver, p.Pkgrel)
-	}
-
-	return fmt.Sprintf("%s-%s", p.Pkgver, p.Pkgrel)
-}
-
-// CompleteVersion returns a Complete version struct including version, rel and
-// epoch.
-func (p *PKGBUILD) CompleteVersion() CompleteVersion {
-	return CompleteVersion{
-		Version: p.Pkgver,
-		Epoch:   uint8(p.Epoch),
-		Pkgrel:  p.Pkgrel,
-	}
-}
-
-// BuildDepends is Depends, MakeDepends and CheckDepends combined.
-func (p *PKGBUILD) BuildDepends() []*Dependency {
-	// TODO real merge
-	deps := make([]*Dependency, len(p.Depends)+len(p.Makedepends)+len(p.Checkdepends))
-
-	deps = append(p.Depends, p.Makedepends...)
-	deps = append(deps, p.Checkdepends...)
-
-	return deps
-}
-
-// IsDevel returns true if package contains devel packages (-{bzr,git,svn,hg})
-// TODO: more robust check.
-func (p *PKGBUILD) IsDevel() bool {
-	for _, name := range p.Pkgnames {
-		if strings.HasSuffix(name, "-git") {
-			return true
-		}
-
-		if strings.HasSuffix(name, "-svn") {
-			return true
-		}
-
-		if strings.HasSuffix(name, "-hg") {
-			return true
-		}
-
-		if strings.HasSuffix(name, "-bzr") {
-			return true
-		}
-	}
-
-	return false
-}
-
-// MustParseSRCINFO must parse the .SRCINFO given by path or it will panic
-func MustParseSRCINFO(path string) *PKGBUILD {
-	pkgbuild, err := ParseSRCINFO(path)
-	if err != nil {
-		panic(err)
-	}
-	return pkgbuild
-}
-
-// ParseSRCINFO parses .SRCINFO file given by path.
-// This is a safe alternative to ParsePKGBUILD given that a .SRCINFO file is
-// available
-func ParseSRCINFO(path string) (*PKGBUILD, error) {
-	f, err := ioutil.ReadFile(path)
-	if err != nil {
-		return nil, fmt.Errorf("unable to read file: %s, %s", path, err.Error())
-	}
-
-	return parsePKGBUILD(string(f))
-}
-
-// ParseSRCINFOContent parses a .SRCINFO formatted byte slice.
-// This is a safe alternative to ParsePKGBUILD given that the .SRCINFO content
-// is available
-func ParseSRCINFOContent(content []byte) (*PKGBUILD, error) {
-	return parsePKGBUILD(string(content))
-}
-
-// parse a PKGBUILD and check that the required fields has a non-empty value
-func parsePKGBUILD(input string) (*PKGBUILD, error) {
-	pkgb, err := parse(input)
-	if err != nil {
-		return nil, err
-	}
-
-	if !validPkgver(string(pkgb.Pkgver)) {
-		return nil, fmt.Errorf("invalid pkgver: %s", pkgb.Pkgver)
-	}
-
-	if len(pkgb.Arch) == 0 {
-		return nil, fmt.Errorf("Arch missing")
-	}
-
-	if len(pkgb.Pkgnames) == 0 {
-		return nil, fmt.Errorf("missing pkgname")
-	}
-
-	for _, name := range pkgb.Pkgnames {
-		if !validPkgname(name) {
-			return nil, fmt.Errorf("invalid pkgname: %s", name)
-		}
-	}
-
-	return pkgb, nil
-}
-
-// parses a SRCINFO formatted PKGBUILD
-func parse(input string) (*PKGBUILD, error) {
-	var pkgbuild *PKGBUILD
-	var next item
-
-	lexer := lex(input)
-Loop:
-	for {
-		token := lexer.nextItem()
-
-		// strip arch from source_arch like constructs
-		witharch := strings.SplitN(token.val, "_", 2)
-		if len(witharch) == 2 {
-			found := false
-			for _, arch := range pkgbuild.Arch {
-				if arch == witharch[1] {
-					token.val = witharch[0]
-					found = true
-					break
-				}
-			}
-
-			if !found {
-				return nil, fmt.Errorf("unsupported arch for variable: %s", token.val)
-			}
-		}
-
-		switch token.typ {
-		case itemPkgbase:
-			next = lexer.nextItem()
-			pkgbuild = &PKGBUILD{Epoch: 0, Pkgbase: next.val}
-		case itemPkgname:
-			next = lexer.nextItem()
-			pkgbuild.Pkgnames = append(pkgbuild.Pkgnames, next.val)
-		case itemPkgver:
-			next = lexer.nextItem()
-			version, err := parseVersion(next.val)
-			if err != nil {
-				return nil, err
-			}
-			pkgbuild.Pkgver = version
-		case itemPkgrel:
-			next = lexer.nextItem()
-			rel, err := parseVersion(next.val)
-			if err != nil {
-				return nil, err
-			}
-			pkgbuild.Pkgrel = rel
-		case itemPkgdir:
-			next = lexer.nextItem()
-			pkgbuild.Pkgdir = next.val
-		case itemEpoch:
-			next = lexer.nextItem()
-			epoch, err := strconv.ParseInt(next.val, 10, 0)
-			if err != nil {
-				return nil, err
-			}
-
-			if epoch < 0 {
-				return nil, fmt.Errorf("invalid epoch: %d", epoch)
-			}
-			pkgbuild.Epoch = int(epoch)
-		case itemPkgdesc:
-			next = lexer.nextItem()
-			pkgbuild.Pkgdesc = next.val
-		case itemArch:
-			next = lexer.nextItem()
-			pkgbuild.Arch = append(pkgbuild.Arch, next.val)
-		case itemURL:
-			next = lexer.nextItem()
-			pkgbuild.URL = next.val
-		case itemLicense:
-			next = lexer.nextItem()
-			pkgbuild.License = append(pkgbuild.License, next.val)
-		case itemGroups:
-			next = lexer.nextItem()
-			pkgbuild.Groups = append(pkgbuild.Groups, next.val)
-		case itemDepends:
-			next = lexer.nextItem()
-			deps, err := parseDependency(next.val, pkgbuild.Depends)
-			if err != nil {
-				return nil, err
-			}
-			pkgbuild.Depends = deps
-		case itemOptdepends:
-			next = lexer.nextItem()
-			pkgbuild.Optdepends = append(pkgbuild.Optdepends, next.val)
-		case itemMakedepends:
-			next = lexer.nextItem()
-			deps, err := parseDependency(next.val, pkgbuild.Makedepends)
-			if err != nil {
-				return nil, err
-			}
-			pkgbuild.Makedepends = deps
-		case itemCheckdepends:
-			next = lexer.nextItem()
-			deps, err := parseDependency(next.val, pkgbuild.Checkdepends)
-			if err != nil {
-				return nil, err
-			}
-			pkgbuild.Checkdepends = deps
-		case itemProvides:
-			next = lexer.nextItem()
-			pkgbuild.Provides = append(pkgbuild.Provides, next.val)
-		case itemConflicts:
-			next = lexer.nextItem()
-			pkgbuild.Conflicts = append(pkgbuild.Conflicts, next.val)
-		case itemReplaces:
-			next = lexer.nextItem()
-			pkgbuild.Replaces = append(pkgbuild.Replaces, next.val)
-		case itemBackup:
-			next = lexer.nextItem()
-			pkgbuild.Backup = append(pkgbuild.Backup, next.val)
-		case itemOptions:
-			next = lexer.nextItem()
-			pkgbuild.Options = append(pkgbuild.Options, next.val)
-		case itemInstall:
-			next = lexer.nextItem()
-			pkgbuild.Install = next.val
-		case itemChangelog:
-			next = lexer.nextItem()
-			pkgbuild.Changelog = next.val
-		case itemSource:
-			next = lexer.nextItem()
-			pkgbuild.Source = append(pkgbuild.Source, next.val)
-		case itemNoextract:
-			next = lexer.nextItem()
-			pkgbuild.Noextract = append(pkgbuild.Noextract, next.val)
-		case itemMd5sums:
-			next = lexer.nextItem()
-			pkgbuild.Md5sums = append(pkgbuild.Md5sums, next.val)
-		case itemSha1sums:
-			next = lexer.nextItem()
-			pkgbuild.Sha1sums = append(pkgbuild.Sha1sums, next.val)
-		case itemSha224sums:
-			next = lexer.nextItem()
-			pkgbuild.Sha224sums = append(pkgbuild.Sha224sums, next.val)
-		case itemSha256sums:
-			next = lexer.nextItem()
-			pkgbuild.Sha256sums = append(pkgbuild.Sha256sums, next.val)
-		case itemSha384sums:
-			next = lexer.nextItem()
-			pkgbuild.Sha384sums = append(pkgbuild.Sha384sums, next.val)
-		case itemSha512sums:
-			next = lexer.nextItem()
-			pkgbuild.Sha512sums = append(pkgbuild.Sha512sums, next.val)
-		case itemValidpgpkeys:
-			next = lexer.nextItem()
-			pkgbuild.Validpgpkeys = append(pkgbuild.Validpgpkeys, next.val)
-		case itemEndSplit:
-		case itemError:
-			return nil, fmt.Errorf(token.val)
-		case itemEOF:
-			break Loop
-		default:
-			return nil, fmt.Errorf("invalid variable: %s", token.val)
-		}
-	}
-	return pkgbuild, nil
-}
-
-// parse and validate a version string
-func parseVersion(s string) (Version, error) {
-	if validPkgver(s) {
-		return Version(s), nil
-	}
-
-	return "", fmt.Errorf("invalid version string: %s", s)
-}
-
-// check if name is a valid pkgname format
-func validPkgname(name string) bool {
-	if len(name) < 1 {
-		return false
-	}
-
-	if name[0] == '-' {
-		return false
-	}
-
-	for _, r := range name {
-		if !isValidPkgnameChar(r) {
-			return false
-		}
-	}
-
-	return true
-}
-
-// check if version is a valid pkgver format
-func validPkgver(version string) bool {
-	if len(version) < 1 {
-		return false
-	}
-
-	if !isAlphaNumeric(rune(version[0])) {
-		return false
-	}
-
-	for _, r := range version[1:] {
-		if !isValidPkgverChar(r) {
-			return false
-		}
-	}
-
-	return true
-}
-
-// ParseDeps parses a string slice of dependencies into a slice of Dependency
-// objects.
-func ParseDeps(deps []string) ([]*Dependency, error) {
-	var err error
-	dependencies := make([]*Dependency, 0)
-
-	for _, dep := range deps {
-		dependencies, err = parseDependency(dep, dependencies)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	return dependencies, nil
-}
-
-// parse dependency with possible version restriction
-func parseDependency(dep string, deps []*Dependency) ([]*Dependency, error) {
-	var name string
-	var dependency *Dependency
-	index := -1
-
-	if dep == "" {
-		return deps, nil
-	}
-
-	if dep[0] == '-' {
-		return nil, fmt.Errorf("invalid dependency name")
-	}
-
-	i := 0
-	for _, c := range dep {
-		if !isValidPkgnameChar(c) {
-			break
-		}
-		i++
-	}
-
-	// check if the dependency has been set before
-	name = dep[0:i]
-	for n, d := range deps {
-		if d.Name == name {
-			index = n
-			break
-		}
-	}
-
-	dependency = &Dependency{
-		Name: name,
-		sgt:  false,
-		slt:  false,
-	}
-
-	if len(dep) != len(name) {
-		var eq bytes.Buffer
-		for _, c := range dep[i:] {
-			if c == '<' || c == '>' || c == '=' {
-				i++
-				eq.WriteRune(c)
-				continue
-			}
-			break
-		}
-
-		version, err := NewCompleteVersion(dep[i:])
-		if err != nil {
-			return nil, err
-		}
-
-		switch eq.String() {
-		case "=":
-			dependency.MinVer = version
-			dependency.MaxVer = version
-		case "<=":
-			dependency.MaxVer = version
-		case ">=":
-			dependency.MinVer = version
-		case "<":
-			dependency.MaxVer = version
-			dependency.slt = true
-		case ">":
-			dependency.MinVer = version
-			dependency.sgt = true
-		}
-	}
-
-	if index == -1 {
-		deps = append(deps, dependency)
-	} else {
-		deps[index] = deps[index].Restrict(dependency)
-	}
-
-	return deps, nil
-}
-
-// isLowerAlpha reports whether c is a lowercase alpha character
-func isLowerAlpha(c rune) bool {
-	return 'a' <= c && c <= 'z'
-}
-
-// check if c is a valid pkgname char
-func isValidPkgnameChar(c rune) bool {
-	return isAlphaNumeric(c) || c == '@' || c == '.' || c == '_' || c == '+' || c == '-'
-}
-
-// check if c is a valid pkgver char
-func isValidPkgverChar(c rune) bool {
-	return isAlphaNumeric(c) || c == '_' || c == '+' || c == '.' || c == '~'
-}

+ 0 - 324
vendor/github.com/mikkeloscar/gopkgbuild/version.go

@@ -1,324 +0,0 @@
-package pkgbuild
-
-import (
-	"fmt"
-	"strconv"
-	"strings"
-	"unicode"
-)
-
-// Version string
-type Version string
-
-type CompleteVersion struct {
-	Version Version
-	Epoch   uint8
-	Pkgrel  Version
-}
-
-func (c *CompleteVersion) String() string {
-	str := ""
-
-	if c.Epoch > 0 {
-		str = fmt.Sprintf("%d:", c.Epoch)
-	}
-
-	str = fmt.Sprintf("%s%s", str, c.Version)
-
-	if c.Pkgrel != "" {
-		str = fmt.Sprintf("%s-%s", str, c.Pkgrel)
-	}
-
-	return str
-}
-
-// NewCompleteVersion creates a CompleteVersion including basic version, epoch
-// and rel from string
-func NewCompleteVersion(s string) (*CompleteVersion, error) {
-	var err error
-	epoch := 0
-	rel := Version("")
-
-	// handle possible epoch
-	versions := strings.Split(s, ":")
-	if len(versions) > 2 {
-		return nil, fmt.Errorf("invalid version format: %s", s)
-	}
-
-	if len(versions) > 1 {
-		epoch, err = strconv.Atoi(versions[0])
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	// handle possible rel
-	versions = strings.Split(versions[len(versions)-1], "-")
-	if len(versions) > 2 {
-		return nil, fmt.Errorf("invalid version format: %s", s)
-	}
-
-	if len(versions) > 1 {
-		rel = Version(versions[1])
-	}
-
-	// finally check that the actual version is valid
-	if validPkgver(versions[0]) {
-		return &CompleteVersion{
-			Version: Version(versions[0]),
-			Epoch:   uint8(epoch),
-			Pkgrel:  rel,
-		}, nil
-	}
-
-	return nil, fmt.Errorf("invalid version format: %s", s)
-}
-
-// Older returns true if a is older than the argument version
-func (a *CompleteVersion) Older(b *CompleteVersion) bool {
-	return a.cmp(b) == -1
-}
-
-// Newer returns true if a is newer than the argument version
-func (a *CompleteVersion) Newer(b *CompleteVersion) bool {
-	return a.cmp(b) == 1
-}
-
-// Equal returns true if a is equal to the argument version
-func (a *CompleteVersion) Equal(b *CompleteVersion) bool {
-	return a.cmp(b) == 0
-}
-
-// Satisfies tests whether or not version fits inside the bounds specified by
-// dep
-func (version *CompleteVersion) Satisfies(dep *Dependency) bool {
-	var cmpMax int8
-	var cmpMin int8
-
-	if dep.MaxVer != nil {
-		cmpMax = version.cmp(dep.MaxVer)
-		if cmpMax == 1 {
-			return false
-		}
-
-		if cmpMax == 0 && dep.slt {
-			return false
-		}
-	}
-
-	if dep.MinVer != nil {
-		if dep.MaxVer == dep.MinVer {
-			cmpMin = cmpMax
-		} else {
-			cmpMin = version.cmp(dep.MinVer)
-		}
-		if cmpMin == -1 {
-			return false
-		}
-
-		if cmpMin == 0 && dep.sgt {
-			return false
-		}
-	}
-
-	return true
-}
-
-// Compare a to b:
-// return 1: a is newer than b
-//        0: a and b are the same version
-//       -1: b is newer than a
-func (a *CompleteVersion) cmp(b *CompleteVersion) int8 {
-	if a.Epoch > b.Epoch {
-		return 1
-	}
-
-	if a.Epoch < b.Epoch {
-		return -1
-	}
-
-	if a.Version.bigger(b.Version) {
-		return 1
-	}
-
-	if b.Version.bigger(a.Version) {
-		return -1
-	}
-
-	if a.Pkgrel == "" || b.Pkgrel == "" {
-		return 0
-	}
-
-	if a.Pkgrel.bigger(b.Pkgrel) {
-		return 1
-	}
-
-	if b.Pkgrel.bigger(a.Pkgrel) {
-		return -1
-	}
-
-	return 0
-}
-
-// Compare alpha and numeric segments of two versions.
-// return 1: a is newer than b
-//        0: a and b are the same version
-//       -1: b is newer than a
-//
-// This is based on the rpmvercmp function used in libalpm
-// https://projects.archlinux.org/pacman.git/tree/lib/libalpm/version.c
-func rpmvercmp(av, bv Version) int {
-	if av == bv {
-		return 0
-	}
-	a, b := []rune(string(av)), []rune(string(bv))
-
-	var one, two, ptr1, ptr2 int
-	var isNum bool
-	one, two, ptr1, ptr2 = 0, 0, 0, 0
-
-	// loop through each version segment of a and b and compare them
-	for len(a) > one && len(b) > two {
-		for len(a) > one && !isAlphaNumeric(a[one]) {
-			one++
-		}
-		for len(b) > two && !isAlphaNumeric(b[two]) {
-			two++
-		}
-
-		// if we ran to the end of either, we are finished with the loop
-		if !(len(a) > one && len(b) > two) {
-			break
-		}
-
-		// if the seperator lengths were different, we are also finished
-		if one-ptr1 != two-ptr2 {
-			if one-ptr1 < two-ptr2 {
-				return -1
-			}
-			return 1
-		}
-
-		ptr1 = one
-		ptr2 = two
-
-		// grab first completely alpha or completely numeric segment
-		// leave one and two pointing to the start of the alpha or numeric
-		// segment and walk ptr1 and ptr2 to end of segment
-		if isDigit(a[ptr1]) {
-			for len(a) > ptr1 && isDigit(a[ptr1]) {
-				ptr1++
-			}
-			for len(b) > ptr2 && isDigit(b[ptr2]) {
-				ptr2++
-			}
-			isNum = true
-		} else {
-			for len(a) > ptr1 && isAlpha(a[ptr1]) {
-				ptr1++
-			}
-			for len(b) > ptr2 && isAlpha(b[ptr2]) {
-				ptr2++
-			}
-			isNum = false
-		}
-
-		// take care of the case where the two version segments are
-		// different types: one numeric, the other alpha (i.e. empty)
-		// numeric segments are always newer than alpha segments
-		if two == ptr2 {
-			if isNum {
-				return 1
-			}
-			return -1
-		}
-
-		if isNum {
-			// we know this part of the strings only contains digits
-			// so we can ignore the error value since it should
-			// always be nil
-			as, _ := strconv.ParseInt(string(a[one:ptr1]), 10, 0)
-			bs, _ := strconv.ParseInt(string(b[two:ptr2]), 10, 0)
-
-			// whichever number has more digits wins
-			if as > bs {
-				return 1
-			}
-			if as < bs {
-				return -1
-			}
-		} else {
-			cmp := alphaCompare(a[one:ptr1], b[two:ptr2])
-			if cmp < 0 {
-				return -1
-			}
-			if cmp > 0 {
-				return 1
-			}
-		}
-
-		// advance one and two to next segment
-		one = ptr1
-		two = ptr2
-	}
-
-	// this catches the case where all numeric and alpha segments have
-	// compared identically but the segment separating characters were
-	// different
-	if len(a) <= one && len(b) <= two {
-		return 0
-	}
-
-	// the final showdown. we never want a remaining alpha string to
-	// beat an empty string. the logic is a bit weird, but:
-	// - if one is empty and two is not an alpha, two is newer.
-	// - if one is an alpha, two is newer.
-	// - otherwise one is newer.
-	if (len(a) <= one && !isAlpha(b[two])) || len(a) > one && isAlpha(a[one]) {
-		return -1
-	}
-	return 1
-}
-
-// alphaCompare compares two alpha version segments and will return a positive
-// value if a is bigger than b and a negative if b is bigger than a else 0
-func alphaCompare(a, b []rune) int8 {
-	if string(a) == string(b) {
-		return 0
-	}
-
-	i := 0
-	for len(a) > i && len(b) > i && a[i] == b[i] {
-		i++
-	}
-
-	if len(a) == i && len(b) > i {
-		return -1
-	}
-
-	if len(b) == i {
-		return 1
-	}
-
-	return int8(a[i]) - int8(b[i])
-}
-
-// check if version number v is bigger than v2
-func (v Version) bigger(v2 Version) bool {
-	return rpmvercmp(v, v2) == 1
-}
-
-// isAlphaNumeric reports whether c is an alpha character or digit
-func isAlphaNumeric(c rune) bool {
-	return isDigit(c) || isAlpha(c)
-}
-
-// isAlpha reports whether c is an alpha character
-func isAlpha(c rune) bool {
-	return unicode.IsLetter(c)
-}
-
-// isDigit reports whether d is an ASCII digit
-func isDigit(d rune) bool {
-	return unicode.IsDigit(d)
-}