Pārlūkot izejas kodu

Merge pull request #251 from Morganamilo/provides

Implement the provider question  and imatate pacman
Morgana 7 gadi atpakaļ
vecāks
revīzija
44f2da3211
5 mainītis faili ar 129 papildinājumiem un 41 dzēšanām
  1. 76 2
      callbacks.go
  2. 30 14
      dependencies.go
  3. 8 19
      install.go
  4. 12 3
      query.go
  5. 3 3
      vcs.go

+ 76 - 2
callbacks.go

@@ -1,12 +1,86 @@
 package main
 
 import (
+	"bufio"
+	"fmt"
 	alpm "github.com/jguer/go-alpm"
+	"os"
+	"strconv"
 )
 
 func questionCallback(question alpm.QuestionAny) {
-	q, err := question.QuestionInstallIgnorepkg()
+	qi, err := question.QuestionInstallIgnorepkg()
 	if err == nil {
-		q.SetInstall(true)
+		qi.SetInstall(true)
+	}
+
+	qp, err := question.QuestionSelectProvider()
+	if err == nil {
+		size := 0
+
+		qp.Providers(alpmHandle).ForEach(func(pkg alpm.Package) error {
+			size++
+			return nil
+		})
+
+		fmt.Print(bold(cyan(":: ")))
+		str := bold(fmt.Sprintf(bold("There are %d providers avalable for %s:"), size, qp.Dep()))
+
+		size = 1
+		var db string
+
+		qp.Providers(alpmHandle).ForEach(func(pkg alpm.Package) error {
+			thisDb := pkg.DB().Name()
+
+			if db != thisDb {
+				db = thisDb
+				str += bold(cyan("\n:: ")) + bold("Repository "+db+"\n\t")
+			}
+			str += fmt.Sprintf("%d) %s ", size, pkg.Name())
+			size++
+			return nil
+		})
+
+		fmt.Println(str)
+
+		for {
+			fmt.Print("\nEnter a number (default=1): ")
+
+			if config.NoConfirm {
+				fmt.Println()
+				break
+			}
+
+			reader := bufio.NewReader(os.Stdin)
+			numberBuf, overflow, err := reader.ReadLine()
+
+			if err != nil {
+				fmt.Println(err)
+				break
+			}
+
+			if overflow {
+				fmt.Println("Input too long")
+				continue
+			}
+
+			if string(numberBuf) == "" {
+				break
+			}
+
+			num, err := strconv.Atoi(string(numberBuf))
+			if err != nil {
+				fmt.Printf("%s invalid number: %s\n", red("error:"), string(numberBuf))
+				continue
+			}
+
+			if num < 1 || num > size {
+				fmt.Printf(" invalid value: %d is not between %d and %d\n", red("error: "), num, 1, size)
+				continue
+			}
+
+			qp.SetUseIndex(num - 1)
+			break
+		}
 	}
 }

+ 30 - 14
dependencies.go

