Browse Source

Merge branch 'Morganamilo-reorderinstall'

Jguer 7 years ago
parent
commit
63bc57e99e
8 changed files with 499 additions and 220 deletions
  1. 4 10
      cmd.go
  2. 238 71
      dependencies.go
  3. 181 103
      install.go
  4. 14 1
      parser.go
  5. 9 0
      print.go
  6. 38 20
      query.go
  7. 12 14
      upgrade.go
  8. 3 1
      vcs.go

+ 4 - 10
cmd.go

@@ -626,16 +626,10 @@ func numberMenu(pkgS []string, flags []string) (err error) {
 	aurI = removeListFromList(aurNI, aurI)
 	repoI = removeListFromList(repoNI, repoI)
 
-	if len(repoI) != 0 {
-		arguments := makeArguments()
-		arguments.addArg("S")
-		arguments.addTarget(repoI...)
-		err = passToPacman(arguments)
-	}
-
-	if len(aurI) != 0 {
-		err = aurInstall(aurI, nil)
-	}
+	arguments := makeArguments()
+	arguments.addTarget(repoI...)
+	arguments.addTarget(aurI...)
+	err = install(arguments)
 
 	return err
 }

+ 238 - 71
dependencies.go

@@ -1,119 +1,286 @@
 package main
 
 import (
-	"fmt"
 	"strings"
 
+	alpm "github.com/jguer/go-alpm"
 	rpc "github.com/mikkeloscar/aur"
 )
 
