Use depSolver in install

This commit is contained in:
morganamilo 2018-10-11 17:26:22 +01:00
parent 704e8406d1
commit 4ff36fbd4b
No known key found for this signature in database
GPG key ID: 6FE9E7996B0B082E
2 changed files with 237 additions and 50 deletions

View file

@ -714,3 +714,204 @@ func (ds *depSolver) getMake() []string {
return makeOnly
}
func (ds *depSolver) checkInnerConflict(name string, conflict string, conflicts mapStringSet) {
for _, base := range ds.Aur {
for _, pkg := range base {
if pkg.Name == name {
continue
}
if satisfiesAur(conflict, pkg) {
conflicts.Add(name, pkg.Name)
}
}
}
for _, pkg := range ds.Repo {
if pkg.Name() == name {
continue
}
if satisfiesRepo(conflict, pkg) {
conflicts.Add(name, pkg.Name())
}
}
}
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()) {
return nil
}
if satisfiesRepo(conflict, &pkg) {
n := pkg.Name()
if n != conflict {
n += " (" + conflict + ")"
}
conflicts.Add(name, n)
}
return nil
})
}
func (ds *depSolver) checkReverseConflict(name string, conflict string, conflicts mapStringSet) {
for _, base := range ds.Aur {
for _, pkg := range base {
if pkg.Name == name {
continue
}
if satisfiesAur(conflict, pkg) {
if name != conflict {
name += " (" + conflict + ")"
}
conflicts.Add(pkg.Name, name)
}
}
}
for _, pkg := range ds.Repo {
if pkg.Name() == name {
continue
}
if satisfiesRepo(conflict, pkg) {
if name != conflict {
name += " (" + conflict + ")"
}
conflicts.Add(pkg.Name(), name)
}
}
}
func (ds *depSolver) checkInnerConflicts(conflicts mapStringSet) {
for _, base := range ds.Aur {
for _, pkg := range base {
for _, conflict := range pkg.Conflicts {
ds.checkInnerConflict(pkg.Name, conflict, conflicts)
}
}
}
for _, pkg := range ds.Repo {
pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
ds.checkInnerConflict(pkg.Name(), conflict.String(), conflicts)
return nil
})
}
}
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)
}
}
}
for _, pkg := range ds.Repo {
pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
ds.checkForwardConflict(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()) {
return nil
}
pkg.Conflicts().ForEach(func(conflict alpm.Depend) error {
ds.checkReverseConflict(pkg.Name(), conflict.String(), conflicts)
return nil
})
return nil
})
}
func (ds *depSolver) CheckConflicts() (mapStringSet, error) {
var wg sync.WaitGroup
innerConflicts := make(mapStringSet)
conflicts := make(mapStringSet)
wg.Add(2)
fmt.Println(bold(cyan("::") + bold(" Checking for conflicts...")))
go func() {
ds.checkForwardConflicts(conflicts)
ds.checkReverseConflicts(conflicts)
wg.Done()
}()
fmt.Println(bold(cyan("::") + bold(" Checking for inner conflicts...")))
go func() {
ds.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)
}
}
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)
}
}
// 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)
}
}
if len(conflicts) > 0 {
if !config.UseAsk {
if config.NoConfirm {
return nil, fmt.Errorf("Package conflicts can not be resolved with noconfirm, aborting")
}
fmt.Println()
fmt.Println(bold(red(arrow)), bold("Conflicting packages will have to be confirmed manually"))
fmt.Println()
}
}
return conflicts, nil
}

View file

