Merge lp:~mvo/aptdaemon/mvo into lp:aptdaemon

Proposed by Michael Vogt
Status: Merged
Merge reported by: Michael Vogt
Merged at revision: not available
Proposed branch: lp:~mvo/aptdaemon/mvo
Merge into: lp:aptdaemon
Diff against target: 143 lines (+63/-10)
3 files modified
aptdaemon/client.py (+6/-3)
aptdaemon/core.py (+9/-4)
aptdaemon/worker.py (+48/-3)
To merge this branch: bzr merge lp:~mvo/aptdaemon/mvo
Reviewer Review Type Date Requested Status
Sebastian Heinlein Disapprove
Review via email: mp+16775@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Michael Vogt (mvo) wrote :

support for removal of unused dependencies

Revision history for this message
Sebastian Heinlein (glatzor) wrote :

Was implemented as a transaction attribute some time ago

review: Disapprove

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'aptdaemon/client.py'
2--- aptdaemon/client.py 2009-12-12 11:15:12 +0000
3+++ aptdaemon/client.py 2010-01-04 11:07:14 +0000
4@@ -491,10 +491,13 @@
5 return self._run_transaction("UpgradePackages", [package_names],
6 wait, reply_handler, error_handler)
7
8- def remove_packages(self, package_names, wait=False, reply_handler=None,
9- error_handler=None):
10+ def remove_packages(self, package_names, wait=False,
11+ remove_unused_dependencies=False,
12+ reply_handler=None, error_handler=None):
13 """Remove packages by name."""
14- return self._run_transaction("RemovePackages", [package_names],
15+ return self._run_transaction("RemovePackages",
16+ (package_names,
17+ remove_unused_dependencies),
18 wait, reply_handler, error_handler)
19
20 def commit_packages(self, install, reinstall, remove, purge, upgrade,
21
22=== modified file 'aptdaemon/core.py'
23--- aptdaemon/core.py 2009-12-12 09:13:33 +0000
24+++ aptdaemon/core.py 2010-01-04 11:07:14 +0000
25@@ -865,24 +865,29 @@
26 return deferred
27
28 @dbus_deferred_method(APTDAEMON_DBUS_INTERFACE,
29- in_signature="as", out_signature="s",
30+ in_signature="asb", out_signature="s",
31 sender_keyword="sender")
32- def RemovePackages(self, package_names, sender):
33+ def RemovePackages(self, package_names, remove_unused_dependencies, sender):
34 """Return the id of a newly create transaction which will remove
35 the given packages.
36
37 Keyword arguments:
38 package_names -- list of package names to remove
39+ remove_unused_dependencies -- remove direct unused dependencies too
40 sender -- the unique D-Bus name of the sender (provided by D-Bus)
41 """
42- log.info("RemovePackages() was called: %s" % package_names)
43+ log.info("RemovePackages() was called: '%s' '%i'" % (
44+ package_names, remove_unused_dependencies))
45 packages = ([], [], package_names, [], [])
46+ kwargs = {"remove_unused_dependencies": remove_unused_dependencies,
47+ "package_names" : package_names,
48+ }
49 deferred = policykit1.check_authorization_by_name(sender,
50 policykit1.PK_ACTION_REMOVE_PACKAGES)
51 deferred.add_callback(lambda x: policykit1.get_uid_from_dbus_name(sender))
52 deferred.add_callback(lambda uid: Transaction(ROLE_REMOVE_PACKAGES,
53 self.queue, uid,
54- packages=packages))
55+ kwargs=kwargs))
56 deferred.add_callback(lambda trans: trans.tid)
57 return deferred
58
59
60=== modified file 'aptdaemon/worker.py'
61--- aptdaemon/worker.py 2009-12-13 07:59:57 +0000
62+++ aptdaemon/worker.py 2010-01-04 11:07:14 +0000
63@@ -94,7 +94,7 @@
64 elif self.trans.role == ROLE_INSTALL_FILE:
65 self.install_file(**self.trans.kwargs)
66 elif self.trans.role == ROLE_REMOVE_PACKAGES:
67- self.remove_packages(self.trans.packages[2])
68+ self.remove_packages(**self.trans.kwargs)
69 elif self.trans.role == ROLE_UPGRADE_SYSTEM:
70 self.upgrade_system(**self.trans.kwargs)
71 elif self.trans.role == ROLE_UPDATE_CACHE:
72@@ -281,18 +281,26 @@
73 begin=64, end=95)):
74 raise TransactionFailed(ERROR_UNKNOWN, deb._failure_string)
75
76- def remove_packages(self, package_names):
77+ def remove_packages(self, package_names, remove_unused_dependencies):
78 """Remove packages.
79
80 Keyword argument:
81 package_names -- list of package name which should be installed
82+ remove_unused_dependencies -- remove unused direct dependencies
83 """
84- log.info("Removing packages: %s", package_names)
85+ log.info("Removing packages: '%s' '%i'" % (package_names, remove_unused_dependencies))
86 ac = self._cache.actiongroup()
87 resolver = apt.cache.ProblemResolver(self._cache)
88 self._mark_packages_for_removal(package_names, resolver)
89 self._resolve_depends(resolver)
90 ac.release()
91+ if remove_unused_dependencies:
92+ # remove no longer used automatic dependencies
93+ ac = self._cache.actiongroup()
94+ for pkgname in package_names:
95+ for unused in self._get_installed_automatic_depends_for_pkg(pkgname):
96+ self._cache[unused].markDelete()
97+ ac.release()
98 self._commit_changes(fetch_range=(10, 10),
99 install_range=(10, 90))
100 #FIXME: should we use a persistant cache? make a check?
101@@ -322,6 +330,43 @@
102 resolver.protect(pkg)
103 resolver.remove(pkg)
104
105+ def _installed_dependencies(self, pkg_name, all_deps=None):
106+ """ recursively return all installed dependencies of a given pkg """
107+ #print "_installed_dependencies", pkg_name, all_deps
108+ if not all_deps:
109+ all_deps = set()
110+ if not self._cache.has_key(pkg_name):
111+ return all_deps
112+ cur = self._cache[pkg_name]._pkg.CurrentVer
113+ if not cur:
114+ return all_deps
115+ for t in ("PreDepends", "Depends", "Recommends"):
116+ try:
117+ for dep in cur.DependsList[t]:
118+ dep_name = dep[0].TargetPkg.Name
119+ if not dep_name in all_deps:
120+ all_deps.add(dep_name)
121+ all_deps |= self._installed_dependencies(dep_name, all_deps)
122+ except KeyError:
123+ pass
124+ return all_deps
125+ def _get_installed_automatic_depends_for_pkg(self, pkgname):
126+ """ Get the installed automatic dependencies for this given package
127+ only.
128+
129+ Note that the package must be marked for removal already for
130+ this to work
131+ """
132+ installed_auto_deps = set()
133+ deps = self._installed_dependencies(pkgname)
134+ for dep_name in deps:
135+ if self._cache.has_key(dep_name):
136+ pkg = self._cache[dep_name]
137+ if (pkg.isInstalled and
138+ pkg.isAutoRemovable):
139+ installed_auto_deps.add(dep_name)
140+ return installed_auto_deps
141+
142 def upgrade_packages(self, package_names):
143 """Upgrade packages.
144

Subscribers

People subscribed via source and target branches

to status/vote changes: