1 |
This patch allows to set the compressor for binary packages via a |
2 |
BINPKG_COMPRESSION variable. BINPKG_COMPRESSION_ARGS allows to specify |
3 |
command-line arguments for that compressor. |
4 |
|
5 |
--- |
6 |
bin/binpkg-helper.py | 91 |
7 |
+++++++++++++++++++++++++++++++++++ |
8 |
bin/misc-functions.sh | 9 +++- |
9 |
bin/quickpkg | 67 +++++++++++++++++++------- |
10 |
man/make.conf.5 | 25 ++++++++++ |
11 |
pym/_emerge/BinpkgExtractorAsync.py | 43 +++++++++++++++-- |
12 |
pym/portage/dbapi/bintree.py | 8 +-- |
13 |
pym/portage/util/compression_probe.py | 45 ++++++++++++++--- |
14 |
7 files changed, 253 insertions(+), 35 deletions(-) |
15 |
create mode 100755 bin/binpkg-helper.py |
16 |
|
17 |
diff --git a/bin/binpkg-helper.py b/bin/binpkg-helper.py |
18 |
new file mode 100755 |
19 |
index 000000000..b603747cf |
20 |
--- /dev/null |
21 |
+++ b/bin/binpkg-helper.py |
22 |
@@ -0,0 +1,91 @@ |
23 |
+#!/usr/bin/python -b |
24 |
+# Copyright 2009-2017 Gentoo Foundation |
25 |
+# Distributed under the terms of the GNU General Public License v2 |
26 |
+ |
27 |
+import argparse |
28 |
+import sys |
29 |
+ |
30 |
+import portage |
31 |
+portage._internal_caller = True |
32 |
+from portage import os |
33 |
+from portage import cpv_getkey |
34 |
+from portage.process import find_binary |
35 |
+from portage.util import ( |
36 |
+ shlex_split, |
37 |
+ varexpand, |
38 |
+ ) |
39 |
+from portage.util.compression_probe import _compressors |
40 |
+ |
41 |
+def command_compressioncmd(args): |
42 |
+ settings = portage.settings |
43 |
+ usage = "usage: compressioncmd ${CATEGORY}/${P}\n" |
44 |
+ |
45 |
+ if len(args) != 1: |
46 |
+ sys.stderr.write(usage) |
47 |
+ sys.stderr.write("One argument is required, got %s\n" % len(args)) |
48 |
+ return 1 |
49 |
+ |
50 |
+ cpv = args[0] |
51 |
+ binpkg_compression = settings.get("BINPKG_COMPRESSION", "bzip2") |
52 |
+ try: |
53 |
+ compression = _compressors[binpkg_compression] |
54 |
+ except KeyError as e: |
55 |
+ sys.stderr.write("Invalid or unsupported compression method: %s" % |
56 |
e.args[0]) |
57 |
+ return 1 |
58 |
+ # Fallback to bzip2 for the package providing the decompressor |
59 |
+ # This solves bootstrapping a client without the decompressor |
60 |
+ |
61 |
+ if cpv_getkey(cpv) is None: |
62 |
+ sys.stderr.write("The argument must be in the ${CATEGORY}/${PN}-${PV} |
63 |
format. Provided argument was: %s\n" % cpv) |
64 |
+ return 1 |
65 |
+ |
66 |
+ if cpv_getkey(cpv) == compression["package"]: |
67 |
+ compression = _compressors["bzip2"] |
68 |
+ try: |
69 |
+ compression_binary = shlex_split(varexpand(compression["compress"], |
70 |
mydict=settings))[0] |
71 |
+ except IndexError as e: |
72 |
+ sys.stderr.write("Invalid or unsupported compression method: %s" % |
73 |
e.args[0]) |
74 |
+ return 1 |
75 |
+ if find_binary(compression_binary) is None: |
76 |
+ missing_package = compression["package"] |
77 |
+ sys.stderr.write("File compression unsupported %s. Missing package: |
78 |
%s" % (binpkg_compression, missing_package)) |
79 |
+ return 1 |
80 |
+ cmd = [varexpand(x, mydict=settings) for x in |
81 |
shlex_split(compression["compress"])] |
82 |
+ # Filter empty elements |
83 |
+ cmd = [x for x in cmd if x != ""] |
84 |
+ |
85 |
+ print(' '.join(cmd)) |
86 |
+ return os.EX_OK |
87 |
+ |
88 |
+def main(argv): |
89 |
+ |
90 |
+ if argv and isinstance(argv[0], bytes): |
91 |
+ for i, x in enumerate(argv): |
92 |
+ argv[i] = portage._unicode_decode(x, errors='strict') |
93 |
+ |
94 |
+ valid_commands = ('compressioncmd',) |
95 |
+ description = "Returns the compression command" |
96 |
+ usage = "usage: %s COMMAND [args]" % \ |
97 |
+ os.path.basename(argv[0]) |
98 |
+ |
99 |
+ parser = argparse.ArgumentParser(description=description, usage=usage) |
100 |
+ options, args = parser.parse_known_args(argv[1:]) |
101 |
+ |
102 |
+ if not args: |
103 |
+ parser.error("missing command argument") |
104 |
+ |
105 |
+ command = args[0] |
106 |
+ |
107 |
+ if command not in valid_commands: |
108 |
+ parser.error("invalid command: '%s'" % command) |
109 |
+ |
110 |
+ if command == 'compressioncmd': |
111 |
+ rval = command_compressioncmd(args[1:]) |
112 |
+ else: |
113 |
+ raise AssertionError("invalid command: '%s'" % command) |
114 |
+ |
115 |
+ return rval |
116 |
+ |
117 |
+if __name__ == "__main__": |
118 |
+ rval = main(sys.argv[:]) |
119 |
+ sys.exit(rval) |
120 |
diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh |
121 |
index 58755a1e1..0ba0db226 100755 |
122 |
--- a/bin/misc-functions.sh |
123 |
+++ b/bin/misc-functions.sh |
124 |
@@ -453,7 +453,7 @@ __dyn_package() { |
125 |
# Make sure $PWD is not ${D} so that we don't leave gmon.out files |
126 |
# in there in case any tools were built with -pg in CFLAGS. |
127 |
|
128 |
- cd "${T}" |
129 |
+ cd "${T}" || die |
130 |
|
131 |
if [[ -n ${PKG_INSTALL_MASK} ]] ; then |
132 |
PROOT=${T}/packaging/ |
133 |
@@ -478,8 +478,13 @@ __dyn_package() { |
134 |
[ -z "${PORTAGE_BINPKG_TMPFILE}" ] && \ |
135 |
die "PORTAGE_BINPKG_TMPFILE is unset" |
136 |
mkdir -p "${PORTAGE_BINPKG_TMPFILE%/*}" || die "mkdir failed" |
137 |
+ |
138 |
COMPRESSION_COMMAND=$(PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} |
139 |
\ |
140 |
+ "${PORTAGE_PYTHON:-/usr/bin/python}" |
141 |
"$PORTAGE_BIN_PATH"/binpkg-helper.py \ |
142 |
+ compressioncmd ${CATEGORY}/${P}) |
143 |
+ [ -z "${COMPRESSION_COMMAND}" ] && \ |
144 |
+ die "Failed to get COMPRESSION_COMMAND" |
145 |
tar $tar_options -cf - $PORTAGE_BINPKG_TAR_OPTS -C "${PROOT}" . | \ |
146 |
- $PORTAGE_BZIP2_COMMAND -c > "$PORTAGE_BINPKG_TMPFILE" |
147 |
+ $COMPRESSION_COMMAND -c > "$PORTAGE_BINPKG_TMPFILE" |
148 |
assert "failed to pack binary package: '$PORTAGE_BINPKG_TMPFILE'" |
149 |
PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \ |
150 |
"${PORTAGE_PYTHON:-/usr/bin/python}" |
151 |
"$PORTAGE_BIN_PATH"/xpak-helper.py recompose \ |
152 |
diff --git a/bin/quickpkg b/bin/quickpkg |
153 |
index 4f26ee912..a7f7ec74f 100755 |
154 |
--- a/bin/quickpkg |
155 |
+++ b/bin/quickpkg |
156 |
@@ -8,6 +8,7 @@ import argparse |
157 |
import errno |
158 |
import math |
159 |
import signal |
160 |
+import subprocess |
161 |
import sys |
162 |
import tarfile |
163 |
|
164 |
@@ -16,17 +17,20 @@ if |
165 |
osp.isfile(osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), |
166 |
".porta |
167 |
sys.path.insert(0, |
168 |
osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")) |
169 |
import portage |
170 |
portage._internal_caller = True |
171 |
+from portage import cpv_getkey |
172 |
from portage import os |
173 |
from portage import xpak |
174 |
from portage.dbapi.dep_expand import dep_expand |
175 |
from portage.dep import Atom, use_reduce |
176 |
from portage.exception import (AmbiguousPackageName, InvalidAtom, |
177 |
InvalidData, |
178 |
InvalidDependString, PackageSetNotFound, PermissionDenied) |
179 |
-from portage.util import ConfigProtect, ensure_dirs, shlex_split, _xattr |
180 |
+from portage.util import ConfigProtect, ensure_dirs, shlex_split, |
181 |
varexpand, _xattr |
182 |
xattr = _xattr.xattr |
183 |
from portage.dbapi.vartree import dblink, tar_contents |
184 |
from portage.checksum import perform_md5 |
185 |
from portage._sets import load_default_config, SETPREFIX |
186 |
+from portage.process import find_binary |
187 |
+from portage.util.compression_probe import _compressors |
188 |
|
189 |
def quickpkg_atom(options, infos, arg, eout): |
190 |
settings = portage.settings |
191 |
@@ -50,16 +54,16 @@ def quickpkg_atom(options, infos, arg, eout): |
192 |
" ".join(e.args[0])) |
193 |
del e |
194 |
infos["missing"].append(arg) |
195 |
- return |
196 |
+ return 1 |
197 |
except (InvalidAtom, InvalidData): |
198 |
eout.eerror("Invalid atom: %s" % (arg,)) |
199 |
infos["missing"].append(arg) |
200 |
- return |
201 |
+ return 1 |
202 |
if atom[:1] == '=' and arg[:1] != '=': |
203 |
# dep_expand() allows missing '=' but it's really invalid |
204 |
eout.eerror("Invalid atom: %s" % (arg,)) |
205 |
infos["missing"].append(arg) |
206 |
- return |
207 |
+ return 1 |
208 |
|
209 |
matches = vardb.match(atom) |
210 |
pkgs_for_arg = 0 |
211 |
@@ -108,16 +112,16 @@ def quickpkg_atom(options, infos, arg, eout): |
212 |
in settings.features)) |
213 |
def protect(filename): |
214 |
if not confprot.isprotected(filename): |
215 |
- return False |
216 |
+ return 1 |
217 |
if include_unmodified_config: |
218 |
file_data = contents[filename] |
219 |
if file_data[0] == "obj": |
220 |
orig_md5 = file_data[2].lower() |
221 |
cur_md5 = perform_md5(filename, calc_prelink=1) |
222 |
if orig_md5 == cur_md5: |
223 |
- return False |
224 |
+ return 1 |
225 |
excluded_config_files.append(filename) |
226 |
- return True |
227 |
+ return os.EX_OK |
228 |
existing_metadata = dict(zip(fix_metadata_keys, |
229 |
vardb.aux_get(cpv, fix_metadata_keys))) |
230 |
category, pf = portage.catsplit(cpv) |
231 |
@@ -134,12 +138,36 @@ def quickpkg_atom(options, infos, arg, eout): |
232 |
binpkg_tmpfile = os.path.join(bintree.pkgdir, |
233 |
cpv + ".tbz2." + str(os.getpid())) |
234 |
ensure_dirs(os.path.dirname(binpkg_tmpfile)) |
235 |
- # The tarfile module will write pax headers holding the |
236 |
- # xattrs only if PAX_FORMAT is specified here. |
237 |
- tar = tarfile.open(binpkg_tmpfile, "w:bz2", |
238 |
- format=tarfile.PAX_FORMAT if xattrs else tarfile.DEFAULT_FORMAT) |
239 |
- tar_contents(contents, root, tar, protect=protect, xattrs=xattrs) |
240 |
- tar.close() |
241 |
+ binpkg_compression = settings.get("BINPKG_COMPRESSION", "bzip2") |
242 |
+ try: |
243 |
+ compression = _compressors[binpkg_compression] |
244 |
+ except KeyError as e: |
245 |
+ eout.eerror("Invalid or unsupported compression method: %s" % |
246 |
e.args[0]) |
247 |
+ return 1 |
248 |
+ # Fallback to bzip2 for the package providing the decompressor |
249 |
+ # This solves bootstrapping a client without the decompressor |
250 |
+ if cpv_getkey(cpv) == compression["package"]: |
251 |
+ compression = _compressors["bzip2"] |
252 |
+ try: |
253 |
+ compression_binary = shlex_split(varexpand(compression["compress"], |
254 |
mydict=settings))[0] |
255 |
+ except IndexError as e: |
256 |
+ eout.eerror("Invalid or unsupported compression method: %s" % |
257 |
e.args[0]) |
258 |
+ return 1 |
259 |
+ if find_binary(compression_binary) is None: |
260 |
+ missing_package = compression["package"] |
261 |
+ eout.eerror("File compression unsupported %s. Missing package: %s" |
262 |
% (binpkg_compression, missing_package)) |
263 |
+ return 1 |
264 |
+ cmd = [varexpand(x, mydict=settings) for x in |
265 |
shlex_split(compression["compress"])] |
266 |
+ # Filter empty elements that make Popen fail |
267 |
+ cmd = [x for x in cmd if x != ""] |
268 |
+ with open(binpkg_tmpfile, "wb") as fobj: |
269 |
+ proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=fobj) |
270 |
+ # The tarfile module will write pax headers holding the |
271 |
+ # xattrs only if PAX_FORMAT is specified here. |
272 |
+ with tarfile.open(mode="w|",format=tarfile.PAX_FORMAT if xattrs |
273 |
else tarfile.DEFAULT_FORMAT, fileobj=proc.stdin) as tar: |
274 |
+ tar_contents(contents, root, tar, protect=protect, xattrs=xattrs) |
275 |
+ proc.stdin.close() |
276 |
+ proc.wait() |
277 |
xpak.tbz2(binpkg_tmpfile).recompose_mem(xpdata) |
278 |
finally: |
279 |
if have_lock: |
280 |
@@ -154,16 +182,20 @@ def quickpkg_atom(options, infos, arg, eout): |
281 |
eout.eerror(str(e)) |
282 |
del e |
283 |
eout.eerror("Failed to create package: '%s'" % binpkg_path) |
284 |
+ return 1 |
285 |
else: |
286 |
eout.eend(0) |
287 |
infos["successes"].append((cpv, s.st_size)) |
288 |
infos["config_files_excluded"] += len(excluded_config_files) |
289 |
for filename in excluded_config_files: |
290 |
eout.ewarn("Excluded config: '%s'" % filename) |
291 |
+ return os.EX_OK |
292 |
if not pkgs_for_arg: |
293 |
eout.eerror("Could not find anything " + \ |
294 |
"to match '%s'; skipping" % arg) |
295 |
infos["missing"].append(arg) |
296 |
+ return 1 |
297 |
+ return os.EX_OK |
298 |
|
299 |
def quickpkg_set(options, infos, arg, eout): |
300 |
eroot = portage.settings['EROOT'] |
301 |
@@ -179,7 +211,7 @@ def quickpkg_set(options, infos, arg, eout): |
302 |
if not set in sets: |
303 |
eout.eerror("Package set not found: '%s'; skipping" % (arg,)) |
304 |
infos["missing"].append(arg) |
305 |
- return |
306 |
+ return 1 |
307 |
|
308 |
try: |
309 |
atoms = setconfig.getSetAtoms(set) |
310 |
@@ -187,10 +219,11 @@ def quickpkg_set(options, infos, arg, eout): |
311 |
eout.eerror("Failed to process package set '%s' because " % set + |
312 |
"it contains the non-existent package set '%s'; skipping" % e) |
313 |
infos["missing"].append(arg) |
314 |
- return |
315 |
- |
316 |
+ return 1 |
317 |
+ retval = os.EX_OK |
318 |
for atom in atoms: |
319 |
- quickpkg_atom(options, infos, atom, eout) |
320 |
+ retval |= quickpkg_atom(options, infos, atom, eout) |
321 |
+ return retval |
322 |
|
323 |
|
324 |
def quickpkg_extended_atom(options, infos, atom, eout): |
325 |
diff --git a/man/make.conf.5 b/man/make.conf.5 |
326 |
index aea189e4a..8e0d04967 100644 |
327 |
--- a/man/make.conf.5 |
328 |
+++ b/man/make.conf.5 |
329 |
@@ -110,6 +110,31 @@ ACCEPT_RESTRICT="*" |
330 |
ACCEPT_RESTRICT="* -bindist" |
331 |
.fi |
332 |
.TP |
333 |
+\fBBINPKG_COMPRESSION\fR = \fI"compression"\fR |
334 |
+This variable is used to determine the compression used for \fIbinary |
335 |
+packages\fR. Supported settings and compression algorithms are: bzip2, |
336 |
gzip, |
337 |
+lz4, lzip, lzop, xz, zstd. |
338 |
+.br |
339 |
+Defaults to "bzip2". |
340 |
+.br |
341 |
+.I Example: |
342 |
+.nf |
343 |
+# Set it to use lz4: |
344 |
+BINPKG_COMPRESSION="lz4" |
345 |
+.fi |
346 |
+.TP |
347 |
+\fBBINPKG_COMPRESSION_ARGS\fR = \fI"arguments for compression command"\fR |
348 |
+This variable is used to add additional arguments to the compression |
349 |
command |
350 |
+selected by \fBBINPKG_COMPRESSION\fR. |
351 |
+.br |
352 |
+Defaults to "". |
353 |
+.br |
354 |
+.I Example: |
355 |
+.nf |
356 |
+# Set it to use compression level 9: |
357 |
+BINPKG_COMPRESSION_ARGS="-9" |
358 |
+.fi |
359 |
+.TP |
360 |
.B CBUILD |
361 |
This variable is passed by the \fIebuild scripts\fR to the \fIconfigure\fR |
362 |
as \fI\-\-build=${CBUILD}\fR only if it is defined. Do not set this |
363 |
yourself |
364 |
diff --git a/pym/_emerge/BinpkgExtractorAsync.py |
365 |
b/pym/_emerge/BinpkgExtractorAsync.py |
366 |
index 0bf3c74c9..e85f4ecac 100644 |
367 |
--- a/pym/_emerge/BinpkgExtractorAsync.py |
368 |
+++ b/pym/_emerge/BinpkgExtractorAsync.py |
369 |
@@ -6,8 +6,15 @@ |
370 |
from _emerge.SpawnProcess import SpawnProcess |
371 |
import portage |
372 |
from portage.localization import _ |
373 |
-from portage.util.compression_probe import (compression_probe, |
374 |
- _decompressors) |
375 |
+from portage.util.compression_probe import ( |
376 |
+ compression_probe, |
377 |
+ _compressors, |
378 |
+) |
379 |
+from portage.process import find_binary |
380 |
+from portage.util import ( |
381 |
+ shlex_split, |
382 |
+ varexpand, |
383 |
+) |
384 |
import signal |
385 |
import subprocess |
386 |
|
387 |
@@ -28,8 +35,11 @@ def _start(self): |
388 |
tar_options.append(portage._shell_quote("--xattrs-exclude=%s" % x)) |
389 |
tar_options = " ".join(tar_options) |
390 |
|
391 |
- decomp_cmd = _decompressors.get( |
392 |
- compression_probe(self.pkg_path)) |
393 |
+ decomp = _compressors.get(compression_probe(self.pkg_path)) |
394 |
+ if decomp is not None: |
395 |
+ decomp_cmd = decomp.get("decompress") |
396 |
+ else: |
397 |
+ decomp_cmd = None |
398 |
if decomp_cmd is None: |
399 |
self.scheduler.output("!!! %s\n" % |
400 |
_("File compression header unrecognized: %s") % |
401 |
@@ -39,6 +49,31 @@ def _start(self): |
402 |
self._async_wait() |
403 |
return |
404 |
|
405 |
+ try: |
406 |
+ decompression_binary = shlex_split(varexpand(decomp_cmd, |
407 |
mydict=self.env))[0] |
408 |
+ except IndexError: |
409 |
+ decompression_binary = "" |
410 |
+ |
411 |
+ if find_binary(decompression_binary) is None: |
412 |
+ # Try alternative command if it exists |
413 |
+ if |
414 |
_compressors.get(compression_probe(self.pkg_path)).get("decompress_alt"): |
415 |
+ decomp_cmd = _compressors.get( |
416 |
+ compression_probe(self.pkg_path)).get("decompress_alt") |
417 |
+ try: |
418 |
+ decompression_binary = shlex_split(varexpand(decomp_cmd, |
419 |
mydict=self.env))[0] |
420 |
+ except IndexError: |
421 |
+ decompression_binary = "" |
422 |
+ |
423 |
+ if find_binary(decompression_binary) is None: |
424 |
+ missing_package = |
425 |
_compressors.get(compression_probe(self.pkg_path)).get("package") |
426 |
+ self.scheduler.output("!!! %s\n" % |
427 |
+ _("File compression unsupported %s.\n Command was: %s.\n Maybe |
428 |
missing package: %s") % |
429 |
+ (self.pkg_path, varexpand(decomp_cmd, mydict=self.env), |
430 |
missing_package), log_path=self.logfile, |
431 |
+ background=self.background, level=logging.ERROR) |
432 |
+ self.returncode = 1 |
433 |
+ self._async_wait() |
434 |
+ return |
435 |
+ |
436 |
# Add -q to decomp_cmd opts, in order to avoid "trailing garbage |
437 |
# after EOF ignored" warning messages due to xpak trailer. |
438 |
# SIGPIPE handling (128 + SIGPIPE) should be compatible with |
439 |
diff --git a/pym/portage/dbapi/bintree.py b/pym/portage/dbapi/bintree.py |
440 |
index ca90ba8f9..c833968c2 100644 |
441 |
--- a/pym/portage/dbapi/bintree.py |
442 |
+++ b/pym/portage/dbapi/bintree.py |
443 |
@@ -141,7 +141,6 @@ def aux_get(self, mycpv, wants, myrepo=None): |
444 |
return [aux_cache.get(x, "") for x in wants] |
445 |
mysplit = mycpv.split("/") |
446 |
mylist = [] |
447 |
- tbz2name = mysplit[1]+".tbz2" |
448 |
if not self.bintree._remotepkgs or \ |
449 |
not self.bintree.isremote(mycpv): |
450 |
try: |
451 |
@@ -1448,9 +1447,10 @@ def _allocate_filename_multi(self, cpv): |
452 |
@staticmethod |
453 |
def _parse_build_id(filename): |
454 |
build_id = -1 |
455 |
- hyphen = filename.rfind("-", 0, -6) |
456 |
+ suffixlen = len(".xpak") |
457 |
+ hyphen = filename.rfind("-", 0, -(suffixlen + 1)) |
458 |
if hyphen != -1: |
459 |
- build_id = filename[hyphen+1:-5] |
460 |
+ build_id = filename[hyphen+1:-suffixlen] |
461 |
try: |
462 |
build_id = long(build_id) |
463 |
except ValueError: |
464 |
@@ -1497,7 +1497,7 @@ def gettbz2(self, pkgname): |
465 |
if self._remote_has_index: |
466 |
rel_url = self._remotepkgs[instance_key].get("PATH") |
467 |
if not rel_url: |
468 |
- rel_url = pkgname+".tbz2" |
469 |
+ rel_url = pkgname + ".tbz2" |
470 |
remote_base_uri = self._remotepkgs[instance_key]["BASE_URI"] |
471 |
url = remote_base_uri.rstrip("/") + "/" + rel_url.lstrip("/") |
472 |
else: |
473 |
diff --git a/pym/portage/util/compression_probe.py |
474 |
b/pym/portage/util/compression_probe.py |
475 |
index 754621016..b15200044 100644 |
476 |
--- a/pym/portage/util/compression_probe.py |
477 |
+++ b/pym/portage/util/compression_probe.py |
478 |
@@ -11,14 +11,43 @@ |
479 |
from portage import _encodings, _unicode_encode |
480 |
from portage.exception import FileNotFound, PermissionDenied |
481 |
|
482 |
-_decompressors = { |
483 |
- "bzip2": "${PORTAGE_BUNZIP2_COMMAND:-${PORTAGE_BZIP2_COMMAND} -d}", |
484 |
- "gzip": "gzip -d", |
485 |
- "lz4": "lz4 -d", |
486 |
- "lzip": "lzip -d", |
487 |
- "lzop": "lzop -d", |
488 |
- "xz": "xz -d", |
489 |
- "zstd": "zstd -d", |
490 |
+_compressors = { |
491 |
+ "bzip2": { |
492 |
+ "compress": "${PORTAGE_BZIP2_COMMAND} ${BINPKG_COMPRESSION_ARGS}", |
493 |
+ "decompress": "${PORTAGE_BUNZIP2_COMMAND}", |
494 |
+ "decompress_alt": "${PORTAGE_BZIP2_COMMAND} -d", |
495 |
+ "package": "app-arch/bzip2", |
496 |
+ }, |
497 |
+ "gzip": { |
498 |
+ "compress": "gzip ${BINPKG_COMPRESSION_ARGS}", |
499 |
+ "decompress": "gzip -d", |
500 |
+ "package": "app-arch/gzip", |
501 |
+ }, |
502 |
+ "lz4": { |
503 |
+ "compress": "lz4 ${BINPKG_COMPRESSION_ARGS}", |
504 |
+ "decompress": "lz4 -d", |
505 |
+ "package": "app-arch/lz4", |
506 |
+ }, |
507 |
+ "lzip": { |
508 |
+ "compress": "lzip ${BINPKG_COMPRESSION_ARGS}", |
509 |
+ "decompress": "lzip -d", |
510 |
+ "package": "app-arch/lzip", |
511 |
+ }, |
512 |
+ "lzop": { |
513 |
+ "compress": "lzop ${BINPKG_COMPRESSION_ARGS}", |
514 |
+ "decompress": "lzop -d", |
515 |
+ "package": "app-arch/lzop", |
516 |
+ }, |
517 |
+ "xz": { |
518 |
+ "compress": "xz ${BINPKG_COMPRESSION_ARGS}", |
519 |
+ "decompress": "xz -d", |
520 |
+ "package": "app-arch/xz-utils", |
521 |
+ }, |
522 |
+ "zstd": { |
523 |
+ "compress": "zstd ${BINPKG_COMPRESSION_ARGS}", |
524 |
+ "decompress": "zstd -d", |
525 |
+ "package": "app-arch/zstd", |
526 |
+ }, |
527 |
} |
528 |
|
529 |
_compression_re = re.compile(b'^(' + |