mirror of
https://github.com/Jguer/yay.git
synced 2024-11-06 17:17:22 +01:00
7b558ba47c
We dont check the dependencies of things already installed becuase, well, they're already installed. But we should check the dependencies of targets even if they are installed because they get reinstalled.
270 lines
5.6 KiB
Go
270 lines
5.6 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"sync"
|
|
|
|
alpm "github.com/jguer/go-alpm"
|
|
// gopkg "github.com/mikkeloscar/gopkgbuild"
|
|
)
|
|
|
|
func (dp *depPool) checkInnerConflict(name string, conflict string, conflicts mapStringSet) {
|
|
for _, pkg := range dp.Aur {
|
|
if pkg.Name == name {
|
|
continue
|
|
}
|
|
|
|
if satisfiesAur(conflict, pkg) {
|
|
conflicts.Add(name, pkg.Name)
|
|
}
|
|
}
|
|
|
|
for _, pkg := range dp.Repo {
|
|
if pkg.Name() == name {
|
|
continue
|
|
}
|
|
|
|
if satisfiesRepo(conflict, pkg) {
|
|
conflicts.Add(name, 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 {
|
|
return nil
|
|
}
|
|
|
|
if satisfiesRepo(conflict, &pkg) {
|
|
n := pkg.Name()
|
|
if n != conflict {
|
|
n += " (" + conflict + ")"
|
|
}
|
|
conflicts.Add(name, n)
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
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 + ")"
|
|
}
|
|
|
|
conflicts.Add(pkg.Name, name)
|
|
}
|
|
}
|
|
|
|
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 (dp *depPool) checkInnerConflicts(conflicts mapStringSet) {
|
|
for _, pkg := range dp.Aur {
|
|
for _, conflict := range pkg.Conflicts {
|
|
dp.checkInnerConflict(pkg.Name, conflict, conflicts)
|
|
}
|
|
}
|
|
|
|
for _, pkg := range dp.Repo {
|
|
pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
|
|
dp.checkInnerConflict(pkg.Name(), conflict.String(), conflicts)
|
|
return nil
|
|
})
|
|
}
|
|
}
|
|
|
|
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 {
|
|
pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
|
|
dp.checkReverseConflict(pkg.Name(), conflict.String(), conflicts)
|
|
return nil
|
|
})
|
|
|
|
return nil
|
|
})
|
|
}
|
|
|
|
func (dp *depPool) CheckConflicts() error {
|
|
var wg sync.WaitGroup
|
|
innerConflicts := make(mapStringSet)
|
|
conflicts := make(mapStringSet)
|
|
wg.Add(2)
|
|
|
|
fmt.Println(bold(cyan("::") + bold(" Checking for conflicts...")))
|
|
go func() {
|
|
dp.checkForwardConflicts(conflicts)
|
|
dp.checkReverseConflicts(conflicts)
|
|
wg.Done()
|
|
}()
|
|
|
|
fmt.Println(bold(cyan("::") + bold(" Checking for inner conflicts...")))
|
|
go func() {
|
|
dp.checkInnerConflicts(innerConflicts)
|
|
wg.Done()
|
|
}()
|
|
|
|
wg.Wait()
|
|
|
|
if len(innerConflicts) != 0 {
|
|
fmt.Println()
|
|
fmt.Println(bold(red(arrow)), bold("Inner conflicts found:"))
|
|
|
|
for name, pkgs := range innerConflicts {
|
|
str := red(bold(smallArrow)) + " " + name + ":"
|
|
for pkg := range pkgs {
|
|
str += " " + cyan(pkg) + ","
|
|
}
|
|
str = strings.TrimSuffix(str, ",")
|
|
|
|
fmt.Println(str)
|
|
}
|
|
|
|
return fmt.Errorf("Unresolvable package conflicts, aborting")
|
|
}
|
|
|
|
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)
|
|
}
|
|
|
|
fmt.Println()
|
|
}
|
|
|
|
return 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), " (Tree: ")
|
|
|
|
if len(tree) == 0 {
|
|
fmt.Print(cyan("Target "))
|
|
} else {
|
|
for _, pkg := range tree {
|
|
fmt.Print(cyan(pkg), " -> ")
|
|
}
|
|
}
|
|
|
|
fmt.Println(")")
|
|
}
|
|
}
|
|
|
|
return fmt.Errorf("")
|
|
}
|