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

Replies