mirror of
https://github.com/Jguer/yay.git
synced 2025-12-15 00:05:43 -05:00
Add recursive removal of packages
This commit is contained in:
parent
8a0bade6cd
commit
1b704a869d
10
clean.go
10
clean.go
@ -20,16 +20,13 @@ func removeVCSPackage(pkgs []string) {
|
||||
}
|
||||
|
||||
// CleanDependencies removes all dangling dependencies in system
|
||||
func cleanDependencies() error {
|
||||
hanging, err := hangingPackages()
|
||||
func cleanDependencies(removeOptional bool) error {
|
||||
hanging, err := hangingPackages(removeOptional)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(hanging) != 0 {
|
||||
if !continueTask("Confirm Removal?", "nN") {
|
||||
return nil
|
||||
}
|
||||
err = cleanRemove(hanging)
|
||||
}
|
||||
|
||||
@ -42,12 +39,9 @@ func cleanRemove(pkgNames []string) (err error) {
|
||||
return nil
|
||||
}
|
||||
|
||||
oldvalue := config.NoConfirm
|
||||
config.NoConfirm = true
|
||||
arguments := makeArguments()
|
||||
arguments.addArg("R")
|
||||
arguments.addTarget(pkgNames...)
|
||||
err = passToPacman(arguments)
|
||||
config.NoConfirm = oldvalue
|
||||
return err
|
||||
}
|
||||
|
||||
4
cmd.go
4
cmd.go
@ -291,8 +291,10 @@ func handleYay() (err error) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else if cmdArgs.existsDouble("c") {
|
||||
err = cleanDependencies(true)
|
||||
} else if cmdArgs.existsArg("c", "clean") {
|
||||
err = cleanDependencies()
|
||||
err = cleanDependencies(false)
|
||||
} else if len(cmdArgs.targets) > 0 {
|
||||
err = handleYogurt()
|
||||
}
|
||||
|
||||
79
query.go
79
query.go
@ -274,26 +274,89 @@ func packageSlices(toCheck []string) (aur []string, repo []string, err error) {
|
||||
|
||||
// HangingPackages returns a list of packages installed as deps
|
||||
// and unneeded by the system
|
||||
func hangingPackages() (hanging []string, err error) {
|
||||
// removeOptional decides whether optional dependencies are counted or not
|
||||
func hangingPackages(removeOptional bool) (hanging []string, err error) {
|
||||
localDb, err := alpmHandle.LocalDb()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
f := func(pkg alpm.Package) error {
|
||||
if pkg.Reason() != alpm.PkgReasonDepend {
|
||||
// safePackages represents every package in the system in one of 3 states
|
||||
// State = 0 - Remove package from the system
|
||||
// State = 1 - Keep package in the system; need to iterate over dependencies
|
||||
// State = 2 - Keep package and have iterated over dependencies
|
||||
safePackages := make(map[string]uint8)
|
||||
// provides stores a mapping from the provides name back to the original package name
|
||||
// Assumption - multiple installed packages don't provide the same dependency
|
||||
provides := make(map[string]string)
|
||||
packages := localDb.PkgCache()
|
||||
|
||||
// Mark explicit dependencies and enumerate the provides list
|
||||
setupResources := func(pkg alpm.Package) error {
|
||||
if pkg.Reason() == alpm.PkgReasonExplicit {
|
||||
safePackages[pkg.Name()] = 1
|
||||
} else {
|
||||
safePackages[pkg.Name()] = 0
|
||||
}
|
||||
|
||||
pkg.Provides().ForEach(func(dep alpm.Depend) error {
|
||||
provides[dep.Name] = pkg.Name()
|
||||
return nil
|
||||
})
|
||||
return nil
|
||||
}
|
||||
packages.ForEach(setupResources)
|
||||
|
||||
iterateAgain := true
|
||||
processDependencies := func(pkg alpm.Package) error {
|
||||
if state, _ := safePackages[pkg.Name()]; state == 0 || state == 2 {
|
||||
return nil
|
||||
}
|
||||
requiredby := pkg.ComputeRequiredBy()
|
||||
if len(requiredby) == 0 {
|
||||
hanging = append(hanging, pkg.Name())
|
||||
fmt.Println(pkg.Name() + ": " + magenta(human(pkg.ISize())))
|
||||
|
||||
safePackages[pkg.Name()] = 2
|
||||
|
||||
// Update state for dependencies
|
||||
markDependencies := func(dep alpm.Depend) error {
|
||||
// Don't assume a dependency is installed
|
||||
state, ok := safePackages[dep.Name]
|
||||
if !ok {
|
||||
// Check if dep is a provides rather than actual package name
|
||||
if p, ok2 := provides[dep.Name]; ok2 {
|
||||
iterateAgain = true
|
||||
safePackages[p] = 1
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
if state == 0 {
|
||||
iterateAgain = true
|
||||
safePackages[dep.Name] = 1
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
pkg.Depends().ForEach(markDependencies)
|
||||
if !removeOptional {
|
||||
pkg.OptionalDepends().ForEach(markDependencies)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
err = localDb.PkgCache().ForEach(f)
|
||||
for iterateAgain {
|
||||
iterateAgain = false
|
||||
packages.ForEach(processDependencies)
|
||||
}
|
||||
|
||||
// Build list of packages to be removed
|
||||
packages.ForEach(func(pkg alpm.Package) error {
|
||||
if safePackages[pkg.Name()] == 0 {
|
||||
hanging = append(hanging, pkg.Name())
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user