mirror of
https://github.com/Jguer/yay
synced 2024-10-31 04:12:51 +00:00
Merge pull request #275 from ratorx/master
Recursively remove dependencies when using yay -Yc
This commit is contained in:
commit
13ef6f66ab
5 changed files with 94 additions and 18 deletions
2
Gopkg.lock
generated
2
Gopkg.lock
generated
|
@ -5,7 +5,7 @@
|
||||||
branch = "master"
|
branch = "master"
|
||||||
name = "github.com/jguer/go-alpm"
|
name = "github.com/jguer/go-alpm"
|
||||||
packages = ["."]
|
packages = ["."]
|
||||||
revision = "ec031c9cd5f6050edc3c2f23df2bff3bbb9511cc"
|
revision = "bc954af9b2ced79e4db54ce6ab3c6a24d769e98b"
|
||||||
|
|
||||||
[[projects]]
|
[[projects]]
|
||||||
branch = "master"
|
branch = "master"
|
||||||
|
|
10
clean.go
10
clean.go
|
@ -20,16 +20,13 @@ func removeVCSPackage(pkgs []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CleanDependencies removes all dangling dependencies in system
|
// CleanDependencies removes all dangling dependencies in system
|
||||||
func cleanDependencies() error {
|
func cleanDependencies(removeOptional bool) error {
|
||||||
hanging, err := hangingPackages()
|
hanging, err := hangingPackages(removeOptional)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(hanging) != 0 {
|
if len(hanging) != 0 {
|
||||||
if !continueTask("Confirm Removal?", "nN") {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
err = cleanRemove(hanging)
|
err = cleanRemove(hanging)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,12 +39,9 @@ func cleanRemove(pkgNames []string) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
oldvalue := config.NoConfirm
|
|
||||||
config.NoConfirm = true
|
|
||||||
arguments := makeArguments()
|
arguments := makeArguments()
|
||||||
arguments.addArg("R")
|
arguments.addArg("R")
|
||||||
arguments.addTarget(pkgNames...)
|
arguments.addTarget(pkgNames...)
|
||||||
err = passToPacman(arguments)
|
err = passToPacman(arguments)
|
||||||
config.NoConfirm = oldvalue
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
4
cmd.go
4
cmd.go
|
@ -323,8 +323,10 @@ func handleYay() (err error) {
|
||||||
//_, options, targets := cmdArgs.formatArgs()
|
//_, options, targets := cmdArgs.formatArgs()
|
||||||
if cmdArgs.existsArg("gendb") {
|
if cmdArgs.existsArg("gendb") {
|
||||||
err = createDevelDB()
|
err = createDevelDB()
|
||||||
|
} else if cmdArgs.existsDouble("c") {
|
||||||
|
err = cleanDependencies(true)
|
||||||
} else if cmdArgs.existsArg("c", "clean") {
|
} else if cmdArgs.existsArg("c", "clean") {
|
||||||
err = cleanDependencies()
|
err = cleanDependencies(false)
|
||||||
} else if len(cmdArgs.targets) > 0 {
|
} else if len(cmdArgs.targets) > 0 {
|
||||||
err = handleYogurt()
|
err = handleYogurt()
|
||||||
}
|
}
|
||||||
|
|
81
query.go
81
query.go
|
@ -313,26 +313,91 @@ func packageSlices(toCheck []string) (aur []string, repo []string, err error) {
|
||||||
|
|
||||||
// HangingPackages returns a list of packages installed as deps
|
// HangingPackages returns a list of packages installed as deps
|
||||||
// and unneeded by the system
|
// 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()
|
localDb, err := alpmHandle.LocalDb()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
f := func(pkg alpm.Package) error {
|
// safePackages represents every package in the system in one of 3 states
|
||||||
if pkg.Reason() != alpm.PkgReasonDepend {
|
// 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
|
||||||
|
provides := make(map[string]stringSet)
|
||||||
|
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 {
|
||||||
|
addMapStringSet(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
|
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 pset, ok2 := provides[dep.Name]; ok2 {
|
||||||
|
for p := range pset {
|
||||||
|
if safePackages[p] == 0 {
|
||||||
|
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
|
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
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
15
vendor/github.com/jguer/go-alpm/package.go
generated
vendored
15
vendor/github.com/jguer/go-alpm/package.go
generated
vendored
|
@ -282,6 +282,21 @@ func (pkg Package) ComputeRequiredBy() []string {
|
||||||
return requiredby
|
return requiredby
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ComputeOptionalFor returns the names of packages that optionally require the given package
|
||||||
|
func (pkg Package) ComputeOptionalFor() []string {
|
||||||
|
result := C.alpm_pkg_compute_optionalfor(pkg.pmpkg)
|
||||||
|
optionalfor := make([]string, 0)
|
||||||
|
for i := (*list)(unsafe.Pointer(result)); i != nil; i = i.Next {
|
||||||
|
defer C.free(unsafe.Pointer(i))
|
||||||
|
if i.Data != nil {
|
||||||
|
defer C.free(unsafe.Pointer(i.Data))
|
||||||
|
name := C.GoString((*C.char)(unsafe.Pointer(i.Data)))
|
||||||
|
optionalfor = append(optionalfor, name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return optionalfor
|
||||||
|
}
|
||||||
|
|
||||||
// NewVersion checks if there is a new version of the package in the Synced DBs.
|
// NewVersion checks if there is a new version of the package in the Synced DBs.
|
||||||
func (pkg Package) NewVersion(l DbList) *Package {
|
func (pkg Package) NewVersion(l DbList) *Package {
|
||||||
ptr := C.alpm_sync_newversion(pkg.pmpkg,
|
ptr := C.alpm_sync_newversion(pkg.pmpkg,
|
||||||
|
|
Loading…
Reference in a new issue