Gentoo Archives: gentoo-portage-dev

From: Zac Medico <zmedico@g.o>
To: gentoo-portage-dev@l.g.o
Cc: Zac Medico <zmedico@g.o>
Subject: [gentoo-portage-dev] [PATCH 1/7 v2] binpkg-multi-instance 1 of 7
Date: Thu, 19 Feb 2015 22:27:08
Message-Id: 1424384786-31027-1-git-send-email-zmedico@gentoo.org
In Reply to: [gentoo-portage-dev] [PATCH 1/7] binpkg-multi-instance 1 of 7 by Zac Medico
1 Extend the _pkg_str class with build_id, build_time, file_size, and
2 mtime attributes. These will be used to distinguish binary package
3 instances that have the same cpv. Package sorting accounts for
4 build_time, which will be used to prefer newer builds over older builds
5 when their versions are identical.
6 ---
7 [PATCH 1/7 v2] updates pkg_desc_index._pkg_node to have a build_time
8 attribute, which fixes an AttributeError raised from dbapi._cmp_cpv
9 for some emerge search actions.
10
11 pym/_emerge/Package.py | 51 +++++++++++++++++++++----------
12 pym/_emerge/resolver/output.py | 21 ++++++++++---
13 pym/portage/cache/index/pkg_desc_index.py | 1 +
14 pym/portage/dbapi/__init__.py | 10 ++++--
15 pym/portage/dbapi/vartree.py | 8 +++--
16 pym/portage/versions.py | 28 +++++++++++++++--
17 6 files changed, 93 insertions(+), 26 deletions(-)
18
19 diff --git a/pym/_emerge/Package.py b/pym/_emerge/Package.py
20 index e8a13cb..975335d 100644
21 --- a/pym/_emerge/Package.py
22 +++ b/pym/_emerge/Package.py
23 @@ -41,12 +41,12 @@ class Package(Task):
24 "_validated_atoms", "_visible")
25
26 metadata_keys = [
27 - "BUILD_TIME", "CHOST", "COUNTER", "DEPEND", "EAPI",
28 - "HDEPEND", "INHERITED", "IUSE", "KEYWORDS",
29 - "LICENSE", "PDEPEND", "PROVIDE", "RDEPEND",
30 - "repository", "PROPERTIES", "RESTRICT", "SLOT", "USE",
31 - "_mtime_", "DEFINED_PHASES", "REQUIRED_USE", "PROVIDES",
32 - "REQUIRES"]
33 + "BUILD_ID", "BUILD_TIME", "CHOST", "COUNTER", "DEFINED_PHASES",
34 + "DEPEND", "EAPI", "HDEPEND", "INHERITED", "IUSE", "KEYWORDS",
35 + "LICENSE", "MD5", "PDEPEND", "PROVIDE", "PROVIDES",
36 + "RDEPEND", "repository", "REQUIRED_USE",
37 + "PROPERTIES", "REQUIRES", "RESTRICT", "SIZE",
38 + "SLOT", "USE", "_mtime_"]
39
40 _dep_keys = ('DEPEND', 'HDEPEND', 'PDEPEND', 'RDEPEND')
41 _buildtime_keys = ('DEPEND', 'HDEPEND')
42 @@ -114,13 +114,14 @@ class Package(Task):
43 return self._metadata["EAPI"]
44
45 @property
46 + def build_id(self):
47 + return self.cpv.build_id
48 +
49 + @property
50 def build_time(self):
51 if not self.built:
52 raise AttributeError('build_time')
53 - try:
54 - return long(self._metadata['BUILD_TIME'])
55 - except (KeyError, ValueError):
56 - return 0
57 + return self.cpv.build_time
58
59 @property
60 def defined_phases(self):
61 @@ -509,9 +510,15 @@ class Package(Task):
62 else:
63 cpv_color = "PKG_NOMERGE"
64
65 + build_id_str = ""
66 + if isinstance(self.cpv.build_id, long) and self.cpv.build_id > 0:
67 + build_id_str = "-%s" % self.cpv.build_id
68 +
69 s = "(%s, %s" \
70 - % (portage.output.colorize(cpv_color, self.cpv + _slot_separator + \
71 - self.slot + "/" + self.sub_slot + _repo_separator + self.repo) , self.type_name)
72 + % (portage.output.colorize(cpv_color, self.cpv +
73 + build_id_str + _slot_separator + self.slot + "/" +
74 + self.sub_slot + _repo_separator + self.repo),
75 + self.type_name)
76
77 if self.type_name == "installed":
78 if self.root_config.settings['ROOT'] != "/":
79 @@ -755,29 +762,41 @@ class Package(Task):
80 def __lt__(self, other):
81 if other.cp != self.cp:
82 return self.cp < other.cp
83 - if portage.vercmp(self.version, other.version) < 0:
84 + result = portage.vercmp(self.version, other.version)
85 + if result < 0:
86 return True
87 + if result == 0 and self.built and other.built:
88 + return self.build_time < other.build_time
89 return False
90
91 def __le__(self, other):
92 if other.cp != self.cp:
93 return self.cp <= other.cp
94 - if portage.vercmp(self.version, other.version) <= 0:
95 + result = portage.vercmp(self.version, other.version)
96 + if result <= 0:
97 return True
98 + if result == 0 and self.built and other.built:
99 + return self.build_time <= other.build_time
100 return False
101
102 def __gt__(self, other):
103 if other.cp != self.cp:
104 return self.cp > other.cp
105 - if portage.vercmp(self.version, other.version) > 0:
106 + result = portage.vercmp(self.version, other.version)
107 + if result > 0:
108 return True
109 + if result == 0 and self.built and other.built:
110 + return self.build_time > other.build_time
111 return False
112
113 def __ge__(self, other):
114 if other.cp != self.cp:
115 return self.cp >= other.cp
116 - if portage.vercmp(self.version, other.version) >= 0:
117 + result = portage.vercmp(self.version, other.version)
118 + if result >= 0:
119 return True
120 + if result == 0 and self.built and other.built:
121 + return self.build_time >= other.build_time
122 return False
123
124 def with_use(self, use):
125 diff --git a/pym/_emerge/resolver/output.py b/pym/_emerge/resolver/output.py
126 index 7df0302..400617d 100644
127 --- a/pym/_emerge/resolver/output.py
128 +++ b/pym/_emerge/resolver/output.py
129 @@ -424,6 +424,18 @@ class Display(object):
130 pkg_str += _repo_separator + pkg.repo
131 return pkg_str
132
133 + def _append_build_id(self, pkg_str, pkg, pkg_info):
134 + """Potentially appends repository to package string.
135 +
136 + @param pkg_str: string
137 + @param pkg: _emerge.Package.Package instance
138 + @param pkg_info: dictionary
139 + @rtype string
140 + """
141 + if pkg.type_name == "binary" and pkg.cpv.build_id is not None:
142 + pkg_str += "-%s" % pkg.cpv.build_id
143 + return pkg_str
144 +
145 def _set_non_root_columns(self, pkg, pkg_info):
146 """sets the indent level and formats the output
147
148 @@ -431,7 +443,7 @@ class Display(object):
149 @param pkg_info: dictionary
150 @rtype string
151 """
152 - ver_str = pkg_info.ver
153 + ver_str = self._append_build_id(pkg_info.ver, pkg, pkg_info)
154 if self.conf.verbosity == 3:
155 ver_str = self._append_slot(ver_str, pkg, pkg_info)
156 ver_str = self._append_repository(ver_str, pkg, pkg_info)
157 @@ -470,7 +482,7 @@ class Display(object):
158 @rtype string
159 Modifies self.verboseadd
160 """
161 - ver_str = pkg_info.ver
162 + ver_str = self._append_build_id(pkg_info.ver, pkg, pkg_info)
163 if self.conf.verbosity == 3:
164 ver_str = self._append_slot(ver_str, pkg, pkg_info)
165 ver_str = self._append_repository(ver_str, pkg, pkg_info)
166 @@ -507,7 +519,7 @@ class Display(object):
167 @param pkg_info: dictionary
168 @rtype the updated addl
169 """
170 - pkg_str = pkg.cpv
171 + pkg_str = self._append_build_id(pkg.cpv, pkg, pkg_info)
172 if self.conf.verbosity == 3:
173 pkg_str = self._append_slot(pkg_str, pkg, pkg_info)
174 pkg_str = self._append_repository(pkg_str, pkg, pkg_info)
175 @@ -868,7 +880,8 @@ class Display(object):
176 if self.conf.columns:
177 myprint = self._set_non_root_columns(pkg, pkg_info)
178 else:
179 - pkg_str = pkg.cpv
180 + pkg_str = self._append_build_id(
181 + pkg.cpv, pkg, pkg_info)
182 if self.conf.verbosity == 3:
183 pkg_str = self._append_slot(pkg_str, pkg, pkg_info)
184 pkg_str = self._append_repository(pkg_str, pkg, pkg_info)
185 diff --git a/pym/portage/cache/index/pkg_desc_index.py b/pym/portage/cache/index/pkg_desc_index.py
186 index a2e45da..dbcbb83 100644
187 --- a/pym/portage/cache/index/pkg_desc_index.py
188 +++ b/pym/portage/cache/index/pkg_desc_index.py
189 @@ -26,6 +26,7 @@ class pkg_node(_unicode):
190 self.__dict__['cp'] = cp
191 self.__dict__['repo'] = repo
192 self.__dict__['version'] = version
193 + self.__dict__['build_time'] = None
194
195 def __new__(cls, cp, version, repo=None):
196 return _unicode.__new__(cls, cp + "-" + version)
197 diff --git a/pym/portage/dbapi/__init__.py b/pym/portage/dbapi/__init__.py
198 index 34dfaa7..044faec 100644
199 --- a/pym/portage/dbapi/__init__.py
200 +++ b/pym/portage/dbapi/__init__.py
201 @@ -31,7 +31,8 @@ class dbapi(object):
202 _use_mutable = False
203 _known_keys = frozenset(x for x in auxdbkeys
204 if not x.startswith("UNUSED_0"))
205 - _pkg_str_aux_keys = ("EAPI", "KEYWORDS", "SLOT", "repository")
206 + _pkg_str_aux_keys = ("BUILD_TIME", "EAPI", "BUILD_ID",
207 + "KEYWORDS", "SLOT", "repository")
208
209 def __init__(self):
210 pass
211 @@ -57,7 +58,12 @@ class dbapi(object):
212
213 @staticmethod
214 def _cmp_cpv(cpv1, cpv2):
215 - return vercmp(cpv1.version, cpv2.version)
216 + result = vercmp(cpv1.version, cpv2.version)
217 + if (result == 0 and cpv1.build_time is not None and
218 + cpv2.build_time is not None):
219 + result = ((cpv1.build_time > cpv2.build_time) -
220 + (cpv1.build_time < cpv2.build_time))
221 + return result
222
223 @staticmethod
224 def _cpv_sort_ascending(cpv_list):
225 diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py
226 index cf31c8e..277c2f1 100644
227 --- a/pym/portage/dbapi/vartree.py
228 +++ b/pym/portage/dbapi/vartree.py
229 @@ -173,7 +173,8 @@ class vardbapi(dbapi):
230 self.vartree = vartree
231 self._aux_cache_keys = set(
232 ["BUILD_TIME", "CHOST", "COUNTER", "DEPEND", "DESCRIPTION",
233 - "EAPI", "HDEPEND", "HOMEPAGE", "IUSE", "KEYWORDS",
234 + "EAPI", "HDEPEND", "HOMEPAGE",
235 + "BUILD_ID", "IUSE", "KEYWORDS",
236 "LICENSE", "PDEPEND", "PROPERTIES", "PROVIDE", "RDEPEND",
237 "repository", "RESTRICT" , "SLOT", "USE", "DEFINED_PHASES",
238 "PROVIDES", "REQUIRES"
239 @@ -425,7 +426,10 @@ class vardbapi(dbapi):
240 continue
241 if len(mysplit) > 1:
242 if ps[0] == mysplit[1]:
243 - returnme.append(_pkg_str(mysplit[0]+"/"+x))
244 + cpv = "%s/%s" % (mysplit[0], x)
245 + metadata = dict(zip(self._aux_cache_keys,
246 + self.aux_get(cpv, self._aux_cache_keys)))
247 + returnme.append(_pkg_str(cpv, metadata=metadata))
248 self._cpv_sort_ascending(returnme)
249 if use_cache:
250 self.cpcache[mycp] = [mystat, returnme[:]]
251 diff --git a/pym/portage/versions.py b/pym/portage/versions.py
252 index 2c9fe5b..1ca9a36 100644
253 --- a/pym/portage/versions.py
254 +++ b/pym/portage/versions.py
255 @@ -18,6 +18,7 @@ if sys.hexversion < 0x3000000:
256 _unicode = unicode
257 else:
258 _unicode = str
259 + long = int
260
261 import portage
262 portage.proxy.lazyimport.lazyimport(globals(),
263 @@ -361,11 +362,13 @@ class _pkg_str(_unicode):
264 """
265
266 def __new__(cls, cpv, metadata=None, settings=None, eapi=None,
267 - repo=None, slot=None):
268 + repo=None, slot=None, build_time=None, build_id=None,
269 + file_size=None, mtime=None):
270 return _unicode.__new__(cls, cpv)
271
272 def __init__(self, cpv, metadata=None, settings=None, eapi=None,
273 - repo=None, slot=None):
274 + repo=None, slot=None, build_time=None, build_id=None,
275 + file_size=None, mtime=None):
276 if not isinstance(cpv, _unicode):
277 # Avoid TypeError from _unicode.__init__ with PyPy.
278 cpv = _unicode_decode(cpv)
279 @@ -375,10 +378,19 @@ class _pkg_str(_unicode):
280 slot = metadata.get('SLOT', slot)
281 repo = metadata.get('repository', repo)
282 eapi = metadata.get('EAPI', eapi)
283 + build_time = metadata.get('BUILD_TIME', build_time)
284 + file_size = metadata.get('SIZE', file_size)
285 + build_id = metadata.get('BUILD_ID', build_id)
286 + mtime = metadata.get('_mtime_', mtime)
287 if settings is not None:
288 self.__dict__['_settings'] = settings
289 if eapi is not None:
290 self.__dict__['eapi'] = eapi
291 +
292 + self.__dict__['build_time'] = self._long(build_time, 0)
293 + self.__dict__['file_size'] = self._long(file_size, None)
294 + self.__dict__['build_id'] = self._long(build_id, None)
295 + self.__dict__['mtime'] = self._long(mtime, None)
296 self.__dict__['cpv_split'] = catpkgsplit(cpv, eapi=eapi)
297 if self.cpv_split is None:
298 raise InvalidData(cpv)
299 @@ -419,6 +431,18 @@ class _pkg_str(_unicode):
300 raise AttributeError("_pkg_str instances are immutable",
301 self.__class__, name, value)
302
303 + @staticmethod
304 + def _long(var, default):
305 + if var is not None:
306 + try:
307 + var = long(var)
308 + except ValueError:
309 + if var:
310 + var = -1
311 + else:
312 + var = default
313 + return var
314 +
315 @property
316 def stable(self):
317 try:
318 --
319 2.0.5