Bläddra i källkod

Use depSolver in install

morganamilo 6 år sedan
förälder
incheckning
4ff36fbd4b
2 ändrade filer med 237 tillägg och 50 borttagningar
  1. 201 0
      depSolver.go
  2. 36 50
      install.go

+ 201 - 0
depSolver.go

@@ -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
+}

+ 36 - 50
install.go

@@ -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") {