@@ -1,6 +1,7 @@
 package main
 
 import (
+	"fmt"
 	"strings"
 
 	alpm "github.com/jguer/go-alpm"
@@ -13,6 +14,7 @@ type depTree struct {
 	Repo      map[string]*alpm.Package
 	Aur       map[string]*rpc.Pkg
 	Missing   stringSet
+	Groups    stringSet
 }
 
 type depCatagories struct {
@@ -28,6 +30,7 @@ func makeDepTree() *depTree {
 		make(map[string]*alpm.Package),
 		make(map[string]*rpc.Pkg),
 		make(stringSet),
+		make(stringSet),
 	}
 
 	return &dt
@@ -273,14 +276,9 @@ func getDepTree(pkgs []string) (*depTree, error) {
 	}
 
 	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
-		}//*/
-
 		db, name := splitDbFromName(pkg)
+		var foundPkg *alpm.Package
+		var singleDb *alpm.Db
 
 		if db == "aur" {
 			dt.ToProcess.set(name)
@@ -288,16 +286,30 @@ func getDepTree(pkgs []string) (*depTree, error) {
 		}
 
 		// Check the repos for a matching dep
-		foundPkg, errdb := syncDb.FindSatisfier(name)
-		found := errdb == nil && (foundPkg.DB().Name() == db || db == "")
-		if found {
-			repoTreeRecursive(foundPkg, dt, localDb, syncDb)
-			continue
+		if db != "" {
+			singleDb, err = alpmHandle.SyncDbByName(db)
+			if err != nil {
+				return dt, err
+			}
+			foundPkg, err = singleDb.PkgCache().FindSatisfier(name)
+		} else {
+			foundPkg, err = syncDb.FindSatisfier(name)
 		}
 
-		_, isGroup := syncDb.PkgCachebyGroup(name)
-		if isGroup == nil {
+		if err == nil {
+			repoTreeRecursive(foundPkg, dt, localDb, syncDb)
 			continue
+		} else {
+			//would be better to check the groups from singleDb if
+			//the user specified a db but theres no easy way to do
+			//it without making alpm_lists so dont bother for now
+			//db/group is probably a rare use case
+			_, err := syncDb.PkgCachebyGroup(name)
+
+			if err == nil {
+				dt.Groups.set(pkg)
+				continue
+			}
 		}
 
 		if db == "" {
@@ -307,6 +319,10 @@ func getDepTree(pkgs []string) (*depTree, error) {
 		}
 	}
 
+	if len(dt.ToProcess) > 0 {
+		fmt.Println(bold(cyan("::") + " Querying AUR..."))
+	}
+
 	err = depTreeRecursive(dt, localDb, syncDb, false)
 	if err != nil {
 		return dt, err

+ 8 - 19
install.go

@@ -17,7 +17,7 @@ import (
 // Install handles package installs
 func install(parser *arguments) error {
 	requestTargets := parser.targets.toSlice()
-	aurTargets, repoTargets, err := packageSlices(requestTargets)
+	var err error
 	if err != nil {
 		return err
 	}
@@ -36,19 +36,16 @@ func install(parser *arguments) error {
 
 	//cache as a stringset. maybe make it return a string set in the first
 	//place
-	remoteNamesCache := make(stringSet)
-	for _, name := range remoteNames {
-		remoteNamesCache.set(name)
-	}
+	remoteNamesCache := sliceToStringSet(remoteNames)
 
 	//if we are doing -u also request every non repo package on the system
 	if parser.existsArg("u", "sysupgrade") {
 		requestTargets = append(requestTargets, remoteNames...)
 	}
 
-	if len(aurTargets) > 0 || parser.existsArg("u", "sysupgrade") && len(remoteNames) > 0 {
-		fmt.Println(bold(cyan("::") + " Querying AUR..."))
-	}
+	//if len(aurTargets) > 0 || parser.existsArg("u", "sysupgrade") && len(remoteNames) > 0 {
+	//	fmt.Println(bold(cyan("::") + " Querying AUR..."))
+	//}
 	dt, err := getDepTree(requestTargets)
 	if err != nil {
 		return err
@@ -114,16 +111,8 @@ func install(parser *arguments) error {
 		arguments.addTarget(pkg.DB().Name() + "/" + pkg.Name())
 	}
 
-	dbList, err := alpmHandle.SyncDbs()
-	if err != nil {
-		return err
-	}
-	for _, pkg := range repoTargets {
-		_, name := splitDbFromName(pkg)
-		_, errdb := dbList.PkgCachebyGroup(name)
-		if errdb == nil {
-			arguments.addTarget(pkg)
-		}
+	for pkg := range dt.Groups {
+		arguments.addTarget(pkg)
 	}
 
 	if len(dc.Aur) == 0 && len(arguments.targets) == 0 {
@@ -156,7 +145,7 @@ func install(parser *arguments) error {
 		for _, pkg := range dc.Repo {
 			depArguments.addTarget(pkg.Name())
 		}
-		for _, pkg := range repoTargets {
+		for pkg := range dt.Repo {
 			depArguments.delTarget(pkg)
 		}
 

+ 12 - 3
query.go

@@ -236,6 +236,7 @@ func packageSlices(toCheck []string) (aur []string, repo []string, err error) {
 
 	for _, _pkg := range toCheck {
 		db, name := splitDbFromName(_pkg)
+		found := false
 
 		if db == "aur" {
 			aur = append(aur, _pkg)
@@ -245,11 +246,19 @@ func packageSlices(toCheck []string) (aur []string, repo []string, err error) {
 			continue
 		}
 
-		_, errdb := dbList.FindSatisfier(name)
-		found := errdb == nil
+		_ = dbList.ForEach(func(db alpm.Db) error {
+			_, err := db.PkgByName(name)
+
+			if err == nil {
+				found = true
+				return fmt.Errorf("")
+
+			}
+			return nil
+		})
 
 		if !found {
-			_, errdb = dbList.PkgCachebyGroup(name)
+			_, errdb := dbList.PkgCachebyGroup(name)
 			found = errdb == nil
 		}
 

+ 3 - 3
vcs.go

@@ -145,7 +145,7 @@ func (infos shaInfos) needsUpdate() bool {
 	//used to signal we have gone through all sources and found nothing
 	finished := make(chan struct{})
 	alive := 0
-	
+
 	//if we find an update we use this to exit early and return true
 	hasUpdate := make(chan struct{})
 
@@ -165,9 +165,9 @@ func (infos shaInfos) needsUpdate() bool {
 
 	for {
 		select {
-		case <- hasUpdate:
+		case <-hasUpdate:
 			return true
-		case <- finished:
+		case <-finished:
 			alive--
 			if alive == 0 {
 				return false