diff --git a/callbacks.go b/callbacks.go index cfec1a6e..0d8a7c0a 100644 --- a/callbacks.go +++ b/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 + } } } diff --git a/dependencies.go b/dependencies.go index 2599264c..0ed4d973 100644 --- a/dependencies.go +++ b/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 diff --git a/install.go b/install.go index 1e36e93d..b2e1d2d5 100644 --- a/install.go +++ b/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) } diff --git a/query.go b/query.go index 8974ab78..5a0be7bf 100644 --- a/query.go +++ b/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 } diff --git a/vcs.go b/vcs.go index dc517319..f6511c04 100644 --- a/vcs.go +++ b/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