-// BuildDependencies finds packages, on the second run
-// compares with a baselist and avoids searching those
-func buildDependencies(baselist []string) func(toCheck []string, isBaseList bool, last bool) (repo []string, notFound []string) {
-	localDb, err := alpmHandle.LocalDb()
-	if err != nil {
-		panic(err)
+type depTree struct {
+	ToProcess []string
+	Repo      map[string]*alpm.Package
+	Aur       map[string]*rpc.Pkg
+	Missing   stringSet
+}
+
+type depCatagories struct {
+	Repo     []*alpm.Package
+	RepoMake []*alpm.Package
+	Aur      []*rpc.Pkg
+	AurMake  []*rpc.Pkg
+}
+
+func makeDepTree() *depTree {
+	dt := depTree{
+		make([]string, 0),
+		make(map[string]*alpm.Package),
+		make(map[string]*rpc.Pkg),
+		make(stringSet),
 	}
 
-	dbList, err := alpmHandle.SyncDbs()
-	if err != nil {
-		panic(err)
+	return &dt
+}
+
+func makeDependCatagories() *depCatagories {
+	dc := depCatagories{
+		make([]*alpm.Package, 0),
+		make([]*alpm.Package, 0),
+		make([]*rpc.Pkg, 0),
+		make([]*rpc.Pkg, 0),
 	}
 
-	f := func(c rune) bool {
+	return &dc
+}
+
+func getNameFromDep(dep string) string {
+	return strings.FieldsFunc(dep, func(c rune) bool {
 		return c == '>' || c == '<' || c == '=' || c == ' '
+	})[0]
+}
+
+func getDepCatagories(pkgs []string, dt *depTree) (*depCatagories, error) {
+	dc := makeDependCatagories()
+
+	for _, pkg := range pkgs {
+		dep := getNameFromDep(pkg)
+		alpmpkg, exists := dt.Repo[dep]
+		if exists {
+			repoDepCatagoriesRecursive(alpmpkg, dc, dt, false)
+			dc.Repo = append(dc.Repo, alpmpkg)
+			delete(dt.Repo, dep)
+		}
+
+		aurpkg, exists := dt.Aur[dep]
+		if exists {
+			depCatagoriesRecursive(aurpkg, dc, dt, false)
+			dc.Aur = append(dc.Aur, aurpkg)
+			delete(dt.Aur, dep)
+		}
 	}
 
-	return func(toCheck []string, isBaseList bool, close bool) (repo []string, notFound []string) {
-		if close {
-			return
+	return dc, nil
+}
+
+func repoDepCatagoriesRecursive(pkg *alpm.Package, dc *depCatagories, dt *depTree, isMake bool) {
+	pkg.Depends().ForEach(func(_dep alpm.Depend) error {
+		dep := _dep.Name
+		alpmpkg, exists := dt.Repo[dep]
+		if exists {
+			delete(dt.Repo, dep)
+			repoDepCatagoriesRecursive(alpmpkg, dc, dt, isMake)
+
+			if isMake {
+				dc.RepoMake = append(dc.RepoMake, alpmpkg)
+			} else {
+				dc.Repo = append(dc.Repo, alpmpkg)
+			}
+
 		}
 
-	Loop:
-		for _, dep := range toCheck {
-			if !isBaseList {
-				for _, base := range baselist {
-					if base == dep {
-						continue Loop
-					}
+		return nil
+	})
+}
+
+func depCatagoriesRecursive(pkg *rpc.Pkg, dc *depCatagories, dt *depTree, isMake bool) {
+	for _, deps := range [2][]string{pkg.Depends, pkg.MakeDepends} {
+		for _, _dep := range deps {
+			dep := getNameFromDep(_dep)
+
+			aurpkg, exists := dt.Aur[dep]
+			if exists {
+				delete(dt.Aur, dep)
+				depCatagoriesRecursive(aurpkg, dc, dt, isMake)
+
+				if isMake {
+					dc.AurMake = append(dc.AurMake, aurpkg)
+				} else {
+					dc.Aur = append(dc.Aur, aurpkg)
 				}
+
 			}
-			if _, erp := localDb.PkgCache().FindSatisfier(dep); erp == nil {
-				continue
-			} else if pkg, erp := dbList.FindSatisfier(dep); erp == nil {
-				repo = append(repo, pkg.Name())
-			} else {
-				field := strings.FieldsFunc(dep, f)
-				notFound = append(notFound, field[0])
+
+			alpmpkg, exists := dt.Repo[dep]
+			if exists {
+				delete(dt.Repo, dep)
+				repoDepCatagoriesRecursive(alpmpkg, dc, dt, isMake)
+
+				if isMake {
+					dc.RepoMake = append(dc.RepoMake, alpmpkg)
+				} else {
+					dc.Repo = append(dc.Repo, alpmpkg)
+				}
+
 			}
+
 		}
-		return
+		isMake = true
 	}
 }
 
-// DepSatisfier receives a string slice, returns a slice of packages found in
-// repos and one of packages not found in repos. Leaves out installed packages.
-func depSatisfier(toCheck []string) (repo []string, notFound []string, err error) {
+func getDepTree(pkgs []string) (*depTree, error) {
+	dt := makeDepTree()
+
 	localDb, err := alpmHandle.LocalDb()
 	if err != nil {
-		return
+		return dt, err
 	}
-	dbList, err := alpmHandle.SyncDbs()
+	syncDb, err := alpmHandle.SyncDbs()
 	if err != nil {
-		return
+		return dt, err
 	}
 
-	f := func(c rune) bool {
-		return c == '>' || c == '<' || c == '=' || c == ' '
-	}
+	for _, pkg := range pkgs {
+		//if they explicitly asked for it still look for installed pkgs
+		/*installedPkg, isInstalled := localDb.PkgCache().FindSatisfier(pkg)
+		if isInstalled == nil {
+			dt.Repo[installedPkg.Name()] = installedPkg
+			continue
+		}//*/
 
-	for _, dep := range toCheck {
-		if _, erp := localDb.PkgCache().FindSatisfier(dep); erp == nil {
+		//check the repos for a matching dep
+		repoPkg, inRepos := syncDb.FindSatisfier(pkg)
+		if inRepos == nil {
+			repoTreeRecursive(repoPkg, dt, localDb, syncDb)
 			continue
-		} else if pkg, erp := dbList.FindSatisfier(dep); erp == nil {
-			repo = append(repo, pkg.Name())
-		} else {
-			field := strings.FieldsFunc(dep, f)
-			notFound = append(notFound, field[0])
 		}
+
+		dt.ToProcess = append(dt.ToProcess, pkg)
 	}
 
-	err = nil
-	return
+	if len(dt.ToProcess) > 0 {
+		err = depTreeRecursive(dt, localDb, syncDb, false)
+	}
+
+	return dt, err
 }
 
-// PkgDependencies returns package dependencies not installed belonging to AUR
-// 0 is Repo, 1 is Foreign.
-func pkgDependencies(a *rpc.Pkg) (runDeps [2][]string, makeDeps [2][]string, err error) {
-	var q aurQuery
-	if len(a.Depends) == 0 && len(a.MakeDepends) == 0 {
-		q, err = rpc.Info([]string{a.Name})
-		if len(q) == 0 || err != nil {
-			err = fmt.Errorf("Unable to search dependencies, %s", err)
+//takes a repo package
+//gives all of the non installed deps
+//does again on each sub dep
+func repoTreeRecursive(pkg *alpm.Package, dt *depTree, localDb *alpm.Db, syncDb alpm.DbList) (err error) {
+	_, exists := dt.Repo[pkg.Name()]
+	if exists {
+		return
+	}
+
+	dt.Repo[pkg.Name()] = pkg
+
+	(*pkg).Depends().ForEach(func(dep alpm.Depend) (err error) {
+		_, exists := dt.Repo[dep.Name]
+		if exists {
+			return
+		}
+
+		_, isInstalled := localDb.PkgCache().FindSatisfier(dep.String())
+		if isInstalled == nil {
 			return
 		}
-	} else {
-		q = append(q, *a)
-	}
 
-	depSearch := buildDependencies(a.Depends)
-	if len(a.Depends) != 0 {
-		runDeps[0], runDeps[1] = depSearch(q[0].Depends, true, false)
-		if len(runDeps[0]) != 0 || len(runDeps[1]) != 0 {
-			fmt.Println("\x1b[1;32m=>\x1b[1;33m Run Dependencies: \x1b[0m")
-			printDeps(runDeps[0], runDeps[1])
+		repoPkg, inRepos := syncDb.FindSatisfier(dep.String())
+		if inRepos == nil {
+			repoTreeRecursive(repoPkg, dt, localDb, syncDb)
+			return
+		} else {
+			dt.Missing.set(dep.String())
 		}
+
+		return
+	})
+
+	return
+}
+
+func depTreeRecursive(dt *depTree, localDb *alpm.Db, syncDb alpm.DbList, isMake bool) (err error) {
+	nextProcess := make([]string, 0)
+	currentProcess := make([]string, 0, len(dt.ToProcess))
+
+	//strip version conditions
+	for _, dep := range dt.ToProcess {
+		currentProcess = append(currentProcess, getNameFromDep(dep))
+	}
+
+	//assume toprocess only contains aur stuff we have not seen
+	info, err := rpc.Info(currentProcess)
+	if err != nil {
+		return
+	}
+
+	//cache the results
+	for _, pkg := range info {
+		//copying to p fixes a bug
+		//would rather not copy but cant find another way to fix
+		p := pkg
+		dt.Aur[pkg.Name] = &p
+
 	}
 
-	if len(a.MakeDepends) != 0 {
-		makeDeps[0], makeDeps[1] = depSearch(q[0].MakeDepends, false, false)
-		if len(makeDeps[0]) != 0 || len(makeDeps[1]) != 0 {
-			fmt.Println("\x1b[1;32m=>\x1b[1;33m Make Dependencies: \x1b[0m")
-			printDeps(makeDeps[0], makeDeps[1])
+	//loop through to process and check if we now have
+	//each packaged cached
+	//if its not cached we assume its missing
+	for k, pkgName := range currentProcess {
+		pkg, exists := dt.Aur[pkgName]
+
+		//didnt get it in the request
+		if !exists {
+			dt.Missing.set(dt.ToProcess[k])
+			continue
+		}
+
+		//for reach dep and makedep
+		for _, deps := range [2][]string{pkg.Depends, pkg.MakeDepends} {
+			for _, versionedDep := range deps {
+				dep := getNameFromDep(versionedDep)
+
+				_, exists = dt.Aur[dep]
+				//we have it cached so skip
+				if exists {
+					continue
+				}
+
+				_, exists = dt.Repo[dep]
+				//we have it cached so skip
+				if exists {
+					continue
+				}
+
+				_, exists = dt.Missing[dep]
+				//we know it doesnt resolve so skip
+				if exists {
+					continue
+				}
+
+				//check if already installed
+				_, isInstalled := localDb.PkgCache().FindSatisfier(versionedDep)
+				if isInstalled == nil {
+					continue
+				}
+
+				//check the repos for a matching dep
+				repoPkg, inRepos := syncDb.FindSatisfier(versionedDep)
+				if inRepos == nil {
+					repoTreeRecursive(repoPkg, dt, localDb, syncDb)
+					continue
+				}
+
+				//if all else failes add it to next search
+				nextProcess = append(nextProcess, versionedDep)
+			}
 		}
 	}
-	depSearch(a.MakeDepends, false, true)
 
-	err = nil
+	dt.ToProcess = nextProcess
+	depTreeRecursive(dt, localDb, syncDb, true)
+
 	return
 }

+ 181 - 103
install.go

@@ -4,14 +4,24 @@ import (
 	"fmt"
 	"os"
 	"os/exec"
+	"strconv"
 
+	alpm "github.com/jguer/go-alpm"
 	rpc "github.com/mikkeloscar/aur"
 	gopkg "github.com/mikkeloscar/gopkgbuild"
 )
 
 // Install handles package installs
 func install(parser *arguments) error {
-	aurs, repos, _ := packageSlices(parser.targets.toSlice())
+	aurs, repos, missing, err := packageSlices(parser.targets.toSlice())
+	if err != nil {
+		return err
+	}
+
+	if len(missing) > 0 {
+		fmt.Println(missing)
+		return fmt.Errorf("Could not find all Targets")
+	}
 
 	arguments := parser.copy()
 	arguments.delArg("u", "sysupgrade")
@@ -27,147 +37,215 @@ func install(parser *arguments) error {
 	}
 
 	if len(aurs) != 0 {
-		err := aurInstall(aurs, []string{})
+		//todo make pretty
+		fmt.Println("Resolving Dependencies")
+
+		dt, err := getDepTree(aurs)
 		if err != nil {
-			fmt.Println("Error installing aur packages.")
+			return err
 		}
-	}
-	return nil
-}
 
-// Install sends system commands to make and install a package from pkgName
-func aurInstall(pkgName []string, flags []string) (err error) {
-	q, err := rpc.Info(pkgName)
-	if err != nil {
-		return
-	}
+		if len(dt.Missing) > 0 {
+			fmt.Println(dt.Missing)
+			return fmt.Errorf("Could not find all Deps")
+		}
 
-	if len(q) != len(pkgName) {
-		fmt.Printf("Some packages from list\n%+v\n do not exist", pkgName)
-	}
+		dc, err := getDepCatagories(aurs, dt)
+		if err != nil {
+			return err
+		}
+
+		for _, pkg := range dc.AurMake {
+			if pkg.Maintainer == "" {
+				fmt.Printf("\x1b[1;31;40m==> Warning:\x1b[0;;40m %s is orphaned.\x1b[0m\n", pkg.Name+"-"+pkg.Version)
+			}
+		}
 
-	var finalrm []string
-	for _, i := range q {
-		mrm, err := PkgInstall(&i, flags)
+		for _, pkg := range dc.Aur {
+			if pkg.Maintainer == "" {
+				fmt.Printf("\x1b[1;31;40m==> Warning:\x1b[0;;40m %s is orphaned.\x1b[0m\n", pkg.Name+"-"+pkg.Version)
+			}
+		}
+
+		fmt.Println()
+
+		p1 := func(a []*alpm.Package) {
+			for _, v := range a {
+				fmt.Print("  ", v.Name())
+			}
+		}
+
+		p2 := func(a []*rpc.Pkg) {
+			for _, v := range a {
+				fmt.Print("  ", v.Name)
+			}
+		}
+
+		fmt.Print("Repo (" + strconv.Itoa(len(dc.Repo)) + "):")
+		p1(dc.Repo)
+		fmt.Println()
+
+		fmt.Print("Repo Make (" + strconv.Itoa(len(dc.RepoMake)) + "):")
+		p1(dc.RepoMake)
+		fmt.Println()
+
+		fmt.Print("Aur (" + strconv.Itoa(len(dc.Aur)) + "):")
+		p2(dc.Aur)
+		fmt.Println()
+
+		fmt.Print("Aur Make (" + strconv.Itoa(len(dc.AurMake)) + "):")
+		p2(dc.AurMake)
+		fmt.Println()
+
+		fmt.Println()
+
+		askCleanBuilds(dc.AurMake)
+		askCleanBuilds(dc.Aur)
+
+		fmt.Println()
+
+		if !continueTask("Proceed with download?", "nN") {
+			return fmt.Errorf("Aborting due to user")
+		}
+
+		err = dowloadPkgBuilds(dc.AurMake)
 		if err != nil {
-			fmt.Println("Error installing", i.Name, ":", err)
+			return err
+		}
+		err = dowloadPkgBuilds(dc.Aur)
+		if err != nil {
+			return err
 		}
-		finalrm = append(finalrm, mrm...)
-	}
 
-	if len(finalrm) != 0 {
-		err = removeMakeDeps(finalrm)
-	}
+		askEditPkgBuilds(dc.AurMake)
+		askEditPkgBuilds(dc.Aur)
 
-	return err
-}
+		if !continueTask("Proceed with install?", "nN") {
+			return fmt.Errorf("Aborting due to user")
+		}
 
-func setupPackageSpace(a *rpc.Pkg) (dir string, pkgbuild *gopkg.PKGBUILD, err error) {
-	dir = config.BuildDir + a.PackageBase + "/"
+		err = downloadPkgBuildsSources(dc.AurMake)
+		if err != nil {
+			return err
+		}
+		err = downloadPkgBuildsSources(dc.Aur)
+		if err != nil {
+			return err
+		}
 
-	if _, err = os.Stat(dir); !os.IsNotExist(err) {
-		if !continueTask("Directory exists. Clean Build?", "yY") {
-			_ = os.RemoveAll(config.BuildDir + a.PackageBase)
+		err = buildInstallPkgBuilds(dc.AurMake, parser.targets)
+		if err != nil {
+			return err
+		}
+		err = buildInstallPkgBuilds(dc.Aur, parser.targets)
+		if err != nil {
+			return err
 		}
-	}
 
-	if err = downloadAndUnpack(baseURL+a.URLPath, config.BuildDir, false); err != nil {
-		return
-	}
+		if len(dc.RepoMake)+len(dc.AurMake) > 0 {
+			if continueTask("Remove make dependancies?", "yY") {
+				return nil
+			}
 
-	if !continueTask("Edit PKGBUILD?", "yY") {
-		editcmd := exec.Command(editor(), dir+"PKGBUILD")
-		editcmd.Stdin, editcmd.Stdout, editcmd.Stderr = os.Stdin, os.Stdout, os.Stderr
-		editcmd.Run()
-	}
+			removeArguments := makeArguments()
+			removeArguments.addArg("R")
 
-	pkgbuild, err = gopkg.ParseSRCINFO(dir + ".SRCINFO")
-	if err == nil {
-		for _, pkgsource := range pkgbuild.Source {
-			owner, repo := parseSource(pkgsource)
-			if owner != "" && repo != "" {
-				err = branchInfo(a.Name, owner, repo)
-				if err != nil {
-					fmt.Println(err)
-				}
+			for _, pkg := range dc.RepoMake {
+				removeArguments.addTarget(pkg.Name())
 			}
+
+			for _, pkg := range dc.AurMake {
+				removeArguments.addTarget(pkg.Name)
+			}
+
+			passToPacman(removeArguments)
 		}
-	}
-	return
-}
 
-// PkgInstall handles install from Info Result.
-func PkgInstall(a *rpc.Pkg, flags []string) (finalmdeps []string, err error) {
-	fmt.Printf("\x1b[1;32m==> Installing\x1b[33m %s\x1b[0m\n", a.Name)
-	if a.Maintainer == "" {
-		fmt.Println("\x1b[1;31;40m==> Warning:\x1b[0;;40m This package is orphaned.\x1b[0m")
+		return nil
 	}
 
-	dir, _, err := setupPackageSpace(a)
-	if err != nil {
-		return
-	}
+	return nil
+}
 
-	if specialDBsauce {
-		return
-	}
+func askCleanBuilds(pkgs []*rpc.Pkg) {
+	for _, pkg := range pkgs {
+		dir := config.BuildDir + pkg.PackageBase + "/"
 
-	runDeps, makeDeps, err := pkgDependencies(a)
-	if err != nil {
-		return
+		if _, err := os.Stat(dir); !os.IsNotExist(err) {
+			if !continueTask(pkg.Name+" Directory exists. Clean Build?", "yY") {
+				_ = os.RemoveAll(config.BuildDir + pkg.PackageBase)
+			}
+		}
 	}
+}
 
-	repoDeps := append(runDeps[0], makeDeps[0]...)
-	aurDeps := append(runDeps[1], makeDeps[1]...)
-	finalmdeps = append(finalmdeps, makeDeps[0]...)
-	finalmdeps = append(finalmdeps, makeDeps[1]...)
+func askEditPkgBuilds(pkgs []*rpc.Pkg) {
+	for _, pkg := range pkgs {
+		dir := config.BuildDir + pkg.PackageBase + "/"
 
-	if len(aurDeps) != 0 || len(repoDeps) != 0 {
-		if !continueTask("Continue?", "nN") {
-			return finalmdeps, fmt.Errorf("user did not like the dependencies")
+		if !continueTask(pkg.Name+" Edit PKGBUILD?", "yY") {
+			editcmd := exec.Command(editor(), dir+"PKGBUILD")
+			editcmd.Stdin, editcmd.Stdout, editcmd.Stderr = os.Stdin, os.Stdout, os.Stderr
+			editcmd.Run()
 		}
-	}
 
-	aurQ, _ := rpc.Info(aurDeps)
-	if len(aurQ) != len(aurDeps) {
-		(aurQuery)(aurQ).missingPackage(aurDeps)
-		if !continueTask("Continue?", "nN") {
-			return finalmdeps, fmt.Errorf("unable to install dependencies")
+		pkgbuild, err := gopkg.ParseSRCINFO(dir + ".SRCINFO")
+		if err == nil {
+			for _, pkgsource := range pkgbuild.Source {
+				owner, repo := parseSource(pkgsource)
+				if owner != "" && repo != "" {
+					err = branchInfo(pkg.Name, owner, repo)
+					if err != nil {
+						fmt.Println(err)
+					}
+				}
+			}
 		}
+
 	}
+}
 
-	arguments := makeArguments()
-	arguments.addArg("S", "asdeps", "noconfirm")
-	arguments.addTarget(repoDeps...)
+func dowloadPkgBuilds(pkgs []*rpc.Pkg) (err error) {
+	for _, pkg := range pkgs {
+		//todo make pretty
+		fmt.Println("Downloading:", pkg.Name+"-"+pkg.Version)
 
-	var depArgs []string
-	if config.NoConfirm {
-		depArgs = []string{"asdeps", "noconfirm"}
-	} else {
-		depArgs = []string{"asdeps"}
+		err = downloadAndUnpack(baseURL+pkg.URLPath, config.BuildDir, false)
+		if err != nil {
+			return
+		}
 	}
 
-	// Repo dependencies
-	if len(repoDeps) != 0 {
-		errR := passToPacman(arguments)
-		if errR != nil {
-			return finalmdeps, errR
+	return
+}
+
+func downloadPkgBuildsSources(pkgs []*rpc.Pkg) (err error) {
+	for _, pkg := range pkgs {
+		dir := config.BuildDir + pkg.PackageBase + "/"
+		err = passToMakepkg(dir, "-f", "--verifysource")
+		if err != nil {
+			return
 		}
 	}
 
-	// Handle AUR dependencies
-	for _, dep := range aurQ {
-		finalmdepsR, errA := PkgInstall(&dep, depArgs)
-		finalmdeps = append(finalmdeps, finalmdepsR...)
+	return
+}
+
+func buildInstallPkgBuilds(pkgs []*rpc.Pkg, targets stringSet) (err error) {
+	//for n := len(pkgs) -1 ; n > 0; n-- {
+	for n := 0; n < len(pkgs); n++ {
+		pkg := pkgs[n]
 
-		if errA != nil {
-			cleanRemove(repoDeps)
-			cleanRemove(aurDeps)
-			return finalmdeps, errA
+		dir := config.BuildDir + pkg.PackageBase + "/"
+		if targets.get(pkg.Name) {
+			err = passToMakepkg(dir, "-Cscfi", "--noconfirm")
+		} else {
+			err = passToMakepkg(dir, "-Cscfi", "--noconfirm", "--asdeps")
+		}
+		if err != nil {
+			return
 		}
 	}
 
-	flags = append(flags, "-sri")
-	err = passToMakepkg(dir, flags...)
 	return
 }

+ 14 - 1
parser.go

@@ -9,6 +9,19 @@ import (
 
 type stringSet map[string]struct{}
 
+func (set stringSet) set(v string) {
+	set[v] = struct{}{}
+}
+
+func (set stringSet) get(v string) bool {
+	_, exists := set[v]
+	return exists
+}
+
+func (set stringSet) remove(v string) {
+	delete(set, v)
+}
+
 func (set stringSet) getAny() string {
 	for v := range set {
 		return v
@@ -30,7 +43,7 @@ func (set stringSet) toSlice() []string {
 
 func (set stringSet) removeAny() string {
 	v := set.getAny()
-	delete(set, v)
+	set.remove(v)
 	return v
 }
 

+ 9 - 0
print.go

@@ -254,3 +254,12 @@ func localStatistics() error {
 
 	return nil
 }
+
+//todo make pretty
+func printMissing(missing stringSet) {
+	fmt.Print("Packages not found in repos or aur:")
+	for pkg := range missing {
+		fmt.Print(" ", pkg)
+	}
+	fmt.Println()
+}

+ 38 - 20
query.go

@@ -153,7 +153,7 @@ func syncSearch(pkgS []string) (err error) {
 
 // SyncInfo serves as a pacman -Si for repo packages and AUR packages.
 func syncInfo(pkgS []string, flags []string) (err error) {
-	aurS, repoS, err := packageSlices(pkgS)
+	aurS, repoS, _, err := packageSlices(pkgS)
 	if err != nil {
 		return
 	}
@@ -181,6 +181,11 @@ func syncInfo(pkgS []string, flags []string) (err error) {
 		}
 	}
 
+	//todo
+	//if len(missing) != 0 {
+	//	printMissing(missing)
+	//}
+
 	return
 }
 
@@ -235,38 +240,51 @@ func queryRepo(pkgInputN []string) (s repoQuery, n int, err error) {
 }
 
 // PackageSlices separates an input slice into aur and repo slices
-func packageSlices(toCheck []string) (aur []string, repo []string, err error) {
+func packageSlices(toCheck []string) (aur []string, repo []string, missing []string, err error) {
+	possibleAur := make([]string, 0)
 	dbList, err := alpmHandle.SyncDbs()
 	if err != nil {
 		return
 	}
 
-	for _, pkg := range toCheck {
-		found := false
-
-		_ = dbList.ForEach(func(db alpm.Db) error {
-			if found {
-				return nil
-			}
+	for _, _pkg := range toCheck {
+		pkg := getNameFromDep(_pkg)
 
-			_, err = db.PkgByName(pkg)
-			if err == nil {
-				found = true
-				repo = append(repo, pkg)
-			}
-			return nil
-		})
+		_, errdb := dbList.FindSatisfier(_pkg)
+		found := errdb == nil
 
 		if !found {
-			if _, errdb := dbList.PkgCachebyGroup(pkg); errdb == nil {
-				repo = append(repo, pkg)
-			} else {
+			_, errdb = dbList.PkgCachebyGroup(_pkg)
+			found = errdb == nil
+		}
+
+		if found {
+			repo = append(repo, pkg)
+		} else {
+			possibleAur = append(possibleAur, pkg)
+		}
+	}
+
+	if len(possibleAur) == 0 {
+		return
+	}
+
+	info, err := rpc.Info(possibleAur)
+	if err != nil {
+		return
+	}
+
+outer:
+	for _, pkg := range possibleAur {
+		for _, rpcpkg := range info {
+			if rpcpkg.Name == pkg {
 				aur = append(aur, pkg)
+				continue outer
 			}
 		}
+		missing = append(missing, pkg)
 	}
 
-	err = nil
 	return
 }
 

+ 12 - 14
upgrade.go

@@ -365,8 +365,14 @@ func upgradePkgs(flags []string) error {
 		repoNums = removeIntListFromList(excludeRepo, repoNums)
 	}
 
+	arguments := cmdArgs.copy()
+	arguments.delArg("u", "sysupgrade")
+	arguments.delArg("y", "refresh")
+
+	var repoNames []string
+	var aurNames []string
+
 	if len(repoUp) != 0 {
-		var repoNames []string
 	repoloop:
 		for i, k := range repoUp {
 			for _, j := range repoNums {
@@ -376,20 +382,9 @@ func upgradePkgs(flags []string) error {
 			}
 			repoNames = append(repoNames, k.Name)
 		}
-
-		arguments := makeArguments()
-		arguments.addArg("S", "noconfirm")
-		arguments.addArg(flags...)
-		arguments.addTarget(repoNames...)
-
-		err := passToPacman(arguments)
-		if err != nil {
-			fmt.Println("Error upgrading repo packages.")
-		}
 	}
 
 	if len(aurUp) != 0 {
-		var aurNames []string
 	aurloop:
 		for i, k := range aurUp {
 			for _, j := range aurNums {
@@ -399,7 +394,10 @@ func upgradePkgs(flags []string) error {
 			}
 			aurNames = append(aurNames, k.Name)
 		}
-		aurInstall(aurNames, flags)
 	}
-	return nil
+
+	arguments.addTarget(repoNames...)
+	arguments.addTarget(aurNames...)
+	err = install(arguments)
+	return err
 }

+ 3 - 1
vcs.go

@@ -38,7 +38,9 @@ func createDevelDB() error {
 
 	config.NoConfirm = true
 	specialDBsauce = true
-	err = aurInstall(remoteNames, nil)
+	arguments := makeArguments()
+	arguments.addTarget(remoteNames...)
+	err = install(arguments)
 	return err
 }