Gentoo Archives: gentoo-commits

From: Sam James <sam@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage:master commit in: lib/portage/, lib/portage/dbapi/, lib/_emerge/
Date: Wed, 02 Nov 2022 22:58:28
Message-Id: 1667429895.445f10f4214c673f8fe0a9cc518c12767be4f159.sam@gentoo
1 commit: 445f10f4214c673f8fe0a9cc518c12767be4f159
2 Author: Sheng Yu <syu.os <AT> protonmail <DOT> com>
3 AuthorDate: Wed Nov 2 18:46:03 2022 +0000
4 Commit: Sam James <sam <AT> gentoo <DOT> org>
5 CommitDate: Wed Nov 2 22:58:15 2022 +0000
6 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=445f10f4
7
8 Use binpkg extensions and header to get format
9
10 This deprecates the BINPKG_FORMAT in the metadata and Package index.
11
12 Also fixed a bug that obsolete packages that have been moved may be
13 attempted to be read during package searching.
14
15 Closes: https://bugs.gentoo.org/877357
16 Closes: https://bugs.gentoo.org/877419
17 Signed-off-by: Sheng Yu <syu.os <AT> protonmail.com>
18 Closes: https://github.com/gentoo/portage/pull/928
19 Signed-off-by: Sam James <sam <AT> gentoo.org>
20
21 lib/_emerge/BinpkgExtractorAsync.py | 4 +-
22 lib/_emerge/BinpkgFetcher.py | 32 ++------
23 lib/_emerge/Package.py | 1 -
24 lib/_emerge/actions.py | 15 +++-
25 lib/_emerge/depgraph.py | 15 +++-
26 lib/_emerge/search.py | 6 +-
27 lib/portage/binpkg.py | 23 ++++--
28 lib/portage/dbapi/bintree.py | 142 +++++++++++++++---------------------
29 lib/portage/gpkg.py | 4 +
30 lib/portage/versions.py | 16 ----
31 lib/portage/xpak.py | 18 +++++
32 11 files changed, 141 insertions(+), 135 deletions(-)
33
34 diff --git a/lib/_emerge/BinpkgExtractorAsync.py b/lib/_emerge/BinpkgExtractorAsync.py
35 index 65b383998..ca7ccf73a 100644
36 --- a/lib/_emerge/BinpkgExtractorAsync.py
37 +++ b/lib/_emerge/BinpkgExtractorAsync.py
38 @@ -34,7 +34,9 @@ class BinpkgExtractorAsync(SpawnProcess):
39 if binpkg_format == "xpak":
40 self._xpak_start()
41 else:
42 - raise InvalidBinaryPackageFormat(self.pkg_path)
43 + raise InvalidBinaryPackageFormat(
44 + f"{self.pkg_path} is not a valid xpak binary package"
45 + )
46
47 def _xpak_start(self):
48 tar_options = ""
49
50 diff --git a/lib/_emerge/BinpkgFetcher.py b/lib/_emerge/BinpkgFetcher.py
51 index b7021e276..9018d0ee2 100644
52 --- a/lib/_emerge/BinpkgFetcher.py
53 +++ b/lib/_emerge/BinpkgFetcher.py
54 @@ -11,9 +11,8 @@ import stat
55 import sys
56 import portage
57 from portage import os
58 -from portage.const import SUPPORTED_GENTOO_BINPKG_FORMATS
59 -from portage.const import SUPPORTED_XPAK_EXTENSIONS, SUPPORTED_GPKG_EXTENSIONS
60 -from portage.exception import FileNotFound, InvalidBinaryPackageFormat
61 +from portage.binpkg import get_binpkg_format
62 +from portage.exception import FileNotFound
63 from portage.util._async.AsyncTaskFuture import AsyncTaskFuture
64 from portage.util._pty import _create_pty_or_pipe
65
66 @@ -28,18 +27,9 @@ class BinpkgFetcher(CompositeTask):
67 pkg = self.pkg
68 bintree = pkg.root_config.trees["bintree"]
69 instance_key = bintree.dbapi._instance_key(pkg.cpv)
70 - binpkg_format = bintree._remotepkgs[instance_key].get("BINPKG_FORMAT", None)
71 -
72 - if binpkg_format is None:
73 - binpkg_path = bintree._remotepkgs[instance_key].get("PATH")
74 - if binpkg_path.endswith(SUPPORTED_XPAK_EXTENSIONS):
75 - binpkg_format = "xpak"
76 - elif binpkg_path.endswith(SUPPORTED_GPKG_EXTENSIONS):
77 - binpkg_format = "gpkg"
78 - else:
79 - raise InvalidBinaryPackageFormat(
80 - f"Unsupported binary package format from '{binpkg_path}'"
81 - )
82 +
83 + binpkg_path = bintree._remotepkgs[instance_key].get("PATH")
84 + binpkg_format = get_binpkg_format(binpkg_path)
85
86 self.pkg_allocated_path = pkg.root_config.trees["bintree"].getname(
87 pkg.cpv, allocate_new=True, remote_binpkg_format=binpkg_format
88 @@ -128,17 +118,11 @@ class _BinpkgFetcherProcess(SpawnProcess):
89 resumecommand = None
90 if bintree._remote_has_index:
91 remote_metadata = bintree._remotepkgs[bintree.dbapi._instance_key(pkg.cpv)]
92 - binpkg_format = remote_metadata.get(
93 - "BINPKG_FORMAT", SUPPORTED_GENTOO_BINPKG_FORMATS[0]
94 - )
95 - if binpkg_format not in SUPPORTED_GENTOO_BINPKG_FORMATS:
96 - raise InvalidBinaryPackageFormat(binpkg_format)
97 rel_uri = remote_metadata.get("PATH")
98 if not rel_uri:
99 - if binpkg_format == "xpak":
100 - rel_uri = pkg.cpv + ".tbz2"
101 - elif binpkg_format == "gpkg":
102 - rel_uri = pkg.cpv + ".gpkg.tar"
103 + # Assume that the remote index is out of date. No path should
104 + # never happen in new portage versions.
105 + rel_uri = pkg.cpv + ".tbz2"
106 remote_base_uri = remote_metadata["BASE_URI"]
107 uri = remote_base_uri.rstrip("/") + "/" + rel_uri.lstrip("/")
108 fetchcommand = remote_metadata.get("FETCHCOMMAND")
109
110 diff --git a/lib/_emerge/Package.py b/lib/_emerge/Package.py
111 index a19904113..c50349e27 100644
112 --- a/lib/_emerge/Package.py
113 +++ b/lib/_emerge/Package.py
114 @@ -63,7 +63,6 @@ class Package(Task):
115
116 metadata_keys = [
117 "BDEPEND",
118 - "BINPKG_FORMAT",
119 "BUILD_ID",
120 "BUILD_TIME",
121 "CHOST",
122
123 diff --git a/lib/_emerge/actions.py b/lib/_emerge/actions.py
124 index b45a6361a..073e3ae7e 100644
125 --- a/lib/_emerge/actions.py
126 +++ b/lib/_emerge/actions.py
127 @@ -41,7 +41,13 @@ from portage.dbapi._expand_new_virt import expand_new_virt
128 from portage.dbapi.IndexedPortdb import IndexedPortdb
129 from portage.dbapi.IndexedVardb import IndexedVardb
130 from portage.dep import Atom, _repo_separator, _slot_separator
131 -from portage.exception import InvalidAtom, InvalidData, ParseError, GPGException
132 +from portage.exception import (
133 + InvalidAtom,
134 + InvalidData,
135 + ParseError,
136 + GPGException,
137 + InvalidBinaryPackageFormat,
138 +)
139 from portage.output import (
140 colorize,
141 create_color_func,
142 @@ -2320,9 +2326,12 @@ def action_info(settings, trees, myopts, myfiles):
143 elif pkg_type == "binary":
144 binpkg_file = bindb.bintree.getname(pkg.cpv)
145 ebuild_file_name = pkg.cpv.split("/")[1] + ".ebuild"
146 - binpkg_format = pkg.cpv._metadata.get("BINPKG_FORMAT", None)
147 - if not binpkg_format:
148 + try:
149 binpkg_format = get_binpkg_format(binpkg_file)
150 + except InvalidBinaryPackageFormat as e:
151 + out.ewarn(e)
152 + continue
153 +
154 if binpkg_format == "xpak":
155 ebuild_file_contents = portage.xpak.tbz2(binpkg_file).getfile(
156 ebuild_file_name
157
158 diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py
159 index 79fa1f3df..c976f8205 100644
160 --- a/lib/_emerge/depgraph.py
161 +++ b/lib/_emerge/depgraph.py
162 @@ -39,6 +39,7 @@ from portage.dep._slot_operator import ignore_built_slot_operator_deps, strip_sl
163 from portage.eapi import eapi_has_strong_blocks, eapi_has_required_use, _get_eapi_attrs
164 from portage.exception import (
165 InvalidAtom,
166 + InvalidBinaryPackageFormat,
167 InvalidData,
168 InvalidDependString,
169 PackageNotFound,
170 @@ -4580,7 +4581,19 @@ class depgraph:
171 noiselevel=-1,
172 )
173 return 0, myfavorites
174 - binpkg_format = get_binpkg_format(x)
175 +
176 + try:
177 + binpkg_format = get_binpkg_format(x)
178 + except InvalidBinaryPackageFormat as e:
179 + writemsg(
180 + colorize(
181 + "BAD",
182 + "\n{e}\n" % x,
183 + ),
184 + noiselevel=-1,
185 + )
186 + continue
187 +
188 if binpkg_format == "xpak":
189 mytbz2 = portage.xpak.tbz2(x)
190 mykey = None
191
192 diff --git a/lib/_emerge/search.py b/lib/_emerge/search.py
193 index 8550b0487..4989ed787 100644
194 --- a/lib/_emerge/search.py
195 +++ b/lib/_emerge/search.py
196 @@ -8,6 +8,7 @@ from portage import os
197 from portage.dbapi.porttree import _parse_uri_map
198 from portage.dbapi.IndexedPortdb import IndexedPortdb
199 from portage.dbapi.IndexedVardb import IndexedVardb
200 +from portage.exception import InvalidBinaryPackageFormat
201 from portage.localization import localized_size
202 from portage.output import bold, darkgreen, green, red
203 from portage.util import writemsg_stdout
204 @@ -490,7 +491,10 @@ class search:
205 if db is not vardb and db.cpv_exists(mycpv):
206 available = True
207 if not myebuild and hasattr(db, "bintree"):
208 - myebuild = db.bintree.getname(mycpv)
209 + try:
210 + myebuild = db.bintree.getname(mycpv)
211 + except InvalidBinaryPackageFormat:
212 + break
213 try:
214 mysum[0] = os.stat(myebuild).st_size
215 except OSError:
216
217 diff --git a/lib/portage/binpkg.py b/lib/portage/binpkg.py
218 index f3f149b14..001a2e277 100644
219 --- a/lib/portage/binpkg.py
220 +++ b/lib/portage/binpkg.py
221 @@ -2,12 +2,14 @@
222 # Distributed under the terms of the GNU General Public License v2
223
224 import tarfile
225 +from portage import os
226 from portage.const import SUPPORTED_XPAK_EXTENSIONS, SUPPORTED_GPKG_EXTENSIONS
227 +from portage.exception import InvalidBinaryPackageFormat
228 from portage.output import colorize
229 from portage.util import writemsg
230
231
232 -def get_binpkg_format(binpkg_path):
233 +def get_binpkg_format(binpkg_path, check_file=False, remote=False):
234 if binpkg_path.endswith(SUPPORTED_XPAK_EXTENSIONS):
235 file_ext_format = "xpak"
236 elif binpkg_path.endswith(SUPPORTED_GPKG_EXTENSIONS):
237 @@ -15,6 +17,17 @@ def get_binpkg_format(binpkg_path):
238 else:
239 file_ext_format = None
240
241 + if remote:
242 + if file_ext_format is not None:
243 + return file_ext_format
244 + else:
245 + raise InvalidBinaryPackageFormat(
246 + f"Unsupported binary package format from '{binpkg_path}'"
247 + )
248 +
249 + if file_ext_format is not None and not check_file:
250 + return file_ext_format
251 +
252 try:
253 with open(binpkg_path, "rb") as binpkg_file:
254 header = binpkg_file.read(100)
255 @@ -32,9 +45,7 @@ def get_binpkg_format(binpkg_path):
256 if file_format is None:
257 try:
258 with tarfile.open(binpkg_path) as gpkg_tar:
259 - if "gpkg-1" in [
260 - f.split("/", maxsplit=1)[-1] for f in gpkg_tar.getnames()
261 - ]:
262 + if "gpkg-1" in (os.path.basename(f) for f in gpkg_tar.getnames()):
263 file_format = "gpkg"
264 except tarfile.TarError:
265 pass
266 @@ -43,7 +54,9 @@ def get_binpkg_format(binpkg_path):
267 file_format = None
268
269 if file_format is None:
270 - return None
271 + raise InvalidBinaryPackageFormat(
272 + f"Unsupported binary package format from '{binpkg_path}'"
273 + )
274
275 if (file_ext_format is not None) and (file_ext_format != file_format):
276 writemsg(
277
278 diff --git a/lib/portage/dbapi/bintree.py b/lib/portage/dbapi/bintree.py
279 index c8bb2c88e..771abedd5 100644
280 --- a/lib/portage/dbapi/bintree.py
281 +++ b/lib/portage/dbapi/bintree.py
282 @@ -85,7 +85,6 @@ class bindbapi(fakedbapi):
283 list(fakedbapi._known_keys) + ["CHOST", "repository", "USE"]
284 )
285 _pkg_str_aux_keys = fakedbapi._pkg_str_aux_keys + (
286 - "BINPKG_FORMAT",
287 "BUILD_ID",
288 "BUILD_TIME",
289 "_mtime_",
290 @@ -108,7 +107,6 @@ class bindbapi(fakedbapi):
291 self._aux_cache_keys = set(
292 [
293 "BDEPEND",
294 - "BINPKG_FORMAT",
295 "BUILD_ID",
296 "BUILD_TIME",
297 "CHOST",
298 @@ -193,7 +191,8 @@ class bindbapi(fakedbapi):
299 st = os.lstat(binpkg_path)
300 except OSError:
301 raise KeyError(mycpv)
302 - binpkg_format = self.cpvdict[instance_key]["BINPKG_FORMAT"]
303 +
304 + binpkg_format = get_binpkg_format(binpkg_path)
305 if binpkg_format == "xpak":
306 metadata_bytes = portage.xpak.tbz2(binpkg_path).get_data()
307 decode_metadata_name = False
308 @@ -202,10 +201,6 @@ class bindbapi(fakedbapi):
309 self.settings, mycpv, binpkg_path
310 ).get_metadata()
311 decode_metadata_name = True
312 - else:
313 - raise InvalidBinaryPackageFormat(
314 - "Unknown binary package format %s" % binpkg_path
315 - )
316
317 def getitem(k):
318 if k == "_mtime_":
319 @@ -266,7 +261,7 @@ class bindbapi(fakedbapi):
320 if not os.path.exists(binpkg_path):
321 raise KeyError(cpv)
322
323 - binpkg_format = cpv.binpkg_format
324 + binpkg_format = get_binpkg_format(binpkg_path)
325 if binpkg_format == "xpak":
326 mytbz2 = portage.xpak.tbz2(binpkg_path)
327 mydata = mytbz2.get_data()
328 @@ -325,7 +320,7 @@ class bindbapi(fakedbapi):
329 await add_pkg._db.unpack_metadata(pkg, dest_dir, loop=loop)
330 else:
331 binpkg_file = self.bintree.getname(cpv)
332 - binpkg_format = cpv.binpkg_format
333 + binpkg_format = get_binpkg_format(binpkg_file)
334 if binpkg_format == "xpak":
335 await loop.run_in_executor(
336 ForkExecutor(loop=loop),
337 @@ -362,7 +357,7 @@ class bindbapi(fakedbapi):
338
339 pkg_path = self.bintree.getname(cpv)
340 if pkg_path is not None:
341 - binpkg_format = cpv.binpkg_format
342 + binpkg_format = get_binpkg_format(pkg_path)
343 if binpkg_format == "xpak":
344 extractor = BinpkgExtractorAsync(
345 background=settings.get("PORTAGE_BACKGROUND") == "1",
346 @@ -502,7 +497,6 @@ class binarytree:
347 self._pkgindex_aux_keys = [
348 "BASE_URI",
349 "BDEPEND",
350 - "BINPKG_FORMAT",
351 "BUILD_ID",
352 "BUILD_TIME",
353 "CHOST",
354 @@ -546,7 +540,6 @@ class binarytree:
355 "ACCEPT_LICENSE",
356 "ACCEPT_PROPERTIES",
357 "ACCEPT_RESTRICT",
358 - "BINPKG_FORMAT",
359 "CBUILD",
360 "CONFIG_PROTECT",
361 "CONFIG_PROTECT_MASK",
362 @@ -582,13 +575,10 @@ class binarytree:
363 "SLOT": "0",
364 "USE": "",
365 }
366 - self._pkgindex_inherited_keys = ["BINPKG_FORMAT", "CHOST", "repository"]
367 + self._pkgindex_inherited_keys = ["CHOST", "repository"]
368
369 # Populate the header with appropriate defaults.
370 self._pkgindex_default_header_data = {
371 - "BINPKG_FORMAT": self.settings.get(
372 - "BINPKG_FORMAT", SUPPORTED_GENTOO_BINPKG_FORMATS[0]
373 - ),
374 "CHOST": self.settings.get("CHOST", ""),
375 "repository": "",
376 }
377 @@ -679,7 +669,7 @@ class binarytree:
378 continue
379
380 moves += 1
381 - binpkg_format = mycpv.binpkg_format
382 + binpkg_format = get_binpkg_format(binpkg_path)
383 if binpkg_format == "xpak":
384 mytbz2 = portage.xpak.tbz2(binpkg_path)
385 mydata = mytbz2.get_data()
386 @@ -924,24 +914,19 @@ class binarytree:
387 metadata[_instance_key(cpv)] = d
388 path = d.get("PATH")
389 if not path:
390 - binpkg_format = d["BINPKG_FORMAT"]
391 - if binpkg_format == "xpak":
392 - if gpkg_only:
393 - if not gpkg_only_warned:
394 - writemsg(
395 - colorize(
396 - "WARN",
397 - "Local XPAK packages are ignored due to 'binpkg-request-signature'.\n",
398 - ),
399 - noiselevel=-1,
400 - )
401 - gpkg_only_warned = True
402 - continue
403 - path = cpv + ".tbz2"
404 - elif binpkg_format == "gpkg":
405 - path = cpv + ".gpkg.tar"
406 - else:
407 + if gpkg_only:
408 + if not gpkg_only_warned:
409 + writemsg(
410 + colorize(
411 + "WARN",
412 + "Local XPAK packages are ignored due to 'binpkg-request-signature'.\n",
413 + ),
414 + noiselevel=-1,
415 + )
416 + gpkg_only_warned = True
417 continue
418 + else:
419 + path = cpv + ".tbz2"
420
421 if reindex:
422 basename = os.path.basename(path)
423 @@ -1040,15 +1025,11 @@ class binarytree:
424 self.invalids.append(myfile[:-5])
425 continue
426
427 - binpkg_format = None
428 - if match:
429 - binpkg_format = match.get("BINPKG_FORMAT", None)
430 -
431 - if not binpkg_format:
432 - if myfile.endswith(SUPPORTED_XPAK_EXTENSIONS):
433 - binpkg_format = "xpak"
434 - elif myfile.endswith(SUPPORTED_GPKG_EXTENSIONS):
435 - binpkg_format = "gpkg"
436 + try:
437 + binpkg_format = get_binpkg_format(myfile)
438 + except InvalidBinaryPackageFormat:
439 + self.invalids.append(myfile[:-5])
440 + continue
441
442 if gpkg_only:
443 if binpkg_format != "gpkg":
444 @@ -1550,7 +1531,19 @@ class binarytree:
445 continue
446
447 if gpkg_only:
448 - binpkg_format = d.get("BINPKG_FORMAT", "xpak")
449 + try:
450 + binpkg_format = get_binpkg_format(
451 + d.get("PATH"), remote=True
452 + )
453 + except InvalidBinaryPackageFormat:
454 + writemsg(
455 + colorize(
456 + "WARN",
457 + f"{e}\n",
458 + ),
459 + noiselevel=-1,
460 + )
461 + continue
462 if binpkg_format != "gpkg":
463 if not gpkg_only_warned:
464 writemsg(
465 @@ -1637,7 +1630,15 @@ class binarytree:
466 noiselevel=-1,
467 )
468 return
469 - binpkg_format = metadata["BINPKG_FORMAT"]
470 +
471 + try:
472 + binpkg_format = get_binpkg_format(full_path)
473 + except InvalidBinaryPackageFormat as e:
474 + writemsg(
475 + f"!!! Invalid binary package: '{full_path}'\n",
476 + noiselevel=-1,
477 + )
478 + return
479
480 invalid_depend = False
481 try:
482 @@ -1765,8 +1766,6 @@ class binarytree:
483 v = _unicode_decode(v)
484 metadata[k] = " ".join(v.split())
485
486 - metadata["BINPKG_FORMAT"] = binpkg_format
487 -
488 return metadata
489
490 def _inject_file(self, pkgindex, cpv, filename):
491 @@ -1848,10 +1847,6 @@ class binarytree:
492 """
493
494 pkg_path = self.getname(cpv)
495 - try:
496 - binpkg_format = cpv.binpkg_format
497 - except AttributeError:
498 - raise KeyError("{} metadata not found!".format(cpv))
499
500 d = dict(cpv._metadata.items())
501 d.update(perform_multiple_checksums(pkg_path, hashes=self._pkgindex_hashes))
502 @@ -1860,18 +1855,10 @@ class binarytree:
503 st = os.lstat(pkg_path)
504 d["_mtime_"] = str(st[stat.ST_MTIME])
505 d["SIZE"] = str(st.st_size)
506 - d["BINPKG_FORMAT"] = binpkg_format
507
508 rel_path = pkg_path[len(self.pkgdir) + 1 :]
509 - # record location if it's non-default
510 - if binpkg_format == "xpak":
511 - if rel_path != cpv + ".tbz2":
512 - d["PATH"] = rel_path
513 - elif binpkg_format == "gpkg":
514 - if rel_path != cpv + ".gpkg.tar":
515 - d["PATH"] = rel_path
516 - else:
517 - raise InvalidBinaryPackageFormat(binpkg_format)
518 + # Always record location
519 + d["PATH"] = rel_path
520
521 return d
522
523 @@ -2079,25 +2066,14 @@ class binarytree:
524 return (None, None)
525
526 if filename is None:
527 - try:
528 - binpkg_format = cpv.binpkg_format
529 - except AttributeError:
530 - # In order to force the caller to clarify its intent, do not
531 - # use default BINPKG_FORMAT unless allocate_new is True.
532 - # The caller can set cpv.binpkg_format in advance if something
533 - # other than the default is desired here.
534 - if allocate_new:
535 - binpkg_format = self.settings.get(
536 - "BINPKG_FORMAT", SUPPORTED_GENTOO_BINPKG_FORMATS[0]
537 - )
538 - else:
539 - binpkg_format = None
540 + binpkg_format = self.settings.get(
541 + "BINPKG_FORMAT", SUPPORTED_GENTOO_BINPKG_FORMATS[0]
542 + )
543
544 if not binpkg_format:
545 - # Raise an error if the desired binpkg_format is not clear.
546 - # The caller should either set allocate_new to True or else
547 - # ensure that cpv.binpkg_format is set to a particular format.
548 - raise InvalidBinaryPackageFormat(binpkg_format)
549 + raise InvalidBinaryPackageFormat(
550 + "Unable to determine the binpkg format."
551 + )
552 elif binpkg_format == "xpak":
553 if self._multi_instance:
554 pf = catsplit(cpv)[1]
555 @@ -2117,7 +2093,7 @@ class binarytree:
556 else:
557 filename = os.path.join(self.pkgdir, cpv + ".gpkg.tar")
558 else:
559 - raise InvalidBinaryPackageFormat(binpkg_format)
560 + raise InvalidBinaryPackageFormat(f"{binpkg_format}")
561
562 return (filename, build_id)
563
564 @@ -2143,8 +2119,8 @@ class binarytree:
565 def _allocate_filename(self, cpv, remote_binpkg_format=None):
566 if remote_binpkg_format is None:
567 try:
568 - binpkg_format = cpv.binpkg_format
569 - except AttributeError:
570 + binpkg_format = get_binpkg_format(cpv._metadata["PATH"])
571 + except (AttributeError, KeyError):
572 binpkg_format = self.settings.get(
573 "BINPKG_FORMAT", SUPPORTED_GENTOO_BINPKG_FORMATS[0]
574 )
575 @@ -2173,8 +2149,8 @@ class binarytree:
576
577 if remote_binpkg_format is None:
578 try:
579 - binpkg_format = cpv.binpkg_format
580 - except AttributeError:
581 + binpkg_format = get_binpkg_format(cpv._metadata["PATH"])
582 + except (AttributeError, KeyError):
583 binpkg_format = self.settings.get(
584 "BINPKG_FORMAT", SUPPORTED_GENTOO_BINPKG_FORMATS[0]
585 )
586
587 diff --git a/lib/portage/gpkg.py b/lib/portage/gpkg.py
588 index 42e1c60fd..5a8c16186 100644
589 --- a/lib/portage/gpkg.py
590 +++ b/lib/portage/gpkg.py
591 @@ -21,6 +21,7 @@ from portage import normalize_path
592 from portage import _encodings
593 from portage import _unicode_decode
594 from portage import _unicode_encode
595 +from portage.binpkg import get_binpkg_format
596 from portage.exception import (
597 FileNotFound,
598 InvalidBinaryPackageFormat,
599 @@ -1560,6 +1561,7 @@ class gpkg:
600 with open(self.gpkg_file, "rb") as container:
601 container_tar_format = self._get_tar_format(container)
602 if container_tar_format is None:
603 + get_binpkg_format(self.gpkg_file, check_file=True)
604 raise InvalidBinaryPackageFormat(
605 f"Cannot identify tar format: {self.gpkg_file}"
606 )
607 @@ -1569,12 +1571,14 @@ class gpkg:
608 try:
609 container_files = container.getnames()
610 except tarfile.ReadError:
611 + get_binpkg_format(self.gpkg_file, check_file=True)
612 raise InvalidBinaryPackageFormat(
613 f"Cannot read tar file: {self.gpkg_file}"
614 )
615
616 # Check if gpkg version file exists in any place
617 if self.gpkg_version not in (os.path.basename(f) for f in container_files):
618 + get_binpkg_format(self.gpkg_file, check_file=True)
619 raise InvalidBinaryPackageFormat(f"Invalid gpkg file: {self.gpkg_file}")
620
621 # Check how many layers are in the container
622
623 diff --git a/lib/portage/versions.py b/lib/portage/versions.py
624 index 3d8694a0e..e1f798bdf 100644
625 --- a/lib/portage/versions.py
626 +++ b/lib/portage/versions.py
627 @@ -491,22 +491,6 @@ class _pkg_str(str):
628 self.__dict__["_stable"] = stable
629 return stable
630
631 - @property
632 - def binpkg_format(self):
633 - """
634 - Returns the BINPKG_FORMAT metadata. A return value of None means
635 - that the format is unset. If there is no metadata available or the
636 - BINPKG_FORMAT key is missing from the metadata, then raise
637 - AttributeError.
638 -
639 - @rtype: str or None
640 - @return: a non-empty BINPKG_FORMAT string, or None
641 - """
642 - try:
643 - return self._metadata["BINPKG_FORMAT"] or None
644 - except (AttributeError, KeyError):
645 - raise AttributeError("binpkg_format")
646 -
647
648 def pkgsplit(mypkg, silent=1, eapi=None):
649 """
650
651 diff --git a/lib/portage/xpak.py b/lib/portage/xpak.py
652 index b20429b6f..b586c0be8 100644
653 --- a/lib/portage/xpak.py
654 +++ b/lib/portage/xpak.py
655 @@ -43,6 +43,8 @@ from portage import normalize_path
656 from portage import _encodings
657 from portage import _unicode_decode
658 from portage import _unicode_encode
659 +from portage.binpkg import get_binpkg_format
660 +from portage.exception import InvalidBinaryPackageFormat
661 from portage.util.file_copy import copyfile
662
663
664 @@ -435,14 +437,26 @@ class tbz2:
665 self.infosize = 0
666 self.xpaksize = 0
667 if trailer[-4:] != b"STOP":
668 + try:
669 + get_binpkg_format(self.file, check_file=True)
670 + except InvalidBinaryPackageFormat:
671 + pass
672 return 0
673 if trailer[0:8] != b"XPAKSTOP":
674 + try:
675 + get_binpkg_format(self.file, check_file=True)
676 + except InvalidBinaryPackageFormat:
677 + pass
678 return 0
679 self.infosize = decodeint(trailer[8:12])
680 self.xpaksize = self.infosize + 8
681 a.seek(-(self.xpaksize), 2)
682 header = a.read(16)
683 if header[0:8] != b"XPAKPACK":
684 + try:
685 + get_binpkg_format(self.file, check_file=True)
686 + except InvalidBinaryPackageFormat:
687 + pass
688 return 0
689 self.indexsize = decodeint(header[8:12])
690 self.datasize = decodeint(header[12:16])
691 @@ -453,6 +467,10 @@ class tbz2:
692 except SystemExit:
693 raise
694 except:
695 + try:
696 + get_binpkg_format(self.file, check_file=True)
697 + except InvalidBinaryPackageFormat:
698 + pass
699 return 0
700 finally:
701 if a is not None: