[Yum-devel] [PATCH] Fix _remove_old_deps to deal with chains of revdeps.
seth vidal
skvidal at fedoraproject.org
Fri Apr 8 15:56:17 UTC 2011
On Fri, 2011-04-08 at 08:44 -0700, Casey Jao wrote:
> ---
> yum/__init__.py | 69
> +++++++++++++++++++++++++++++++++++++++++++++++++++----
> 1 files changed, 64 insertions(+), 5 deletions(-)
>
> diff --git a/yum/__init__.py b/yum/__init__.py
> index cf4d827..bbb5204 100644
> --- a/yum/__init__.py
> +++ b/yum/__init__.py
> @@ -5276,6 +5276,11 @@ class YumBase(depsolve.Depsolve):
> found_leaves = set()
> checked = set()
> beingremoved = [ t.po for t in
> self.tsInfo.getMembersWithState(output_states=TS_REMOVE_STATES) ]
> + # cache previously examined packages
> + okay_to_remove = {}
> + for i in self.rpmdb.returnPackages():
> + okay_to_remove[i] = True
> +
> for pkg in beingremoved: # for each package required by the pkg
> being removed
> #print 'removal: %s' % pkg.name
> for required in pkg.required_packages():
> @@ -5283,23 +5288,29 @@ class YumBase(depsolve.Depsolve):
> # continue # if we've already checked it, skip it.
> #checked.add(required)
> if required.yumdb_info.get('reason', '') != 'dep': # if
> the required pkg is not a dep, then skip it
> + okay_to_remove[required] = False
> continue
> if required in beingremoved:
> continue
> + if self._has_needed_revdeps(required, beingremoved,
> okay_to_remove):
> + continue
> still_needed = False
> for requiring in required.requiring_packages(): # so we
> have required deps - look at all the pkgs which require them
> if requiring == required: # if they are
> self-requiring skip them
> continue
> - if requiring not in beingremoved: # if the
> requiring pkg is not in the list of pkgs being removed then it is still
> needed
> - still_needed = True
> - break
> + #if requiring not in beingremoved: # if the
> requiring pkg is not in the list of pkgs being removed then it is still
> needed
> + #still_needed = True
> + #break
> +
> # go through the stuff in the ts to be installed - make
> sure none of that needs the required pkg, either.
> for (provn,provf,provevr) in required.provides:
> if self.tsInfo.getNewRequires(provn, provf,
> provevr).keys():
> still_needed = True
> + okay_to_remove[required] = False
> break
> for fn in required.filelist + required.dirlist:
> if self.tsInfo.getNewRequires(fn,
> None,(None,None,None)).keys():
> + okay_to_remove[required] = False
> still_needed = True
> break
>
> @@ -5319,5 +5330,53 @@ class YumBase(depsolve.Depsolve):
> beingremoved.append(txmbr.po)
> found_leaves.add(txmbr)
> self.verbose_logger.log(logginglevels.INFO_2, "Found and
> removing %s unneeded dependencies" % len(found_leaves))
> -
> -
> +
> + # Checks if pkg has any reverse deps which cannot be removed.
> + # Currently this only checks the install reason for each revdep,
> + # but we may want to check for other reasons that would
> + # prevent the revdep from being removed (e.g. protected)
> + def _has_needed_revdeps(self, pkg, beingremoved, ok_to_remove):
> + # check if we've already found this package to have
> user-installed deps
> + if not ok_to_remove[pkg]:
> + # Debugging output
> + #print pkg, "has been visited already and cannot be removed!!!"
> + return True
> + # Debugging output
> + #print "Examining revdeps of", pkg
> + # track which pkgs we have visited already
> + visited = {}
> + for po in self.rpmdb.returnPackages():
> + visited[po] = False
> + # no need to consider packages that are already being removed
> + for po in beingremoved:
> + visited[po] = True
> + stack = []
> + stack.append(pkg)
> + # depth-first search
> + while stack:
> + curpkg = stack[-1]
> + if not visited[curpkg]:
> + if not ok_to_remove[curpkg]:
> + # Debugging
> + #print pkg, "has been visited already and cannot be
> removed!!!"
> + ok_to_remove[pkg] = False
> + return True
> + if curpkg.yumdb_info.get('reason', '') != 'dep':
> + # Debugging output
> + #print pkg, "has revdep", curpkg, "which was
> user-installed."
> + ok_to_remove[pkg] = False
> + return True
> + visited[curpkg] = True
> + all_leaves_visited = True
> + leaves = curpkg.requiring_packages()
> + for leaf in leaves:
> + if not visited[leaf]:
> + stack.append(leaf)
> + all_leaves_visited = False
> + break
> + if all_leaves_visited:
> + stack.pop()
> + # Debugging output
> + #print pkg, "has no user-installed revdeps"
> + return False
> +
> _______________________________________________
> Yum-devel mailing list
> Yum-devel at lists.baseurl.org
> http://lists.baseurl.org/mailman/listinfo/yum-devel
Casey,
This looks pretty good. Can you clean up the debugging comments and
maybe turn them into higher debug-level log calls? Also do you have any
testcases to go along with this?
Thanks,
-sv
More information about the Yum-devel
mailing list