Gentoo Archives: gentoo-portage-dev

From: Matt Turner <mattst88@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Matt Turner <mattst88@g.o>
Subject: [gentoo-portage-dev] [PATCH v2 gentoolkit 1/2] eclean: Rewrite findPackages()
Date: Sat, 07 Mar 2020 06:11:16
Message-Id: 20200307061110.1034493-1-mattst88@gentoo.org
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

Replies