mirror of
https://github.com/Jguer/yay.git
synced 2024-11-06 09:07:21 +01:00
Merge pull request #866 from Morganamilo/revert-depsolver
Revert "Merge pull request #767 from Morganamilo/merge-dep-pool-order"
This commit is contained in:
commit
6354a4424e
73
dep.go
73
dep.go
@ -8,11 +8,6 @@ import (
|
||||
rpc "github.com/mikkeloscar/aur"
|
||||
)
|
||||
|
||||
type missing struct {
|
||||
Good stringSet
|
||||
Missing map[string][][]string
|
||||
}
|
||||
|
||||
type providers struct {
|
||||
lookfor string
|
||||
Pkgs []*rpc.Pkg
|
||||
@ -45,74 +40,6 @@ func (q providers) Swap(i, j int) {
|
||||
q.Pkgs[i], q.Pkgs[j] = q.Pkgs[j], q.Pkgs[i]
|
||||
}
|
||||
|
||||
type Base []*rpc.Pkg
|
||||
|
||||
func (b Base) Pkgbase() string {
|
||||
return b[0].PackageBase
|
||||
}
|
||||
|
||||
func (b Base) Version() string {
|
||||
return b[0].Version
|
||||
}
|
||||
|
||||
func (b Base) URLPath() string {
|
||||
return b[0].URLPath
|
||||
}
|
||||
|
||||
func baseAppend(bases []Base, pkg *rpc.Pkg) []Base {
|
||||
for i, base := range bases {
|
||||
if base.Pkgbase() == pkg.PackageBase {
|
||||
bases[i] = append(bases[i], pkg)
|
||||
return bases
|
||||
}
|
||||
}
|
||||
|
||||
return append(bases, Base{pkg})
|
||||
}
|
||||
|
||||
func baseFind(bases []Base, name string) *rpc.Pkg {
|
||||
for _, base := range bases {
|
||||
for _, pkg := range base {
|
||||
if pkg.Name == name {
|
||||
return pkg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type target struct {
|
||||
Db string
|
||||
Name string
|
||||
Mod string
|
||||
Version string
|
||||
}
|
||||
|
||||
func toTarget(pkg string) target {
|
||||
db, dep := splitDbFromName(pkg)
|
||||
name, mod, version := splitDep(dep)
|
||||
|
||||
return target{
|
||||
db,
|
||||
name,
|
||||
mod,
|
||||
version,
|
||||
}
|
||||
}
|
||||
|
||||
func (t target) DepString() string {
|
||||
return t.Name + t.Mod + t.Version
|
||||
}
|
||||
|
||||
func (t target) String() string {
|
||||
if t.Db != "" {
|
||||
return t.Db + "/" + t.DepString()
|
||||
}
|
||||
|
||||
return t.DepString()
|
||||
}
|
||||
|
||||
func splitDep(dep string) (string, string, string) {
|
||||
mod := ""
|
||||
|
||||
|
411
depCheck.go
411
depCheck.go
@ -7,105 +7,41 @@ import (
|
||||
"sync"
|
||||
|
||||
alpm "github.com/jguer/go-alpm"
|
||||
rpc "github.com/mikkeloscar/aur"
|
||||
)
|
||||
|
||||
func (ds *depSolver) _checkMissing(dep string, stack []string, missing *missing) {
|
||||
if missing.Good.get(dep) {
|
||||
return
|
||||
}
|
||||
|
||||
if trees, ok := missing.Missing[dep]; ok {
|
||||
for _, tree := range trees {
|
||||
if stringSliceEqual(tree, stack) {
|
||||
return
|
||||
}
|
||||
}
|
||||
missing.Missing[dep] = append(missing.Missing[dep], stack)
|
||||
return
|
||||
}
|
||||
|
||||
aurPkg := ds.findSatisfierAur(dep)
|
||||
if aurPkg != nil {
|
||||
missing.Good.set(dep)
|
||||
for _, deps := range [3][]string{aurPkg.Depends, aurPkg.MakeDepends, aurPkg.CheckDepends} {
|
||||
for _, aurDep := range deps {
|
||||
if _, err := ds.LocalDb.PkgCache().FindSatisfier(aurDep); err == nil {
|
||||
missing.Good.set(aurDep)
|
||||
continue
|
||||
}
|
||||
|
||||
ds._checkMissing(aurDep, append(stack, aurPkg.Name), missing)
|
||||
}
|
||||
func (dp *depPool) checkInnerConflict(name string, conflict string, conflicts mapStringSet) {
|
||||
for _, pkg := range dp.Aur {
|
||||
if pkg.Name == name {
|
||||
continue
|
||||
}
|
||||
|
||||
return
|
||||
if satisfiesAur(conflict, pkg) {
|
||||
conflicts.Add(name, pkg.Name)
|
||||
}
|
||||
}
|
||||
|
||||
repoPkg := ds.findSatisfierRepo(dep)
|
||||
if repoPkg != nil {
|
||||
missing.Good.set(dep)
|
||||
repoPkg.Depends().ForEach(func(repoDep alpm.Depend) error {
|
||||
if _, err := ds.LocalDb.PkgCache().FindSatisfier(repoDep.String()); err == nil {
|
||||
missing.Good.set(repoDep.String())
|
||||
return nil
|
||||
}
|
||||
for _, pkg := range dp.Repo {
|
||||
if pkg.Name() == name {
|
||||
continue
|
||||
}
|
||||
|
||||
ds._checkMissing(repoDep.String(), append(stack, repoPkg.Name()), missing)
|
||||
return nil
|
||||
})
|
||||
|
||||
return
|
||||
if satisfiesRepo(conflict, pkg) {
|
||||
conflicts.Add(name, pkg.Name())
|
||||
}
|
||||
}
|
||||
|
||||
missing.Missing[dep] = [][]string{stack}
|
||||
}
|
||||
|
||||
func (ds *depSolver) CheckMissing() error {
|
||||
missing := &missing{
|
||||
make(stringSet),
|
||||
make(map[string][][]string),
|
||||
}
|
||||
|
||||
for _, target := range ds.Targets {
|
||||
ds._checkMissing(target.DepString(), make([]string, 0), missing)
|
||||
}
|
||||
|
||||
if len(missing.Missing) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stderr, bold(red(arrow+" Error: "))+"Could not find all required packages:")
|
||||
for dep, trees := range missing.Missing {
|
||||
for _, tree := range trees {
|
||||
|
||||
fmt.Fprint(os.Stderr, " ", cyan(dep))
|
||||
|
||||
if len(tree) == 0 {
|
||||
fmt.Fprint(os.Stderr, " (Target")
|
||||
} else {
|
||||
fmt.Fprint(os.Stderr, " (Wanted by: ")
|
||||
for n := 0; n < len(tree)-1; n++ {
|
||||
fmt.Fprint(os.Stderr, cyan(tree[n]), " -> ")
|
||||
}
|
||||
fmt.Fprint(os.Stderr, cyan(tree[len(tree)-1]))
|
||||
}
|
||||
|
||||
fmt.Fprintln(os.Stderr, ")")
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("")
|
||||
}
|
||||
|
||||
func (ds *depSolver) checkForwardConflict(name string, conflict string, conflicts mapStringSet) {
|
||||
ds.LocalDb.PkgCache().ForEach(func(pkg alpm.Package) error {
|
||||
if pkg.Name() == name || ds.hasPackage(pkg.Name()) {
|
||||
func (dp *depPool) checkForwardConflict(name string, conflict string, conflicts mapStringSet) {
|
||||
dp.LocalDb.PkgCache().ForEach(func(pkg alpm.Package) error {
|
||||
if pkg.Name() == name || dp.hasPackage(pkg.Name()) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if satisfiesRepo(conflict, &pkg) {
|
||||
n := pkg.Name()
|
||||
if n != conflict {
|
||||
n += " (" + conflict + ")"
|
||||
}
|
||||
conflicts.Add(name, n)
|
||||
}
|
||||
|
||||
@ -113,55 +49,74 @@ func (ds *depSolver) checkForwardConflict(name string, conflict string, conflict
|
||||
})
|
||||
}
|
||||
|
||||
func (ds *depSolver) checkReverseConflict(name string, conflict string, conflicts mapStringSet) {
|
||||
for _, base := range ds.Aur {
|
||||
for _, pkg := range base {
|
||||
if pkg.Name == name {
|
||||
continue
|
||||
func (dp *depPool) checkReverseConflict(name string, conflict string, conflicts mapStringSet) {
|
||||
for _, pkg := range dp.Aur {
|
||||
if pkg.Name == name {
|
||||
continue
|
||||
}
|
||||
|
||||
if satisfiesAur(conflict, pkg) {
|
||||
if name != conflict {
|
||||
name += " (" + conflict + ")"
|
||||
}
|
||||
|
||||
if satisfiesAur(conflict, pkg) {
|
||||
conflicts.Add(pkg.Name, name)
|
||||
}
|
||||
conflicts.Add(pkg.Name, name)
|
||||
}
|
||||
}
|
||||
|
||||
for _, pkg := range ds.Repo {
|
||||
for _, pkg := range dp.Repo {
|
||||
if pkg.Name() == name {
|
||||
continue
|
||||
}
|
||||
|
||||
if satisfiesRepo(conflict, pkg) {
|
||||
if name != conflict {
|
||||
name += " (" + conflict + ")"
|
||||
}
|
||||
|
||||
conflicts.Add(pkg.Name(), name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ds *depSolver) checkForwardConflicts(conflicts mapStringSet) {
|
||||
for _, base := range ds.Aur {
|
||||
for _, pkg := range base {
|
||||
for _, conflict := range pkg.Conflicts {
|
||||
ds.checkForwardConflict(pkg.Name, conflict, conflicts)
|
||||
}
|
||||
func (dp *depPool) checkInnerConflicts(conflicts mapStringSet) {
|
||||
for _, pkg := range dp.Aur {
|
||||
for _, conflict := range pkg.Conflicts {
|
||||
dp.checkInnerConflict(pkg.Name, conflict, conflicts)
|
||||
}
|
||||
}
|
||||
|
||||
for _, pkg := range ds.Repo {
|
||||
for _, pkg := range dp.Repo {
|
||||
pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
|
||||
ds.checkForwardConflict(pkg.Name(), conflict.String(), conflicts)
|
||||
dp.checkInnerConflict(pkg.Name(), conflict.String(), conflicts)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (ds *depSolver) checkReverseConflicts(conflicts mapStringSet) {
|
||||
ds.LocalDb.PkgCache().ForEach(func(pkg alpm.Package) error {
|
||||
if ds.hasPackage(pkg.Name()) {
|
||||
func (dp *depPool) checkForwardConflicts(conflicts mapStringSet) {
|
||||
for _, pkg := range dp.Aur {
|
||||
for _, conflict := range pkg.Conflicts {
|
||||
dp.checkForwardConflict(pkg.Name, conflict, conflicts)
|
||||
}
|
||||
}
|
||||
|
||||
for _, pkg := range dp.Repo {
|
||||
pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
|
||||
dp.checkForwardConflict(pkg.Name(), conflict.String(), conflicts)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (dp *depPool) checkReverseConflicts(conflicts mapStringSet) {
|
||||
dp.LocalDb.PkgCache().ForEach(func(pkg alpm.Package) error {
|
||||
if dp.hasPackage(pkg.Name()) {
|
||||
return nil
|
||||
}
|
||||
|
||||
pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
|
||||
ds.checkReverseConflict(pkg.Name(), conflict.String(), conflicts)
|
||||
dp.checkReverseConflict(pkg.Name(), conflict.String(), conflicts)
|
||||
return nil
|
||||
})
|
||||
|
||||
@ -169,147 +124,66 @@ func (ds *depSolver) checkReverseConflicts(conflicts mapStringSet) {
|
||||
})
|
||||
}
|
||||
|
||||
func (ds *depSolver) checkInnerRepoConflicts(conflicts mapStringSet) {
|
||||
for _, pkg := range ds.Repo {
|
||||
pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
|
||||
for _, innerpkg := range ds.Repo {
|
||||
if pkg.Name() != innerpkg.Name() && satisfiesRepo(conflict.String(), innerpkg) {
|
||||
conflicts.Add(pkg.Name(), innerpkg.Name())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (ds *depSolver) checkInnerConflicts(conflicts mapStringSet) {
|
||||
removed := make(stringSet)
|
||||
//ds.checkInnerConflictRepoAur(conflicts)
|
||||
|
||||
for current, currbase := range ds.Aur {
|
||||
for _, pkg := range currbase {
|
||||
ds.checkInnerConflict(pkg, ds.Aur[:current], removed, conflicts)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if anything conflicts with currpkg
|
||||
// If so add the conflict with currpkg being removed by the conflicting pkg
|
||||
func (ds *depSolver) checkInnerConflict(currpkg *rpc.Pkg, aur []Base, removed stringSet, conflicts mapStringSet) {
|
||||
for _, base := range aur {
|
||||
for _, pkg := range base {
|
||||
for _, conflict := range pkg.Conflicts {
|
||||
if !removed.get(pkg.Name) && satisfiesAur(conflict, currpkg) {
|
||||
addInnerConflict(pkg.Name, currpkg.Name, removed, conflicts)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, pkg := range ds.Repo {
|
||||
pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
|
||||
if !removed.get(pkg.Name()) && satisfiesAur(conflict.String(), currpkg) {
|
||||
addInnerConflict(pkg.Name(), currpkg.Name, removed, conflicts)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
for _, conflict := range currpkg.Conflicts {
|
||||
for _, base := range aur {
|
||||
for _, pkg := range base {
|
||||
if !removed.get(pkg.Name) && satisfiesAur(conflict, pkg) {
|
||||
addInnerConflict(pkg.Name, currpkg.Name, removed, conflicts)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, pkg := range ds.Repo {
|
||||
if !removed.get(pkg.Name()) && satisfiesRepo(conflict, pkg) {
|
||||
addInnerConflict(pkg.Name(), currpkg.Name, removed, conflicts)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func addInnerConflict(toRemove string, removedBy string, removed stringSet, conflicts mapStringSet) {
|
||||
conflicts.Add(removedBy, toRemove)
|
||||
removed.set(toRemove)
|
||||
}
|
||||
|
||||
func (ds *depSolver) CheckConflicts() (mapStringSet, error) {
|
||||
func (dp *depPool) CheckConflicts() (mapStringSet, error) {
|
||||
var wg sync.WaitGroup
|
||||
innerConflicts := make(mapStringSet)
|
||||
conflicts := make(mapStringSet)
|
||||
repoConflicts := make(mapStringSet)
|
||||
wg.Add(3)
|
||||
wg.Add(2)
|
||||
|
||||
fmt.Println(bold(cyan("::") + bold(" Checking for conflicts...")))
|
||||
go func() {
|
||||
ds.checkForwardConflicts(conflicts)
|
||||
ds.checkReverseConflicts(conflicts)
|
||||
dp.checkForwardConflicts(conflicts)
|
||||
dp.checkReverseConflicts(conflicts)
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
fmt.Println(bold(cyan("::") + bold(" Checking for inner conflicts...")))
|
||||
go func() {
|
||||
ds.checkInnerConflicts(innerConflicts)
|
||||
wg.Done()
|
||||
}()
|
||||
go func() {
|
||||
ds.checkInnerRepoConflicts(repoConflicts)
|
||||
dp.checkInnerConflicts(innerConflicts)
|
||||
wg.Done()
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
|
||||
formatConflicts := func(conflicts mapStringSet, inner bool, s string) {
|
||||
if len(conflicts) != 0 {
|
||||
fmt.Fprintln(os.Stderr)
|
||||
if inner {
|
||||
fmt.Fprintln(os.Stderr, bold(red(arrow)), bold("Inner conflicts found:"))
|
||||
} else {
|
||||
fmt.Fprintln(os.Stderr, bold(red(arrow)), bold("Package conflicts found:"))
|
||||
}
|
||||
if len(innerConflicts) != 0 {
|
||||
fmt.Println()
|
||||
fmt.Println(bold(red(arrow)), bold("Inner conflicts found:"))
|
||||
|
||||
printConflict := func(name string, pkgs stringSet) {
|
||||
str := fmt.Sprintf(s, cyan(name))
|
||||
for pkg := range pkgs {
|
||||
str += " " + cyan(pkg) + ","
|
||||
}
|
||||
str = strings.TrimSuffix(str, ",")
|
||||
for name, pkgs := range innerConflicts {
|
||||
str := red(bold(smallArrow)) + " " + name + ":"
|
||||
for pkg := range pkgs {
|
||||
str += " " + cyan(pkg) + ","
|
||||
}
|
||||
str = strings.TrimSuffix(str, ",")
|
||||
|
||||
fmt.Fprintln(os.Stderr, str)
|
||||
}
|
||||
|
||||
for _, pkg := range ds.Repo {
|
||||
if pkgs, ok := conflicts[pkg.Name()]; ok {
|
||||
printConflict(pkg.Name(), pkgs)
|
||||
}
|
||||
}
|
||||
for _, base := range ds.Aur {
|
||||
for _, pkg := range base {
|
||||
if pkgs, ok := conflicts[pkg.Name]; ok {
|
||||
printConflict(pkg.Name, pkgs)
|
||||
}
|
||||
}
|
||||
}
|
||||
fmt.Println(str)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
repoStr := red(bold(smallArrow)) + " %s Conflicts with:"
|
||||
formatConflicts(repoConflicts, true, repoStr)
|
||||
if len(conflicts) != 0 {
|
||||
fmt.Println()
|
||||
fmt.Println(bold(red(arrow)), bold("Package conflicts found:"))
|
||||
|
||||
for name, pkgs := range conflicts {
|
||||
str := red(bold(smallArrow)) + " Installing " + cyan(name) + " will remove:"
|
||||
for pkg := range pkgs {
|
||||
str += " " + cyan(pkg) + ","
|
||||
}
|
||||
str = strings.TrimSuffix(str, ",")
|
||||
|
||||
fmt.Println(str)
|
||||
}
|
||||
|
||||
if len(repoConflicts) > 0 {
|
||||
return nil, fmt.Errorf("Unavoidable conflicts, aborting")
|
||||
}
|
||||
|
||||
str := red(bold(smallArrow)) + " Installing %s will remove:"
|
||||
formatConflicts(conflicts, false, str)
|
||||
formatConflicts(innerConflicts, true, str)
|
||||
|
||||
for name, c := range innerConflicts {
|
||||
for cs, _ := range c {
|
||||
conflicts.Add(name, cs)
|
||||
// Add the inner conflicts to the conflicts
|
||||
// These are used to decide what to pass --ask to (if set) or don't pass --noconfirm to
|
||||
// As we have no idea what the order is yet we add every inner conflict to the slice
|
||||
for name, pkgs := range innerConflicts {
|
||||
conflicts[name] = make(stringSet)
|
||||
for pkg := range pkgs {
|
||||
conflicts[pkg] = make(stringSet)
|
||||
}
|
||||
}
|
||||
|
||||
@ -327,3 +201,96 @@ func (ds *depSolver) CheckConflicts() (mapStringSet, error) {
|
||||
|
||||
return conflicts, nil
|
||||
}
|
||||
|
||||
type missing struct {
|
||||
Good stringSet
|
||||
Missing map[string][][]string
|
||||
}
|
||||
|
||||
func (dp *depPool) _checkMissing(dep string, stack []string, missing *missing) {
|
||||
if missing.Good.get(dep) {
|
||||
return
|
||||
}
|
||||
|
||||
if trees, ok := missing.Missing[dep]; ok {
|
||||
for _, tree := range trees {
|
||||
if stringSliceEqual(tree, stack) {
|
||||
return
|
||||
}
|
||||
}
|
||||
missing.Missing[dep] = append(missing.Missing[dep], stack)
|
||||
return
|
||||
}
|
||||
|
||||
aurPkg := dp.findSatisfierAur(dep)
|
||||
if aurPkg != nil {
|
||||
missing.Good.set(dep)
|
||||
for _, deps := range [3][]string{aurPkg.Depends, aurPkg.MakeDepends, aurPkg.CheckDepends} {
|
||||
for _, aurDep := range deps {
|
||||
if _, err := dp.LocalDb.PkgCache().FindSatisfier(aurDep); err == nil {
|
||||
missing.Good.set(aurDep)
|
||||
continue
|
||||
}
|
||||
|
||||
dp._checkMissing(aurDep, append(stack, aurPkg.Name), missing)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
repoPkg := dp.findSatisfierRepo(dep)
|
||||
if repoPkg != nil {
|
||||
missing.Good.set(dep)
|
||||
repoPkg.Depends().ForEach(func(repoDep alpm.Depend) error {
|
||||
if _, err := dp.LocalDb.PkgCache().FindSatisfier(repoDep.String()); err == nil {
|
||||
missing.Good.set(repoDep.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
dp._checkMissing(repoDep.String(), append(stack, repoPkg.Name()), missing)
|
||||
return nil
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
missing.Missing[dep] = [][]string{stack}
|
||||
}
|
||||
|
||||
func (dp *depPool) CheckMissing() error {
|
||||
missing := &missing{
|
||||
make(stringSet),
|
||||
make(map[string][][]string),
|
||||
}
|
||||
|
||||
for _, target := range dp.Targets {
|
||||
dp._checkMissing(target.DepString(), make([]string, 0), missing)
|
||||
}
|
||||
|
||||
if len(missing.Missing) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Println(bold(red(arrow+" Error: ")) + "Could not find all required packages:")
|
||||
for dep, trees := range missing.Missing {
|
||||
for _, tree := range trees {
|
||||
|
||||
fmt.Print(" ", cyan(dep))
|
||||
|
||||
if len(tree) == 0 {
|
||||
fmt.Print(" (Target")
|
||||
} else {
|
||||
fmt.Print(" (Wanted by: ")
|
||||
for n := 0; n < len(tree)-1; n++ {
|
||||
fmt.Print(cyan(tree[n]), " -> ")
|
||||
}
|
||||
fmt.Print(cyan(tree[len(tree)-1]))
|
||||
}
|
||||
|
||||
fmt.Println(")")
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("")
|
||||
}
|
||||
|
135
depOrder.go
Normal file
135
depOrder.go
Normal file
@ -0,0 +1,135 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
alpm "github.com/jguer/go-alpm"
|
||||
rpc "github.com/mikkeloscar/aur"
|
||||
)
|
||||
|
||||
type Base []*rpc.Pkg
|
||||
|
||||
func (b Base) Pkgbase() string {
|
||||
return b[0].PackageBase
|
||||
}
|
||||
|
||||
func (b Base) Version() string {
|
||||
return b[0].Version
|
||||
}
|
||||
|
||||
func (b Base) URLPath() string {
|
||||
return b[0].URLPath
|
||||
}
|
||||
|
||||
type depOrder struct {
|
||||
Aur []Base
|
||||
Repo []*alpm.Package
|
||||
Runtime stringSet
|
||||
}
|
||||
|
||||
func makeDepOrder() *depOrder {
|
||||
return &depOrder{
|
||||
make([]Base, 0),
|
||||
make([]*alpm.Package, 0),
|
||||
make(stringSet),
|
||||
}
|
||||
}
|
||||
|
||||
func getDepOrder(dp *depPool) *depOrder {
|
||||
do := makeDepOrder()
|
||||
|
||||
for _, target := range dp.Targets {
|
||||
dep := target.DepString()
|
||||
aurPkg := dp.Aur[dep]
|
||||
if aurPkg != nil && pkgSatisfies(aurPkg.Name, aurPkg.Version, dep) {
|
||||
do.orderPkgAur(aurPkg, dp, true)
|
||||
}
|
||||
|
||||
aurPkg = dp.findSatisfierAur(dep)
|
||||
if aurPkg != nil {
|
||||
do.orderPkgAur(aurPkg, dp, true)
|
||||
}
|
||||
|
||||
repoPkg := dp.findSatisfierRepo(dep)
|
||||
if repoPkg != nil {
|
||||
do.orderPkgRepo(repoPkg, dp, true)
|
||||
}
|
||||
}
|
||||
|
||||
return do
|
||||
}
|
||||
|
||||
func (do *depOrder) orderPkgAur(pkg *rpc.Pkg, dp *depPool, runtime bool) {
|
||||
if runtime {
|
||||
do.Runtime.set(pkg.Name)
|
||||
}
|
||||
delete(dp.Aur, pkg.Name)
|
||||
|
||||
for i, deps := range [3][]string{pkg.Depends, pkg.MakeDepends, pkg.CheckDepends} {
|
||||
for _, dep := range deps {
|
||||
aurPkg := dp.findSatisfierAur(dep)
|
||||
if aurPkg != nil {
|
||||
do.orderPkgAur(aurPkg, dp, runtime && i == 0)
|
||||
}
|
||||
|
||||
repoPkg := dp.findSatisfierRepo(dep)
|
||||
if repoPkg != nil {
|
||||
do.orderPkgRepo(repoPkg, dp, runtime && i == 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for i, base := range do.Aur {
|
||||
if base.Pkgbase() == pkg.PackageBase {
|
||||
do.Aur[i] = append(base, pkg)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
do.Aur = append(do.Aur, Base{pkg})
|
||||
}
|
||||
|
||||
func (do *depOrder) orderPkgRepo(pkg *alpm.Package, dp *depPool, runtime bool) {
|
||||
if runtime {
|
||||
do.Runtime.set(pkg.Name())
|
||||
}
|
||||
delete(dp.Repo, pkg.Name())
|
||||
|
||||
pkg.Depends().ForEach(func(dep alpm.Depend) (err error) {
|
||||
repoPkg := dp.findSatisfierRepo(dep.String())
|
||||
if repoPkg != nil {
|
||||
do.orderPkgRepo(repoPkg, dp, runtime)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
do.Repo = append(do.Repo, pkg)
|
||||
}
|
||||
|
||||
func (do *depOrder) HasMake() bool {
|
||||
lenAur := 0
|
||||
for _, base := range do.Aur {
|
||||
lenAur += len(base)
|
||||
}
|
||||
|
||||
return len(do.Runtime) != lenAur+len(do.Repo)
|
||||
}
|
||||
|
||||
func (do *depOrder) getMake() []string {
|
||||
makeOnly := make([]string, 0, len(do.Aur)+len(do.Repo)-len(do.Runtime))
|
||||
|
||||
for _, base := range do.Aur {
|
||||
for _, pkg := range base {
|
||||
if !do.Runtime.get(pkg.Name) {
|
||||
makeOnly = append(makeOnly, pkg.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, pkg := range do.Repo {
|
||||
if !do.Runtime.get(pkg.Name()) {
|
||||
makeOnly = append(makeOnly, pkg.Name())
|
||||
}
|
||||
}
|
||||
|
||||
return makeOnly
|
||||
}
|
477
depPool.go
Normal file
477
depPool.go
Normal file
@ -0,0 +1,477 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
alpm "github.com/jguer/go-alpm"
|
||||
rpc "github.com/mikkeloscar/aur"
|
||||
)
|
||||
|
||||
type target struct {
|
||||
Db string
|
||||
Name string
|
||||
Mod string
|
||||
Version string
|
||||
}
|
||||
|
||||
func toTarget(pkg string) target {
|
||||
db, dep := splitDbFromName(pkg)
|
||||
name, mod, version := splitDep(dep)
|
||||
|
||||
return target{
|
||||
db,
|
||||
name,
|
||||
mod,
|
||||
version,
|
||||
}
|
||||
}
|
||||
|
||||
func (t target) DepString() string {
|
||||
return t.Name + t.Mod + t.Version
|
||||
}
|
||||
|
||||
func (t target) String() string {
|
||||
if t.Db != "" {
|
||||
return t.Db + "/" + t.DepString()
|
||||
}
|
||||
|
||||
return t.DepString()
|
||||
}
|
||||
|
||||
type depPool struct {
|
||||
Targets []target
|
||||
Explicit stringSet
|
||||
Repo map[string]*alpm.Package
|
||||
Aur map[string]*rpc.Pkg
|
||||
AurCache map[string]*rpc.Pkg
|
||||
Groups []string
|
||||
LocalDb *alpm.Db
|
||||
SyncDb alpm.DbList
|
||||
Warnings *aurWarnings
|
||||
}
|
||||
|
||||
func makeDepPool() (*depPool, error) {
|
||||
localDb, err := alpmHandle.LocalDb()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
syncDb, err := alpmHandle.SyncDbs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dp := &depPool{
|
||||
make([]target, 0),
|
||||
make(stringSet),
|
||||
make(map[string]*alpm.Package),
|
||||
make(map[string]*rpc.Pkg),
|
||||
make(map[string]*rpc.Pkg),
|
||||
make([]string, 0),
|
||||
localDb,
|
||||
syncDb,
|
||||
nil,
|
||||
}
|
||||
|
||||
return dp, nil
|
||||
}
|
||||
|
||||
// Includes db/ prefixes and group installs
|
||||
func (dp *depPool) ResolveTargets(pkgs []string) error {
|
||||
// RPC requests are slow
|
||||
// Combine as many AUR package requests as possible into a single RPC
|
||||
// call
|
||||
aurTargets := make(stringSet)
|
||||
|
||||
pkgs = removeInvalidTargets(pkgs)
|
||||
|
||||
for _, pkg := range pkgs {
|
||||
var err error
|
||||
target := toTarget(pkg)
|
||||
|
||||
// skip targets already satisfied
|
||||
// even if the user enters db/pkg and aur/pkg the latter will
|
||||
// still get skipped even if it's from a different database to
|
||||
// the one specified
|
||||
// this is how pacman behaves
|
||||
if dp.hasPackage(target.DepString()) {
|
||||
continue
|
||||
}
|
||||
|
||||
var foundPkg *alpm.Package
|
||||
var singleDb *alpm.Db
|
||||
|
||||
// aur/ prefix means we only check the aur
|
||||
if target.Db == "aur" || mode == modeAUR {
|
||||
dp.Targets = append(dp.Targets, target)
|
||||
aurTargets.set(target.DepString())
|
||||
continue
|
||||
}
|
||||
|
||||
// If there'ss a different priefix only look in that repo
|
||||
if target.Db != "" {
|
||||
singleDb, err = alpmHandle.SyncDbByName(target.Db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
foundPkg, err = singleDb.PkgCache().FindSatisfier(target.DepString())
|
||||
//otherwise find it in any repo
|
||||
} else {
|
||||
foundPkg, err = dp.SyncDb.FindSatisfier(target.DepString())
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
dp.Targets = append(dp.Targets, target)
|
||||
dp.Explicit.set(foundPkg.Name())
|
||||
dp.ResolveRepoDependency(foundPkg)
|
||||
continue
|
||||
} else {
|
||||
//check for groups
|
||||
//currently we don't resolve the packages in a group
|
||||
//only check if the group exists
|
||||
//would be better to check the groups from singleDb if
|
||||
//the user specified a db but there's no easy way to do
|
||||
//it without making alpm_lists so don't bother for now
|
||||
//db/group is probably a rare use case
|
||||
group, err := dp.SyncDb.PkgCachebyGroup(target.Name)
|
||||
if err == nil {
|
||||
dp.Groups = append(dp.Groups, target.String())
|
||||
group.ForEach(func(pkg alpm.Package) error {
|
||||
dp.Explicit.set(pkg.Name())
|
||||
return nil
|
||||
})
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
//if there was no db prefix check the aur
|
||||
if target.Db == "" {
|
||||
aurTargets.set(target.DepString())
|
||||
}
|
||||
|
||||
dp.Targets = append(dp.Targets, target)
|
||||
}
|
||||
|
||||
if len(aurTargets) > 0 && (mode == modeAny || mode == modeAUR) {
|
||||
return dp.resolveAURPackages(aurTargets, true)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Pseudo provides finder.
|
||||
// Try to find provides by performing a search of the package name
|
||||
// This effectively performs -Ss on each package
|
||||
// then runs -Si on each result to cache the information.
|
||||
//
|
||||
// For example if you were to -S yay then yay -Ss would give:
|
||||
// yay-git yay-bin yay realyog pacui pacui-git ruby-yard
|
||||
// These packages will all be added to the cache in case they are needed later
|
||||
// Ofcouse only the first three packages provide yay, the rest are just false
|
||||
// positives.
|
||||
//
|
||||
// This method increases dependency resolve time
|
||||
func (dp *depPool) findProvides(pkgs stringSet) error {
|
||||
var mux sync.Mutex
|
||||
var wg sync.WaitGroup
|
||||
|
||||
doSearch := func(pkg string) {
|
||||
defer wg.Done()
|
||||
var err error
|
||||
var results []rpc.Pkg
|
||||
|
||||
// Hack for a bigger search result, if the user wants
|
||||
// java-envronment we can search for just java instead and get
|
||||
// more hits.
|
||||
words := strings.Split(pkg, "-")
|
||||
|
||||
for i := range words {
|
||||
results, err = rpc.SearchByNameDesc(strings.Join(words[:i+1], "-"))
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, result := range results {
|
||||
mux.Lock()
|
||||
if _, ok := dp.AurCache[result.Name]; !ok {
|
||||
pkgs.set(result.Name)
|
||||
}
|
||||
mux.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
for pkg := range pkgs {
|
||||
if _, err := dp.LocalDb.PkgByName(pkg); err == nil {
|
||||
continue
|
||||
}
|
||||
wg.Add(1)
|
||||
go doSearch(pkg)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dp *depPool) cacheAURPackages(_pkgs stringSet) error {
|
||||
pkgs := _pkgs.copy()
|
||||
query := make([]string, 0)
|
||||
|
||||
for pkg := range pkgs {
|
||||
if _, ok := dp.AurCache[pkg]; ok {
|
||||
pkgs.remove(pkg)
|
||||
}
|
||||
}
|
||||
|
||||
if len(pkgs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if config.Provides {
|
||||
err := dp.findProvides(pkgs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for pkg := range pkgs {
|
||||
if _, ok := dp.AurCache[pkg]; !ok {
|
||||
name, _, _ := splitDep(pkg)
|
||||
query = append(query, name)
|
||||
}
|
||||
}
|
||||
|
||||
info, err := aurInfo(query, dp.Warnings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, pkg := range info {
|
||||
// Dump everything in cache just in case we need it later
|
||||
dp.AurCache[pkg.Name] = pkg
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dp *depPool) resolveAURPackages(pkgs stringSet, explicit bool) error {
|
||||
newPackages := make(stringSet)
|
||||
newAURPackages := make(stringSet)
|
||||
|
||||
err := dp.cacheAURPackages(pkgs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(pkgs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for name := range pkgs {
|
||||
_, ok := dp.Aur[name]
|
||||
if ok {
|
||||
continue
|
||||
}
|
||||
|
||||
pkg := dp.findSatisfierAurCache(name)
|
||||
if pkg == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if explicit {
|
||||
dp.Explicit.set(pkg.Name)
|
||||
}
|
||||
dp.Aur[pkg.Name] = pkg
|
||||
|
||||
for _, deps := range [3][]string{pkg.Depends, pkg.MakeDepends, pkg.CheckDepends} {
|
||||
for _, dep := range deps {
|
||||
newPackages.set(dep)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for dep := range newPackages {
|
||||
if dp.hasSatisfier(dep) {
|
||||
continue
|
||||
}
|
||||
|
||||
_, isInstalled := dp.LocalDb.PkgCache().FindSatisfier(dep) //has satisfier installed: skip
|
||||
hm := hideMenus
|
||||
hideMenus = isInstalled == nil
|
||||
repoPkg, inRepos := dp.SyncDb.FindSatisfier(dep) //has satisfier in repo: fetch it
|
||||
hideMenus = hm
|
||||
if isInstalled == nil && (config.ReBuild != "tree" || inRepos == nil) {
|
||||
continue
|
||||
}
|
||||
|
||||
if inRepos == nil {
|
||||
dp.ResolveRepoDependency(repoPkg)
|
||||
continue
|
||||
}
|
||||
|
||||
//assume it's in the aur
|
||||
//ditch the versioning because the RPC can't handle it
|
||||
newAURPackages.set(dep)
|
||||
|
||||
}
|
||||
|
||||
err = dp.resolveAURPackages(newAURPackages, false)
|
||||
return err
|
||||
}
|
||||
|
||||
func (dp *depPool) ResolveRepoDependency(pkg *alpm.Package) {
|
||||
dp.Repo[pkg.Name()] = pkg
|
||||
|
||||
pkg.Depends().ForEach(func(dep alpm.Depend) (err error) {
|
||||
//have satisfier in dep tree: skip
|
||||
if dp.hasSatisfier(dep.String()) {
|
||||
return
|
||||
}
|
||||
|
||||
//has satisfier installed: skip
|
||||
_, isInstalled := dp.LocalDb.PkgCache().FindSatisfier(dep.String())
|
||||
if isInstalled == nil {
|
||||
return
|
||||
}
|
||||
|
||||
//has satisfier in repo: fetch it
|
||||
repoPkg, inRepos := dp.SyncDb.FindSatisfier(dep.String())
|
||||
if inRepos != nil {
|
||||
return
|
||||
}
|
||||
|
||||
dp.ResolveRepoDependency(repoPkg)
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func getDepPool(pkgs []string, warnings *aurWarnings) (*depPool, error) {
|
||||
dp, err := makeDepPool()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dp.Warnings = warnings
|
||||
err = dp.ResolveTargets(pkgs)
|
||||
|
||||
return dp, err
|
||||
}
|
||||
|
||||
func (dp *depPool) findSatisfierAur(dep string) *rpc.Pkg {
|
||||
for _, pkg := range dp.Aur {
|
||||
if satisfiesAur(dep, pkg) {
|
||||
return pkg
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// This is mostly used to promote packages from the cache
|
||||
// to the Install list
|
||||
// Provide a pacman style provider menu if there's more than one candidate
|
||||
// This acts slightly differently from Pacman, It will give
|
||||
// a menu even if a package with a matching name exists. I believe this
|
||||
// method is better because most of the time you are choosing between
|
||||
// foo and foo-git.
|
||||
// Using Pacman's ways trying to install foo would never give you
|
||||
// a menu.
|
||||
// TODO: maybe intermix repo providers in the menu
|
||||
func (dp *depPool) findSatisfierAurCache(dep string) *rpc.Pkg {
|
||||
depName, _, _ := splitDep(dep)
|
||||
seen := make(stringSet)
|
||||
providers := makeProviders(depName)
|
||||
|
||||
if _, err := dp.LocalDb.PkgByName(depName); err == nil {
|
||||
if pkg, ok := dp.AurCache[dep]; ok && pkgSatisfies(pkg.Name, pkg.Version, dep) {
|
||||
return pkg
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if cmdArgs.op == "Y" || cmdArgs.op == "yay" {
|
||||
for _, pkg := range dp.AurCache {
|
||||
if pkgSatisfies(pkg.Name, pkg.Version, dep) {
|
||||
for _, target := range dp.Targets {
|
||||
if target.Name == pkg.Name {
|
||||
return pkg
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, pkg := range dp.AurCache {
|
||||
if seen.get(pkg.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
if pkgSatisfies(pkg.Name, pkg.Version, dep) {
|
||||
providers.Pkgs = append(providers.Pkgs, pkg)
|
||||
seen.set(pkg.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, provide := range pkg.Provides {
|
||||
if provideSatisfies(provide, dep) {
|
||||
providers.Pkgs = append(providers.Pkgs, pkg)
|
||||
seen.set(pkg.Name)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if providers.Len() == 1 {
|
||||
return providers.Pkgs[0]
|
||||
}
|
||||
|
||||
if providers.Len() > 1 {
|
||||
sort.Sort(providers)
|
||||
return providerMenu(dep, providers)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dp *depPool) findSatisfierRepo(dep string) *alpm.Package {
|
||||
for _, pkg := range dp.Repo {
|
||||
if satisfiesRepo(dep, pkg) {
|
||||
return pkg
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (dp *depPool) hasSatisfier(dep string) bool {
|
||||
return dp.findSatisfierRepo(dep) != nil || dp.findSatisfierAur(dep) != nil
|
||||
}
|
||||
|
||||
func (dp *depPool) hasPackage(name string) bool {
|
||||
for _, pkg := range dp.Repo {
|
||||
if pkg.Name() == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
for _, pkg := range dp.Aur {
|
||||
if pkg.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
for _, pkg := range dp.Groups {
|
||||
if pkg == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
631
depSolver.go
631
depSolver.go
@ -1,631 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
alpm "github.com/jguer/go-alpm"
|
||||
rpc "github.com/mikkeloscar/aur"
|
||||
)
|
||||
|
||||
type depSolver struct {
|
||||
Aur []Base
|
||||
Repo []*alpm.Package
|
||||
Runtime stringSet
|
||||
Targets []target
|
||||
Explicit stringSet
|
||||
AurCache map[string]*rpc.Pkg
|
||||
Groups []string
|
||||
LocalDb *alpm.Db
|
||||
SyncDb alpm.DbList
|
||||
Seen stringSet
|
||||
Warnings *aurWarnings
|
||||
}
|
||||
|
||||
func makeDepSolver() (*depSolver, error) {
|
||||
localDb, err := alpmHandle.LocalDb()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
syncDb, err := alpmHandle.SyncDbs()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &depSolver{
|
||||
make([]Base, 0),
|
||||
make([]*alpm.Package, 0),
|
||||
make(stringSet),
|
||||
make([]target, 0),
|
||||
make(stringSet),
|
||||
make(map[string]*rpc.Pkg),
|
||||
make([]string, 0),
|
||||
localDb,
|
||||
syncDb,
|
||||
make(stringSet),
|
||||
nil,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getDepSolver(pkgs []string, warnings *aurWarnings) (*depSolver, error) {
|
||||
ds, err := makeDepSolver()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ds.Warnings = warnings
|
||||
err = ds.resolveTargets(pkgs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ds.resolveRuntime()
|
||||
return ds, err
|
||||
}
|
||||
|
||||
// Includes db/ prefixes and group installs
|
||||
func (ds *depSolver) resolveTargets(pkgs []string) error {
|
||||
// RPC requests are slow
|
||||
// Combine as many AUR package requests as possible into a single RPC
|
||||
// call
|
||||
aurTargets := make([]string, 0)
|
||||
pkgs = removeInvalidTargets(pkgs)
|
||||
|
||||
for _, pkg := range pkgs {
|
||||
var err error
|
||||
target := toTarget(pkg)
|
||||
|
||||
// skip targets already satisfied
|
||||
// even if the user enters db/pkg and aur/pkg the latter will
|
||||
// still get skipped even if it's from a different database to
|
||||
// the one specified
|
||||
// this is how pacman behaves
|
||||
if ds.hasPackage(target.DepString()) {
|
||||
continue
|
||||
}
|
||||
|
||||
var foundPkg *alpm.Package
|
||||
var singleDb *alpm.Db
|
||||
|
||||
// aur/ prefix means we only check the aur
|
||||
if target.Db == "aur" || mode == modeAUR {
|
||||
ds.Targets = append(ds.Targets, target)
|
||||
aurTargets = append(aurTargets, target.DepString())
|
||||
continue
|
||||
}
|
||||
|
||||
// If there'ss a different priefix only look in that repo
|
||||
if target.Db != "" {
|
||||
singleDb, err = alpmHandle.SyncDbByName(target.Db)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
foundPkg, err = singleDb.PkgCache().FindSatisfier(target.DepString())
|
||||
//otherwise find it in any repo
|
||||
} else {
|
||||
foundPkg, err = ds.SyncDb.FindSatisfier(target.DepString())
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
ds.Targets = append(ds.Targets, target)
|
||||
ds.Explicit.set(foundPkg.Name())
|
||||
ds.ResolveRepoDependency(foundPkg)
|
||||
continue
|
||||
} else {
|
||||
//check for groups
|
||||
//currently we don't resolve the packages in a group
|
||||
//only check if the group exists
|
||||
//would be better to check the groups from singleDb if
|
||||
//the user specified a db but there's no easy way to do
|
||||
//it without making alpm_lists so don't bother for now
|
||||
//db/group is probably a rare use case
|
||||
group, err := ds.SyncDb.PkgCachebyGroup(target.Name)
|
||||
if err == nil {
|
||||
ds.Groups = append(ds.Groups, target.String())
|
||||
group.ForEach(func(pkg alpm.Package) error {
|
||||
ds.Explicit.set(pkg.Name())
|
||||
return nil
|
||||
})
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
//if there was no db prefix check the aur
|
||||
if target.Db == "" {
|
||||
aurTargets = append(aurTargets, target.DepString())
|
||||
}
|
||||
|
||||
ds.Targets = append(ds.Targets, target)
|
||||
}
|
||||
|
||||
if len(aurTargets) > 0 && (mode == modeAny || mode == modeAUR) {
|
||||
return ds.resolveAURPackages(aurTargets, true)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ds *depSolver) hasPackage(name string) bool {
|
||||
for _, pkg := range ds.Repo {
|
||||
if pkg.Name() == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
for _, base := range ds.Aur {
|
||||
for _, pkg := range base {
|
||||
if pkg.Name == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, pkg := range ds.Groups {
|
||||
if pkg == name {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (ds *depSolver) findSatisfierAur(dep string) *rpc.Pkg {
|
||||
for _, base := range ds.Aur {
|
||||
for _, pkg := range base {
|
||||
if satisfiesAur(dep, pkg) {
|
||||
return pkg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ds *depSolver) findSatisfierRepo(dep string) *alpm.Package {
|
||||
for _, pkg := range ds.Repo {
|
||||
if satisfiesRepo(dep, pkg) {
|
||||
return pkg
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ds *depSolver) hasSatisfier(dep string) bool {
|
||||
return ds.findSatisfierRepo(dep) != nil || ds.findSatisfierAur(dep) != nil
|
||||
}
|
||||
|
||||
func (ds *depSolver) ResolveRepoDependency(pkg *alpm.Package) {
|
||||
if ds.Seen.get(pkg.Name()) {
|
||||
return
|
||||
}
|
||||
ds.Repo = append(ds.Repo, pkg)
|
||||
ds.Seen.set(pkg.Name())
|
||||
|
||||
pkg.Depends().ForEach(func(dep alpm.Depend) (err error) {
|
||||
//have satisfier in dep tree: skip
|
||||
if ds.hasSatisfier(dep.String()) {
|
||||
return
|
||||
}
|
||||
|
||||
//has satisfier installed: skip
|
||||
_, isInstalled := ds.LocalDb.PkgCache().FindSatisfier(dep.String())
|
||||
if isInstalled == nil {
|
||||
return
|
||||
}
|
||||
|
||||
//has satisfier in repo: fetch it
|
||||
repoPkg, inRepos := ds.SyncDb.FindSatisfier(dep.String())
|
||||
if inRepos != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ds.ResolveRepoDependency(repoPkg)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// This is mostly used to promote packages from the cache
|
||||
// to the Install list
|
||||
// Provide a pacman style provider menu if there's more than one candidate
|
||||
// This acts slightly differently from Pacman, It will give
|
||||
// a menu even if a package with a matching name exists. I believe this
|
||||
// method is better because most of the time you are choosing between
|
||||
// foo and foo-git.
|
||||
// Using Pacman's ways trying to install foo would never give you
|
||||
// a menu.
|
||||
// TODO: maybe intermix repo providers in the menu
|
||||
func (ds *depSolver) findSatisfierAurCache(dep string) *rpc.Pkg {
|
||||
depName, _, _ := splitDep(dep)
|
||||
seen := make(stringSet)
|
||||
providers := makeProviders(depName)
|
||||
|
||||
if _, err := ds.LocalDb.PkgByName(depName); err == nil {
|
||||
if pkg, ok := ds.AurCache[dep]; ok && pkgSatisfies(pkg.Name, pkg.Version, dep) {
|
||||
return pkg
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if cmdArgs.op == "Y" || cmdArgs.op == "yay" {
|
||||
for _, pkg := range ds.AurCache {
|
||||
if pkgSatisfies(pkg.Name, pkg.Version, dep) {
|
||||
for _, target := range ds.Targets {
|
||||
if target.Name == pkg.Name {
|
||||
return pkg
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, pkg := range ds.AurCache {
|
||||
if seen.get(pkg.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
if pkgSatisfies(pkg.Name, pkg.Version, dep) {
|
||||
providers.Pkgs = append(providers.Pkgs, pkg)
|
||||
seen.set(pkg.Name)
|
||||
continue
|
||||
}
|
||||
|
||||
for _, provide := range pkg.Provides {
|
||||
if provideSatisfies(provide, dep) {
|
||||
providers.Pkgs = append(providers.Pkgs, pkg)
|
||||
seen.set(pkg.Name)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !config.Provides && providers.Len() >= 1 {
|
||||
return providers.Pkgs[0]
|
||||
}
|
||||
|
||||
if providers.Len() == 1 {
|
||||
return providers.Pkgs[0]
|
||||
}
|
||||
|
||||
if providers.Len() > 1 {
|
||||
sort.Sort(providers)
|
||||
return providerMenu(dep, providers)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ds *depSolver) cacheAURPackages(_pkgs []string) error {
|
||||
pkgs := sliceToStringSet(_pkgs)
|
||||
query := make([]string, 0)
|
||||
|
||||
for pkg := range pkgs {
|
||||
if _, ok := ds.AurCache[pkg]; ok {
|
||||
pkgs.remove(pkg)
|
||||
}
|
||||
}
|
||||
|
||||
if len(pkgs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if config.Provides {
|
||||
err := ds.findProvides(pkgs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for pkg := range pkgs {
|
||||
if _, ok := ds.AurCache[pkg]; !ok {
|
||||
name, _, _ := splitDep(pkg)
|
||||
query = append(query, name)
|
||||
}
|
||||
}
|
||||
|
||||
info, err := aurInfo(query, ds.Warnings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, pkg := range info {
|
||||
// Dump everything in cache just in case we need it later
|
||||
ds.AurCache[pkg.Name] = pkg
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Pseudo provides finder.
|
||||
// Try to find provides by performing a search of the package name
|
||||
// This effectively performs -Ss on each package
|
||||
// then runs -Si on each result to cache the information.
|
||||
//
|
||||
// For example if you were to -S yay then yay -Ss would give:
|
||||
// yay-git yay-bin yay realyog pacui pacui-git ruby-yard
|
||||
// These packages will all be added to the cache in case they are needed later
|
||||
// Ofcouse only the first three packages provide yay, the rest are just false
|
||||
// positives.
|
||||
//
|
||||
// This method increases dependency resolve time
|
||||
func (ds *depSolver) findProvides(pkgs stringSet) error {
|
||||
var mux sync.Mutex
|
||||
var wg sync.WaitGroup
|
||||
|
||||
doSearch := func(pkg string) {
|
||||
defer wg.Done()
|
||||
var err error
|
||||
var results []rpc.Pkg
|
||||
|
||||
// Hack for a bigger search result, if the user wants
|
||||
// java-envronment we can search for just java instead and get
|
||||
// more hits.
|
||||
words := strings.Split(pkg, "-")
|
||||
|
||||
for i := range words {
|
||||
results, err = rpc.SearchByNameDesc(strings.Join(words[:i+1], "-"))
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, result := range results {
|
||||
mux.Lock()
|
||||
if _, ok := ds.AurCache[result.Name]; !ok {
|
||||
pkgs.set(result.Name)
|
||||
}
|
||||
mux.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
for pkg := range pkgs {
|
||||
if _, err := ds.LocalDb.PkgByName(pkg); err == nil {
|
||||
continue
|
||||
}
|
||||
wg.Add(1)
|
||||
go doSearch(pkg)
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ds *depSolver) resolveAURPackages(pkgs []string, explicit bool) error {
|
||||
newPackages := make(stringSet)
|
||||
newAURPackages := make([]string, 0)
|
||||
toAdd := make([]*rpc.Pkg, 0)
|
||||
|
||||
if len(pkgs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
err := ds.cacheAURPackages(pkgs)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, name := range pkgs {
|
||||
if ds.Seen.get(name) {
|
||||
continue
|
||||
}
|
||||
|
||||
pkg := ds.findSatisfierAurCache(name)
|
||||
if pkg == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
if explicit {
|
||||
ds.Explicit.set(pkg.Name)
|
||||
}
|
||||
|
||||
ds.Seen.set(pkg.Name)
|
||||
toAdd = append(toAdd, pkg)
|
||||
|
||||
for _, deps := range [3][]string{pkg.Depends, pkg.MakeDepends, pkg.CheckDepends} {
|
||||
for _, dep := range deps {
|
||||
newPackages.set(dep)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for dep := range newPackages {
|
||||
if ds.hasSatisfier(dep) {
|
||||
continue
|
||||
}
|
||||
|
||||
_, isInstalled := ds.LocalDb.PkgCache().FindSatisfier(dep) //has satisfier installed: skip
|
||||
hm := hideMenus
|
||||
hideMenus = isInstalled == nil
|
||||
repoPkg, inRepos := ds.SyncDb.FindSatisfier(dep) //has satisfier in repo: fetch it
|
||||
hideMenus = hm
|
||||
if isInstalled == nil && (config.ReBuild != "tree" || inRepos == nil) {
|
||||
continue
|
||||
}
|
||||
|
||||
if inRepos == nil {
|
||||
ds.ResolveRepoDependency(repoPkg)
|
||||
continue
|
||||
}
|
||||
|
||||
//assume it's in the aur
|
||||
//ditch the versioning because the RPC can't handle it
|
||||
newAURPackages = append(newAURPackages, dep)
|
||||
|
||||
}
|
||||
|
||||
err = ds.resolveAURPackages(newAURPackages, false)
|
||||
|
||||
for _, pkg := range toAdd {
|
||||
if !ds.hasPackage(pkg.Name) {
|
||||
ds.Aur = baseAppend(ds.Aur, pkg)
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (ds *depSolver) Print() {
|
||||
repo := ""
|
||||
repoMake := ""
|
||||
aur := ""
|
||||
aurMake := ""
|
||||
|
||||
repoLen := 0
|
||||
repoMakeLen := 0
|
||||
aurLen := 0
|
||||
aurMakeLen := 0
|
||||
|
||||
for _, pkg := range ds.Repo {
|
||||
if ds.Runtime.get(pkg.Name()) {
|
||||
repo += " " + pkg.Name() + "-" + pkg.Version()
|
||||
repoLen++
|
||||
} else {
|
||||
repoMake += " " + pkg.Name() + "-" + pkg.Version()
|
||||
repoMakeLen++
|
||||
}
|
||||
}
|
||||
|
||||
for _, base := range ds.Aur {
|
||||
pkg := base.Pkgbase()
|
||||
pkgStr := " " + pkg + "-" + base[0].Version
|
||||
pkgStrMake := pkgStr
|
||||
|
||||
push := false
|
||||
pushMake := false
|
||||
|
||||
if len(base) > 1 || pkg != base[0].Name {
|
||||
pkgStr += " ("
|
||||
pkgStrMake += " ("
|
||||
|
||||
for _, split := range base {
|
||||
if ds.Runtime.get(split.Name) {
|
||||
pkgStr += split.Name + " "
|
||||
aurLen++
|
||||
push = true
|
||||
} else {
|
||||
pkgStrMake += split.Name + " "
|
||||
aurMakeLen++
|
||||
pushMake = true
|
||||
}
|
||||
}
|
||||
|
||||
pkgStr = pkgStr[:len(pkgStr)-1] + ")"
|
||||
pkgStrMake = pkgStrMake[:len(pkgStrMake)-1] + ")"
|
||||
} else if ds.Runtime.get(base[0].Name) {
|
||||
aurLen++
|
||||
push = true
|
||||
} else {
|
||||
aurMakeLen++
|
||||
pushMake = true
|
||||
}
|
||||
|
||||
if push {
|
||||
aur += pkgStr
|
||||
}
|
||||
if pushMake {
|
||||
aurMake += pkgStrMake
|
||||
}
|
||||
}
|
||||
|
||||
printDownloads("Repo", repoLen, repo)
|
||||
printDownloads("Repo Make", repoMakeLen, repoMake)
|
||||
printDownloads("Aur", aurLen, aur)
|
||||
printDownloads("Aur Make", aurMakeLen, aurMake)
|
||||
}
|
||||
|
||||
func (ds *depSolver) resolveRuntime() {
|
||||
for _, pkg := range ds.Repo {
|
||||
if ds.Explicit.get(pkg.Name()) {
|
||||
ds.Runtime.set(pkg.Name())
|
||||
ds.resolveRuntimeRepo(pkg)
|
||||
}
|
||||
}
|
||||
|
||||
for _, base := range ds.Aur {
|
||||
for _, pkg := range base {
|
||||
if ds.Explicit.get(pkg.Name) {
|
||||
ds.Runtime.set(pkg.Name)
|
||||
ds.resolveRuntimeAur(pkg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ds *depSolver) resolveRuntimeRepo(pkg *alpm.Package) {
|
||||
pkg.Depends().ForEach(func(dep alpm.Depend) (err error) {
|
||||
for _, pkg := range ds.Repo {
|
||||
if ds.Runtime.get(pkg.Name()) {
|
||||
continue
|
||||
}
|
||||
|
||||
if satisfiesRepo(dep.String(), pkg) {
|
||||
ds.Runtime.set(pkg.Name())
|
||||
ds.resolveRuntimeRepo(pkg)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (ds *depSolver) resolveRuntimeAur(pkg *rpc.Pkg) {
|
||||
for _, dep := range pkg.Depends {
|
||||
for _, pkg := range ds.Repo {
|
||||
if ds.Runtime.get(pkg.Name()) {
|
||||
continue
|
||||
}
|
||||
|
||||
if satisfiesRepo(dep, pkg) {
|
||||
ds.Runtime.set(pkg.Name())
|
||||
ds.resolveRuntimeRepo(pkg)
|
||||
}
|
||||
}
|
||||
|
||||
for _, base := range ds.Aur {
|
||||
for _, pkg := range base {
|
||||
if ds.Runtime.get(pkg.Name) {
|
||||
continue
|
||||
}
|
||||
|
||||
if satisfiesAur(dep, pkg) {
|
||||
ds.Runtime.set(pkg.Name)
|
||||
ds.resolveRuntimeAur(pkg)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (ds *depSolver) HasMake() bool {
|
||||
lenAur := 0
|
||||
for _, base := range ds.Aur {
|
||||
lenAur += len(base)
|
||||
}
|
||||
|
||||
return len(ds.Runtime) != lenAur+len(ds.Repo)
|
||||
}
|
||||
|
||||
func (ds *depSolver) getMake() []string {
|
||||
makeOnly := make([]string, 0, len(ds.Aur)+len(ds.Repo)-len(ds.Runtime))
|
||||
|
||||
for _, base := range ds.Aur {
|
||||
for _, pkg := range base {
|
||||
if !ds.Runtime.get(pkg.Name) {
|
||||
makeOnly = append(makeOnly, pkg.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, pkg := range ds.Repo {
|
||||
if !ds.Runtime.get(pkg.Name()) {
|
||||
makeOnly = append(makeOnly, pkg.Name())
|
||||
}
|
||||
}
|
||||
|
||||
return makeOnly
|
||||
}
|
80
install.go
80
install.go
@ -17,6 +17,7 @@ import (
|
||||
func install(parser *arguments) error {
|
||||
var err error
|
||||
var incompatible stringSet
|
||||
var do *depOrder
|
||||
|
||||
var aurUp upSlice
|
||||
var repoUp upSlice
|
||||
@ -109,17 +110,17 @@ func install(parser *arguments) error {
|
||||
|
||||
targets := sliceToStringSet(parser.targets)
|
||||
|
||||
ds, err := getDepSolver(requestTargets, warnings)
|
||||
dp, err := getDepPool(requestTargets, warnings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = ds.CheckMissing()
|
||||
err = dp.CheckMissing()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(ds.Aur) == 0 {
|
||||
if len(dp.Aur) == 0 {
|
||||
if !config.CombinedUpgrade {
|
||||
if parser.existsArg("u", "sysupgrade") {
|
||||
fmt.Println(" there is nothing to do")
|
||||
@ -133,32 +134,37 @@ func install(parser *arguments) error {
|
||||
return show(passToPacman(parser))
|
||||
}
|
||||
|
||||
if len(ds.Aur) > 0 && 0 == os.Geteuid() {
|
||||
if len(dp.Aur) > 0 && 0 == os.Geteuid() {
|
||||
return fmt.Errorf(bold(red(arrow)) + " Refusing to install AUR Packages as root, Aborting.")
|
||||
}
|
||||
|
||||
conflicts, err := ds.CheckConflicts()
|
||||
conflicts, err := dp.CheckConflicts()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, pkg := range ds.Repo {
|
||||
do = getDepOrder(dp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, pkg := range do.Repo {
|
||||
arguments.addTarget(pkg.DB().Name() + "/" + pkg.Name())
|
||||
}
|
||||
|
||||
for _, pkg := range ds.Groups {
|
||||
for _, pkg := range dp.Groups {
|
||||
arguments.addTarget(pkg)
|
||||
}
|
||||
|
||||
if len(ds.Aur) == 0 && len(arguments.targets) == 0 && (!parser.existsArg("u", "sysupgrade") || mode == modeAUR) {
|
||||
if len(do.Aur) == 0 && len(arguments.targets) == 0 && (!parser.existsArg("u", "sysupgrade") || mode == modeAUR) {
|
||||
fmt.Println(" there is nothing to do")
|
||||
return nil
|
||||
}
|
||||
|
||||
ds.Print()
|
||||
do.Print()
|
||||
fmt.Println()
|
||||
|
||||
if ds.HasMake() {
|
||||
if do.HasMake() {
|
||||
if config.RemoveMake == "yes" {
|
||||
removeMake = true
|
||||
} else if config.RemoveMake == "no" {
|
||||
@ -169,9 +175,9 @@ func install(parser *arguments) error {
|
||||
}
|
||||
|
||||
if config.CleanMenu {
|
||||
if anyExistInCache(ds.Aur) {
|
||||
askClean := pkgbuildNumberMenu(ds.Aur, remoteNamesCache)
|
||||
toClean, err := cleanNumberMenu(ds.Aur, remoteNamesCache, askClean)
|
||||
if anyExistInCache(do.Aur) {
|
||||
askClean := pkgbuildNumberMenu(do.Aur, remoteNamesCache)
|
||||
toClean, err := cleanNumberMenu(do.Aur, remoteNamesCache, askClean)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -180,8 +186,8 @@ func install(parser *arguments) error {
|
||||
}
|
||||
}
|
||||
|
||||
toSkip := pkgbuildsToSkip(ds.Aur, targets)
|
||||
cloned, err := downloadPkgbuilds(ds.Aur, toSkip, config.BuildDir)
|
||||
toSkip := pkgbuildsToSkip(do.Aur, targets)
|
||||
cloned, err := downloadPkgbuilds(do.Aur, toSkip, config.BuildDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -190,8 +196,8 @@ func install(parser *arguments) error {
|
||||
var toEdit []Base
|
||||
|
||||
if config.DiffMenu {
|
||||
pkgbuildNumberMenu(ds.Aur, remoteNamesCache)
|
||||
toDiff, err = diffNumberMenu(ds.Aur, remoteNamesCache)
|
||||
pkgbuildNumberMenu(do.Aur, remoteNamesCache)
|
||||
toDiff, err = diffNumberMenu(do.Aur, remoteNamesCache)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -214,19 +220,19 @@ func install(parser *arguments) error {
|
||||
config.NoConfirm = oldValue
|
||||
}
|
||||
|
||||
err = mergePkgbuilds(ds.Aur)
|
||||
err = mergePkgbuilds(do.Aur)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
srcinfos, err = parseSrcinfoFiles(ds.Aur, true)
|
||||
srcinfos, err = parseSrcinfoFiles(do.Aur, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if config.EditMenu {
|
||||
pkgbuildNumberMenu(ds.Aur, remoteNamesCache)
|
||||
toEdit, err = editNumberMenu(ds.Aur, remoteNamesCache)
|
||||
pkgbuildNumberMenu(do.Aur, remoteNamesCache)
|
||||
toEdit, err = editNumberMenu(do.Aur, remoteNamesCache)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -249,13 +255,13 @@ func install(parser *arguments) error {
|
||||
config.NoConfirm = oldValue
|
||||
}
|
||||
|
||||
incompatible, err = getIncompatible(ds.Aur, srcinfos)
|
||||
incompatible, err = getIncompatible(do.Aur, srcinfos)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if config.PGPFetch {
|
||||
err = checkPgpKeys(ds.Aur, srcinfos)
|
||||
err = checkPgpKeys(do.Aur, srcinfos)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -276,15 +282,15 @@ func install(parser *arguments) error {
|
||||
expArguments := makeArguments()
|
||||
expArguments.addArg("D", "asexplicit")
|
||||
|
||||
for _, pkg := range ds.Repo {
|
||||
if !ds.Explicit.get(pkg.Name()) && !localNamesCache.get(pkg.Name()) && !remoteNamesCache.get(pkg.Name()) {
|
||||
for _, pkg := range do.Repo {
|
||||
if !dp.Explicit.get(pkg.Name()) && !localNamesCache.get(pkg.Name()) && !remoteNamesCache.get(pkg.Name()) {
|
||||
depArguments.addTarget(pkg.Name())
|
||||
continue
|
||||
}
|
||||
|
||||
if parser.existsArg("asdeps", "asdep") && ds.Explicit.get(pkg.Name()) {
|
||||
if parser.existsArg("asdeps", "asdep") && dp.Explicit.get(pkg.Name()) {
|
||||
depArguments.addTarget(pkg.Name())
|
||||
} else if parser.existsArg("asexp", "asexplicit") && ds.Explicit.get(pkg.Name()) {
|
||||
} else if parser.existsArg("asexp", "asexplicit") && dp.Explicit.get(pkg.Name()) {
|
||||
expArguments.addTarget(pkg.Name())
|
||||
}
|
||||
}
|
||||
@ -306,12 +312,12 @@ func install(parser *arguments) error {
|
||||
|
||||
go updateCompletion(false)
|
||||
|
||||
err = downloadPkgbuildsSources(ds.Aur, incompatible)
|
||||
err = downloadPkgbuildsSources(do.Aur, incompatible)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = buildInstallPkgbuilds(ds, srcinfos, parser, incompatible, conflicts)
|
||||
err = buildInstallPkgbuilds(dp, do, srcinfos, parser, incompatible, conflicts)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -320,7 +326,7 @@ func install(parser *arguments) error {
|
||||
removeArguments := makeArguments()
|
||||
removeArguments.addArg("R", "u")
|
||||
|
||||
for _, pkg := range ds.getMake() {
|
||||
for _, pkg := range do.getMake() {
|
||||
removeArguments.addTarget(pkg)
|
||||
}
|
||||
|
||||
@ -335,7 +341,7 @@ func install(parser *arguments) error {
|
||||
}
|
||||
|
||||
if config.CleanAfter {
|
||||
cleanAfter(ds.Aur)
|
||||
cleanAfter(do.Aur)
|
||||
}
|
||||
|
||||
return nil
|
||||
@ -894,8 +900,8 @@ func downloadPkgbuildsSources(bases []Base, incompatible stringSet) (err error)
|
||||
return
|
||||
}
|
||||
|
||||
func buildInstallPkgbuilds(ds *depSolver, srcinfos map[string]*gosrc.Srcinfo, parser *arguments, incompatible stringSet, conflicts mapStringSet) error {
|
||||
for _, base := range ds.Aur {
|
||||
func buildInstallPkgbuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc.Srcinfo, parser *arguments, incompatible stringSet, conflicts mapStringSet) error {
|
||||
for _, base := range do.Aur {
|
||||
pkg := base.Pkgbase()
|
||||
dir := filepath.Join(config.BuildDir, pkg)
|
||||
built := true
|
||||
@ -921,7 +927,7 @@ func buildInstallPkgbuilds(ds *depSolver, srcinfos map[string]*gosrc.Srcinfo, pa
|
||||
|
||||
isExplicit := false
|
||||
for _, b := range base {
|
||||
isExplicit = isExplicit || ds.Explicit.get(b.Name)
|
||||
isExplicit = isExplicit || dp.Explicit.get(b.Name)
|
||||
}
|
||||
if config.ReBuild == "no" || (config.ReBuild == "yes" && !isExplicit) {
|
||||
for _, split := range base {
|
||||
@ -944,7 +950,7 @@ func buildInstallPkgbuilds(ds *depSolver, srcinfos map[string]*gosrc.Srcinfo, pa
|
||||
if cmdArgs.existsArg("needed") {
|
||||
installed := true
|
||||
for _, split := range base {
|
||||
if alpmpkg, err := ds.LocalDb.PkgByName(split.Name); err != nil || alpmpkg.Version() != version {
|
||||
if alpmpkg, err := dp.LocalDb.PkgByName(split.Name); err != nil || alpmpkg.Version() != version {
|
||||
installed = false
|
||||
}
|
||||
}
|
||||
@ -1028,11 +1034,11 @@ func buildInstallPkgbuilds(ds *depSolver, srcinfos map[string]*gosrc.Srcinfo, pa
|
||||
}
|
||||
|
||||
arguments.addTarget(pkgdest)
|
||||
if !ds.Explicit.get(split.Name) && !localNamesCache.get(split.Name) && !remoteNamesCache.get(split.Name) {
|
||||
if !dp.Explicit.get(split.Name) && !localNamesCache.get(split.Name) && !remoteNamesCache.get(split.Name) {
|
||||
depArguments.addTarget(split.Name)
|
||||
}
|
||||
|
||||
if ds.Explicit.get(split.Name) {
|
||||
if dp.Explicit.get(split.Name) {
|
||||
if parser.existsArg("asdeps", "asdep") {
|
||||
depArguments.addTarget(split.Name)
|
||||
} else if parser.existsArg("asexplicit", "asexp") {
|
||||
|
70
print.go
70
print.go
@ -189,6 +189,76 @@ func (u upSlice) print() {
|
||||
}
|
||||
}
|
||||
|
||||
// printDownloadsFromRepo prints repository packages to be downloaded
|
||||
func (do *depOrder) Print() {
|
||||
repo := ""
|
||||
repoMake := ""
|
||||
aur := ""
|
||||
aurMake := ""
|
||||
|
||||
repoLen := 0
|
||||
repoMakeLen := 0
|
||||
aurLen := 0
|
||||
aurMakeLen := 0
|
||||
|
||||
for _, pkg := range do.Repo {
|
||||
if do.Runtime.get(pkg.Name()) {
|
||||
repo += " " + pkg.Name() + "-" + pkg.Version()
|
||||
repoLen++
|
||||
} else {
|
||||
repoMake += " " + pkg.Name() + "-" + pkg.Version()
|
||||
repoMakeLen++
|
||||
}
|
||||
}
|
||||
|
||||
for _, base := range do.Aur {
|
||||
pkg := base.Pkgbase()
|
||||
pkgStr := " " + pkg + "-" + base[0].Version
|
||||
pkgStrMake := pkgStr
|
||||
|
||||
push := false
|
||||
pushMake := false
|
||||
|
||||
if len(base) > 1 || pkg != base[0].Name {
|
||||
pkgStr += " ("
|
||||
pkgStrMake += " ("
|
||||
|
||||
for _, split := range base {
|
||||
if do.Runtime.get(split.Name) {
|
||||
pkgStr += split.Name + " "
|
||||
aurLen++
|
||||
push = true
|
||||
} else {
|
||||
pkgStrMake += split.Name + " "
|
||||
aurMakeLen++
|
||||
pushMake = true
|
||||
}
|
||||
}
|
||||
|
||||
pkgStr = pkgStr[:len(pkgStr)-1] + ")"
|
||||
pkgStrMake = pkgStrMake[:len(pkgStrMake)-1] + ")"
|
||||
} else if do.Runtime.get(base[0].Name) {
|
||||
aurLen++
|
||||
push = true
|
||||
} else {
|
||||
aurMakeLen++
|
||||
pushMake = true
|
||||
}
|
||||
|
||||
if push {
|
||||
aur += pkgStr
|
||||
}
|
||||
if pushMake {
|
||||
aurMake += pkgStrMake
|
||||
}
|
||||
}
|
||||
|
||||
printDownloads("Repo", repoLen, repo)
|
||||
printDownloads("Repo Make", repoMakeLen, repoMake)
|
||||
printDownloads("Aur", aurLen, aur)
|
||||
printDownloads("Aur Make", aurMakeLen, aurMake)
|
||||
}
|
||||
|
||||
func printDownloads(repoName string, length int, packages string) {
|
||||
if length < 1 {
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user