1 |
I found the original code to be nearly incomprehensible. Instead of |
2 |
populating a dict of potential binpkgs to remove and then removing from |
3 |
the to-be-removed list, just selectively add to-be-removed packages. |
4 |
|
5 |
Signed-off-by: Matt Turner <mattst88@g.o> |
6 |
--- |
7 |
pym/gentoolkit/eclean/search.py | 113 ++++++++++++++++---------------- |
8 |
1 file changed, 55 insertions(+), 58 deletions(-) |
9 |
|
10 |
diff --git a/pym/gentoolkit/eclean/search.py b/pym/gentoolkit/eclean/search.py |
11 |
index 58bd97e..0efefdb 100644 |
12 |
--- a/pym/gentoolkit/eclean/search.py |
13 |
+++ b/pym/gentoolkit/eclean/search.py |
14 |
@@ -498,89 +498,86 @@ def findPackages( |
15 |
port_dbapi=portage.db[portage.root]["porttree"].dbapi, |
16 |
var_dbapi=portage.db[portage.root]["vartree"].dbapi |
17 |
): |
18 |
- """Find all obsolete binary packages. |
19 |
- |
20 |
- XXX: packages are found only by symlinks. |
21 |
- Maybe i should also return .tbz2 files from All/ that have |
22 |
- no corresponding symlinks. |
23 |
+ """Find obsolete binary packages. |
24 |
|
25 |
@param options: dict of options determined at runtime |
26 |
- @param exclude: an exclusion dict as defined in |
27 |
- exclude.parseExcludeFile class. |
28 |
- @param destructive: boolean, defaults to False |
29 |
- @param time_limit: integer time value as returned by parseTime() |
30 |
- @param package_names: boolean, defaults to False. |
31 |
- used only if destructive=True |
32 |
- @param pkgdir: path to the binary package dir being checked |
33 |
+ @type options: dict |
34 |
+ @param exclude: exclusion dict (as defined in the exclude.parseExcludeFile class) |
35 |
+ @type exclude: dict, optional |
36 |
+ @param destructive: binpkg is obsolete if not installed (default: `False`) |
37 |
+ @type destructive: bool, optional |
38 |
+ @param time_limit: exclude binpkg if newer than time value as returned by parseTime() |
39 |
+ @type time_limit: int, optional |
40 |
+ @param package_names: exclude all binpkg versions if package is installed |
41 |
+ (used with `destructive=True`) (default: `False`) |
42 |
+ @type package_names: bool, optional |
43 |
+ @param pkgdir: path to the binpkg cache (PKGDIR) |
44 |
+ @type pkgdir: str |
45 |
@param port_dbapi: defaults to portage.db[portage.root]["porttree"].dbapi |
46 |
- can be overridden for tests. |
47 |
- @param var_dbapi: defaults to portage.db[portage.root]["vartree"].dbapi |
48 |
- can be overridden for tests. |
49 |
+ Can be overridden for tests. |
50 |
+ @param var_dbapi: defaults to portage.db[portage.root]["vartree"].dbapi |
51 |
+ Can be overridden for tests. |
52 |
|
53 |
+ @return binary packages to remove. e.g. {'cat/pkg-ver': [filepath]} |
54 |
@rtype: dict |
55 |
- @return clean_me i.e. {'cat/pkg-ver.tbz2': [filepath],} |
56 |
""" |
57 |
if exclude is None: |
58 |
exclude = {} |
59 |
- clean_me = {} |
60 |
- # create a full package dictionary |
61 |
|
62 |
- # now do an access test, os.walk does not error for "no read permission" |
63 |
+ # Access test, os.walk does not error for "no read permission" |
64 |
try: |
65 |
test = os.listdir(pkgdir) |
66 |
del test |
67 |
except EnvironmentError as er: |
68 |
if options['ignore-failure']: |
69 |
exit(0) |
70 |
- print( pp.error("Error accessing PKGDIR." ), file=sys.stderr) |
71 |
- print( pp.error("(Check your make.conf file and environment)."), file=sys.stderr) |
72 |
- print( pp.error("Error: %s" %str(er)), file=sys.stderr) |
73 |
+ print(pp.error("Error accessing PKGDIR."), file=sys.stderr) |
74 |
+ print(pp.error("(Check your make.conf file and environment)."), file=sys.stderr) |
75 |
+ print(pp.error("Error: %s" % str(er)), file=sys.stderr) |
76 |
exit(1) |
77 |
|
78 |
- # if portage supports FEATURES=binpkg-multi-instance, then |
79 |
- # cpv_all can return multiple instances per cpv, where |
80 |
- # instances are distinguishable by some extra attributes |
81 |
- # provided by portage's _pkg_str class |
82 |
+ # Create a dictionary of all installed packages |
83 |
+ if destructive and package_names: |
84 |
+ installed = dict.fromkeys(var_dbapi.cp_all()) |
85 |
+ else: |
86 |
+ installed = {} |
87 |
+ |
88 |
+ # Dictionary of binary packages to clean. Organized as cpv->[pkgs] in order |
89 |
+ # to support FEATURES=binpkg-multi-instance. |
90 |
+ dead_binpkgs = {} |
91 |
+ |
92 |
bin_dbapi = portage.binarytree(pkgdir=pkgdir, settings=var_dbapi.settings).dbapi |
93 |
for cpv in bin_dbapi.cpv_all(): |
94 |
- mtime = int(bin_dbapi.aux_get(cpv, ['_mtime_'])[0]) |
95 |
- if time_limit and mtime >= time_limit: |
96 |
- # time-limit exclusion |
97 |
- continue |
98 |
- # dict is cpv->[pkgs] (supports binpkg-multi-instance) |
99 |
- clean_me.setdefault(cpv, []).append(cpv) |
100 |
+ cp = portage.cpv_getkey(cpv) |
101 |
|
102 |
- # keep only obsolete ones |
103 |
- if destructive and package_names: |
104 |
- cp_all = dict.fromkeys(var_dbapi.cp_all()) |
105 |
- else: |
106 |
- cp_all = {} |
107 |
- for cpv in list(clean_me): |
108 |
- if exclDictMatchCP(exclude,portage.cpv_getkey(cpv)): |
109 |
- # exclusion because of the exclude file |
110 |
- del clean_me[cpv] |
111 |
+ # Exclude per --exclude-file=... |
112 |
+ if exclDictMatchCP(exclude, cp): |
113 |
continue |
114 |
+ |
115 |
+ # Exclude if binpkg is newer than --time-limit=... |
116 |
+ if time_limit: |
117 |
+ mtime = int(bin_dbapi.aux_get(cpv, ['_mtime_'])[0]) |
118 |
+ if mtime >= time_limit: |
119 |
+ continue |
120 |
+ |
121 |
+ # Exclude if binpkg exists in the porttree and not --deep |
122 |
if not destructive and port_dbapi.cpv_exists(cpv): |
123 |
- # exclusion because pkg still exists (in porttree) |
124 |
- del clean_me[cpv] |
125 |
continue |
126 |
+ |
127 |
if destructive and var_dbapi.cpv_exists(cpv): |
128 |
+ # Exclude if an instance of the package is installed due to |
129 |
+ # the --package-names option. |
130 |
+ if cp in installed and port_dbapi.cpv_exists(cpv): |
131 |
+ continue |
132 |
+ |
133 |
+ # Exclude if BUILD_TIME of binpkg is same as vartree |
134 |
buildtime = var_dbapi.aux_get(cpv, ['BUILD_TIME'])[0] |
135 |
- clean_me[cpv] = [pkg for pkg in clean_me[cpv] |
136 |
- # only keep path if BUILD_TIME is identical with vartree |
137 |
- if bin_dbapi.aux_get(pkg, ['BUILD_TIME'])[0] != buildtime] |
138 |
- if not clean_me[cpv]: |
139 |
- # nothing we can clean for this package |
140 |
- del clean_me[cpv] |
141 |
+ if buildtime == bin_dbapi.aux_get(cpv, ['BUILD_TIME'])[0]: |
142 |
continue |
143 |
- if portage.cpv_getkey(cpv) in cp_all and port_dbapi.cpv_exists(cpv): |
144 |
- # exclusion because of --package-names |
145 |
- del clean_me[cpv] |
146 |
|
147 |
- # the getname method correctly supports FEATURES=binpkg-multi-instance, |
148 |
- # allowing for multiple paths per cpv (the API used here is also compatible |
149 |
- # with older portage which does not support binpkg-multi-instance) |
150 |
- for cpv, pkgs in clean_me.items(): |
151 |
- clean_me[cpv] = [bin_dbapi.bintree.getname(pkg) for pkg in pkgs] |
152 |
+ binpkg_path = bin_dbapi.bintree.getname(cpv) |
153 |
+ dead_binpkgs.setdefault(cpv, []).append(binpkg_path) |
154 |
+ |
155 |
+ return dead_binpkgs |
156 |
|
157 |
- return clean_me |
158 |
+# vim: set ts=4 sw=4 tw=79: |
159 |
-- |
160 |
2.24.1 |