@ -17,7 +17,6 @@ import (
func install(parser *arguments) error {
var err error
var incompatible stringSet
var do *depOrder
var aurUp upSlice
var repoUp upSlice
@ -110,25 +109,17 @@ func install(parser *arguments) error {
targets := sliceToStringSet(parser.targets)
dp, err := getDepPool(requestTargets, warnings)
if err != nil {
return err
}
ds, err := getDepSolver(requestTargets, warnings)
if err != nil {
return err
}
ds.Print()
fmt.Println(ds.Runtime)
err = dp.CheckMissing()
err = ds.CheckMissing()
if err != nil {
return err
}
if len(dp.Aur) == 0 {
if len(ds.Aur) == 0 {
if !config.CombinedUpgrade {
if parser.existsArg("u", "sysupgrade") {
fmt.Println(" there is nothing to do")
@ -142,37 +133,32 @@ func install(parser *arguments) error {
return show(passToPacman(parser))
}
if len(dp.Aur) > 0 && 0 == os.Geteuid() {
if len(ds.Aur) > 0 && 0 == os.Geteuid() {
return fmt.Errorf(bold(red(arrow)) + " Refusing to install AUR Packages as root, Aborting.")
}
conflicts, err := dp.CheckConflicts()
conflicts, err := ds.CheckConflicts()
if err != nil {
return err
}
do = getDepOrder(dp)
if err != nil {
return err
}
for _, pkg := range do.Repo {
for _, pkg := range ds.Repo {
arguments.addTarget(pkg.DB().Name() + "/" + pkg.Name())
}
for _, pkg := range dp.Groups {
for _, pkg := range ds.Groups {
arguments.addTarget(pkg)
}
if len(do.Aur) == 0 && len(arguments.targets) == 0 && (!parser.existsArg("u", "sysupgrade") || mode == ModeAUR) {
if len(ds.Aur) == 0 && len(arguments.targets) == 0 && (!parser.existsArg("u", "sysupgrade") || mode == ModeAUR) {
fmt.Println(" there is nothing to do")
return nil
}
do.Print()
ds.Print()
fmt.Println()
if do.HasMake() {
if ds.HasMake() {
if config.RemoveMake == "yes" {
removeMake = true
} else if config.RemoveMake == "no" {
@ -183,9 +169,9 @@ func install(parser *arguments) error {
}
if config.CleanMenu {
if anyExistInCache(do.Aur) {
askClean := pkgbuildNumberMenu(do.Aur, remoteNamesCache)
toClean, err := cleanNumberMenu(do.Aur, remoteNamesCache, askClean)
if anyExistInCache(ds.Aur) {
askClean := pkgbuildNumberMenu(ds.Aur, remoteNamesCache)
toClean, err := cleanNumberMenu(ds.Aur, remoteNamesCache, askClean)
if err != nil {
return err
}
@ -194,8 +180,8 @@ func install(parser *arguments) error {
}
}
toSkip := pkgbuildsToSkip(do.Aur, targets)
cloned, err := downloadPkgbuilds(do.Aur, toSkip, config.BuildDir)
toSkip := pkgbuildsToSkip(ds.Aur, targets)
cloned, err := downloadPkgbuilds(ds.Aur, toSkip, config.BuildDir)
if err != nil {
return err
}
@ -204,8 +190,8 @@ func install(parser *arguments) error {
var toEdit []Base
if config.DiffMenu {
pkgbuildNumberMenu(do.Aur, remoteNamesCache)
toDiff, err = diffNumberMenu(do.Aur, remoteNamesCache)
pkgbuildNumberMenu(ds.Aur, remoteNamesCache)
toDiff, err = diffNumberMenu(ds.Aur, remoteNamesCache)
if err != nil {
return err
}
@ -228,19 +214,19 @@ func install(parser *arguments) error {
config.NoConfirm = oldValue
}
err = mergePkgbuilds(do.Aur)
err = mergePkgbuilds(ds.Aur)
if err != nil {
return err
}
srcinfos, err = parseSrcinfoFiles(do.Aur, true)
srcinfos, err = parseSrcinfoFiles(ds.Aur, true)
if err != nil {
return err
}
if config.EditMenu {
pkgbuildNumberMenu(do.Aur, remoteNamesCache)
toEdit, err = editNumberMenu(do.Aur, remoteNamesCache)
pkgbuildNumberMenu(ds.Aur, remoteNamesCache)
toEdit, err = editNumberMenu(ds.Aur, remoteNamesCache)
if err != nil {
return err
}
@ -263,13 +249,13 @@ func install(parser *arguments) error {
config.NoConfirm = oldValue
}
incompatible, err = getIncompatible(do.Aur, srcinfos)
incompatible, err = getIncompatible(ds.Aur, srcinfos)
if err != nil {
return err
}
if config.PGPFetch {
err = checkPgpKeys(do.Aur, srcinfos)
err = checkPgpKeys(ds.Aur, srcinfos)
if err != nil {
return err
}
@ -290,15 +276,15 @@ func install(parser *arguments) error {
expArguments := makeArguments()
expArguments.addArg("D", "asexplicit")
for _, pkg := range do.Repo {
if !dp.Explicit.get(pkg.Name()) && !localNamesCache.get(pkg.Name()) && !remoteNamesCache.get(pkg.Name()) {
for _, pkg := range ds.Repo {
if !ds.Explicit.get(pkg.Name()) && !localNamesCache.get(pkg.Name()) && !remoteNamesCache.get(pkg.Name()) {
depArguments.addTarget(pkg.Name())
continue
}
if parser.existsArg("asdeps", "asdep") && dp.Explicit.get(pkg.Name()) {
if parser.existsArg("asdeps", "asdep") && ds.Explicit.get(pkg.Name()) {
depArguments.addTarget(pkg.Name())
} else if parser.existsArg("asexp", "asexplicit") && dp.Explicit.get(pkg.Name()) {
} else if parser.existsArg("asexp", "asexplicit") && ds.Explicit.get(pkg.Name()) {
expArguments.addTarget(pkg.Name())
}
}
@ -320,12 +306,12 @@ func install(parser *arguments) error {
go updateCompletion(false)
err = downloadPkgbuildsSources(do.Aur, incompatible)
err = downloadPkgbuildsSources(ds.Aur, incompatible)
if err != nil {
return err
}
err = buildInstallPkgbuilds(dp, do, srcinfos, parser, incompatible, conflicts)
err = buildInstallPkgbuilds(ds, srcinfos, parser, incompatible, conflicts)
if err != nil {
return err
}
@ -334,7 +320,7 @@ func install(parser *arguments) error {
removeArguments := makeArguments()
removeArguments.addArg("R", "u")
for _, pkg := range do.getMake() {
for _, pkg := range ds.getMake() {
removeArguments.addTarget(pkg)
}
@ -349,7 +335,7 @@ func install(parser *arguments) error {
}
if config.CleanAfter {
cleanAfter(do.Aur)
cleanAfter(ds.Aur)
}
return nil
@ -906,8 +892,8 @@ func downloadPkgbuildsSources(bases []Base, incompatible stringSet) (err error)
return
}
func buildInstallPkgbuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc.Srcinfo, parser *arguments, incompatible stringSet, conflicts mapStringSet) error {
for _, base := range do.Aur {
func buildInstallPkgbuilds(ds *depSolver, srcinfos map[string]*gosrc.Srcinfo, parser *arguments, incompatible stringSet, conflicts mapStringSet) error {
for _, base := range ds.Aur {
pkg := base.Pkgbase()
dir := filepath.Join(config.BuildDir, pkg)
built := true
@ -933,7 +919,7 @@ func buildInstallPkgbuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc
isExplicit := false
for _, b := range base {
isExplicit = isExplicit || dp.Explicit.get(b.Name)
isExplicit = isExplicit || ds.Explicit.get(b.Name)
}
if config.ReBuild == "no" || (config.ReBuild == "yes" && !isExplicit) {
for _, split := range base {
@ -956,7 +942,7 @@ func buildInstallPkgbuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc
if cmdArgs.existsArg("needed") {
installed := true
for _, split := range base {
if alpmpkg, err := dp.LocalDb.PkgByName(split.Name); err != nil || alpmpkg.Version() != version {
if alpmpkg, err := ds.LocalDb.PkgByName(split.Name); err != nil || alpmpkg.Version() != version {
installed = false
}
}
@ -1040,11 +1026,11 @@ func buildInstallPkgbuilds(dp *depPool, do *depOrder, srcinfos map[string]*gosrc
}
arguments.addTarget(pkgdest)
if !dp.Explicit.get(split.Name) && !localNamesCache.get(split.Name) && !remoteNamesCache.get(split.Name) {
if !ds.Explicit.get(split.Name) && !localNamesCache.get(split.Name) && !remoteNamesCache.get(split.Name) {
depArguments.addTarget(split.Name)
}
if dp.Explicit.get(split.Name) {
if ds.Explicit.get(split.Name) {
if parser.existsArg("asdeps", "asdep") {
depArguments.addTarget(split.Name)
} else if parser.existsArg("asexplicit", "asexp") {