Gentoo Archives: gentoo-commits

From: "Michał Górny" <mgorny@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/portage:master commit in: bin/ebuild-helpers/, bin/, lib/portage/tests/bin/
Date: Thu, 20 Sep 2018 18:49:33
Message-Id: 1537469309.aa0a94198794f8ee8eedad26251b02f7b01dce17.mgorny@gentoo
1 commit: aa0a94198794f8ee8eedad26251b02f7b01dce17
2 Author: Michał Górny <mgorny <AT> gentoo <DOT> org>
3 AuthorDate: Sat Mar 24 11:47:02 2018 +0000
4 Commit: Michał Górny <mgorny <AT> gentoo <DOT> org>
5 CommitDate: Thu Sep 20 18:48:29 2018 +0000
6 URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=aa0a9419
7
8 ecompress: Replace with implementation from portage[mgorny]
9
10 Replace the old ecompress/ecompressdir implementation with the one used
11 in portage[mgorny]. This is a squashed version of a long series of
12 commits that gutted off parts of old logic, introduced the new code,
13 fixed ongoing bugs and finally restored the missing features. Given
14 the scale of changes, it is easier to review it as completely new code.
15
16 The duplicate model of ecompress/ecompressdir (both not exactly par
17 on features) has been replaced by a single helper that compresses
18 everything uniformly. Instead of complex path-wise processing,
19 a mark-file logic is used -- the same as in estrip. Additionally,
20 the functions are moved out of ebuild path to clearly indicate they are
21 internal API (they were not used in any ebuilds).
22
23 The new implementation is par on features with the old one. It supports
24 exclusion suffix lists, automatic decompression of already-compressed
25 files (with eqawarn-ing about its unreliability), lower bound for
26 compressed file size, hardlink breaking and symlink fixing. In other
27 words, there should be no regression upon replacing it.
28
29 Signed-off-by: Michał Górny <mgorny <AT> gentoo.org>
30 Reviewed-by: Zac Medico <zmedico <AT> gentoo.org>
31
32 bin/ebuild-helpers/ecompress | 161 --------------------------
33 bin/ebuild-helpers/ecompressdir | 226 -------------------------------------
34 bin/ecompress | 147 ++++++++++++++++++++++++
35 bin/ecompress-file | 68 +++++++++++
36 bin/misc-functions.sh | 127 +--------------------
37 lib/portage/tests/bin/setup_env.py | 2 +-
38 6 files changed, 221 insertions(+), 510 deletions(-)
39
40 diff --git a/bin/ebuild-helpers/ecompress b/bin/ebuild-helpers/ecompress
41 deleted file mode 100755
42 index 50ee81129..000000000
43 --- a/bin/ebuild-helpers/ecompress
44 +++ /dev/null
45 @@ -1,161 +0,0 @@
46 -#!/bin/bash
47 -# Copyright 1999-2010 Gentoo Foundation
48 -# Distributed under the terms of the GNU General Public License v2
49 -
50 -source "${PORTAGE_BIN_PATH}"/isolated-functions.sh || exit 1
51 -
52 -if [[ -z $1 ]] ; then
53 - __helpers_die "${0##*/}: at least one argument needed"
54 - exit 1
55 -fi
56 -
57 -# setup compression stuff
58 -PORTAGE_COMPRESS=${PORTAGE_COMPRESS-bzip2}
59 -[[ -z ${PORTAGE_COMPRESS} ]] && exit 0
60 -
61 -if [[ ${PORTAGE_COMPRESS_FLAGS+set} != "set" ]] ; then
62 - case ${PORTAGE_COMPRESS} in
63 - bzip2|gzip) PORTAGE_COMPRESS_FLAGS="-9";;
64 - esac
65 -fi
66 -
67 -# decompress_args(suffix, binary)
68 -# - suffix: the compression suffix to work with
69 -# - binary: the program to execute that'll compress/decompress
70 -# new_args: global array used to return revised arguments
71 -decompress_args() {
72 - local suffix=$1 binary=$2
73 - shift 2
74 -
75 - # Initialize the global new_args array.
76 - new_args=()
77 - declare -a decompress_args=()
78 - local x i=0 decompress_count=0
79 - for x in "$@" ; do
80 - if [[ ${x%$suffix} = $x ]] ; then
81 - new_args[$i]=$x
82 - else
83 - new_args[$i]=${x%$suffix}
84 - decompress_args[$decompress_count]=$x
85 - ((decompress_count++))
86 - fi
87 - ((i++))
88 - done
89 -
90 - if [ $decompress_count -gt 0 ] ; then
91 - ${binary} "${decompress_args[@]}"
92 - if [ $? -ne 0 ] ; then
93 - # Apparently decompression failed for one or more files, so
94 - # drop those since we don't want to compress them twice.
95 - new_args=()
96 - local x i=0
97 - for x in "$@" ; do
98 - if [[ ${x%$suffix} = $x ]] ; then
99 - new_args[$i]=$x
100 - ((i++))
101 - elif [[ -f ${x%$suffix} ]] ; then
102 - new_args[$i]=${x%$suffix}
103 - ((i++))
104 - else
105 - # Apparently decompression failed for this one, so drop
106 - # it since we don't want to compress it twice.
107 - true
108 - fi
109 - done
110 - fi
111 - fi
112 -}
113 -
114 -case $1 in
115 - --suffix)
116 - [[ -n $2 ]] && __vecho "${0##*/}: --suffix takes no additional arguments" 1>&2
117 -
118 - if [[ ! -e ${T}/.ecompress.suffix ]] ; then
119 - set -e
120 - tmpdir="${T}"/.ecompress$$.${RANDOM}
121 - mkdir "${tmpdir}"
122 - cd "${tmpdir}"
123 - # we have to fill the file enough so that there is something
124 - # to compress as some programs will refuse to do compression
125 - # if it cannot actually compress the file
126 - echo {0..1000} > compressme
127 - ${PORTAGE_COMPRESS} ${PORTAGE_COMPRESS_FLAGS} compressme > /dev/null
128 - # If PORTAGE_COMPRESS_FLAGS contains -k then we need to avoid
129 - # having our glob match the uncompressed file here.
130 - suffix=$(echo compressme.*)
131 - [[ -z $suffix || "$suffix" == "compressme.*" ]] && \
132 - suffix=$(echo compressme*)
133 - suffix=${suffix#compressme}
134 - cd /
135 - rm -rf "${tmpdir}"
136 - echo "${suffix}" > "${T}/.ecompress.suffix"
137 - fi
138 - cat "${T}/.ecompress.suffix"
139 - ;;
140 - --bin)
141 - [[ -n $2 ]] && __vecho "${0##*/}: --bin takes no additional arguments" 1>&2
142 -
143 - echo "${PORTAGE_COMPRESS} ${PORTAGE_COMPRESS_FLAGS}"
144 - ;;
145 - --queue)
146 - shift
147 - ret=0
148 - for x in "${@/%/.ecompress.file}" ; do
149 - >> "$x"
150 - ((ret|=$?))
151 - done
152 - [[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
153 - exit $ret
154 - ;;
155 - --dequeue)
156 - [[ -n $2 ]] && __vecho "${0##*/}: --dequeue takes no additional arguments" 1>&2
157 - find "${D}" -name '*.ecompress.file' -print0 \
158 - | sed -e 's:\.ecompress\.file::g' \
159 - | ${XARGS} -0 ecompress
160 - find "${D}" -name '*.ecompress.file' -print0 | ${XARGS} -0 rm -f
161 - ;;
162 - --*)
163 - __helpers_die "${0##*/}: unknown arguments '$*'"
164 - exit 1
165 - ;;
166 - *)
167 - # Since dodoc calls ecompress on files that are already compressed,
168 - # perform decompression here (similar to ecompressdir behavior).
169 - decompress_args ".Z" "gunzip -f" "$@"
170 - set -- "${new_args[@]}"
171 - decompress_args ".gz" "gunzip -f" "$@"
172 - set -- "${new_args[@]}"
173 - decompress_args ".bz2" "bunzip2 -f" "$@"
174 - set -- "${new_args[@]}"
175 -
176 - mask_ext_re=""
177 - set -f
178 - for x in $PORTAGE_COMPRESS_EXCLUDE_SUFFIXES ; do
179 - mask_ext_re+="|$x"
180 - done
181 - set +f
182 - mask_ext_re="^(${mask_ext_re:1})\$"
183 - declare -a filtered_args=()
184 - i=0
185 - for x in "$@" ; do
186 - [[ ${x##*.} =~ $mask_ext_re ]] && continue
187 - [[ -s ${x} ]] || continue
188 - filtered_args[$i]=$x
189 - ((i++))
190 - done
191 - [ $i -eq 0 ] && exit 0
192 - set -- "${filtered_args[@]}"
193 -
194 - # If a compressed version of the file already exists, simply
195 - # delete it so that the compressor doesn't whine (bzip2 will
196 - # complain and skip, gzip will prompt for input)
197 - suffix=$(ecompress --suffix)
198 - [[ -n ${suffix} ]] && echo -n "${@/%/${suffix}$'\001'}" | \
199 - tr '\001' '\000' | ${XARGS} -0 rm -f
200 - # Finally, let's actually do some real work
201 - "${PORTAGE_COMPRESS}" ${PORTAGE_COMPRESS_FLAGS} "$@"
202 - ret=$?
203 - [[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
204 - exit $ret
205 - ;;
206 -esac
207
208 diff --git a/bin/ebuild-helpers/ecompressdir b/bin/ebuild-helpers/ecompressdir
209 deleted file mode 100755
210 index dacb857be..000000000
211 --- a/bin/ebuild-helpers/ecompressdir
212 +++ /dev/null
213 @@ -1,226 +0,0 @@
214 -#!/bin/bash
215 -# Copyright 1999-2018 Gentoo Foundation
216 -# Distributed under the terms of the GNU General Public License v2
217 -
218 -source "${PORTAGE_BIN_PATH}"/helper-functions.sh || exit 1
219 -
220 -if [[ -z $1 ]] ; then
221 - __helpers_die "${0##*/}: at least one argument needed"
222 - exit 1
223 -fi
224 -
225 -if ! ___eapi_has_prefix_variables; then
226 - ED=${D} EPREFIX=
227 -fi
228 -
229 -SIZE_LIMIT=''
230 -while [[ $# -gt 0 ]] ; do
231 - case $1 in
232 - --ignore)
233 - shift
234 - for skip in "$@" ; do
235 - [[ -d ${ED%/}/${skip#/} || -f ${ED%/}/${skip#/} ]] \
236 - && >> "${ED%/}/${skip#/}.ecompress.skip"
237 - done
238 - exit 0
239 - ;;
240 - --queue)
241 - shift
242 - set -- "${@#/}"
243 - set -- "${@/%/.ecompress.dir}"
244 - set -- "${@/#/${ED%/}/}"
245 - ret=0
246 - for x in "$@" ; do
247 - # Stash the limit in the .dir file so we can reload it later.
248 - printf "${SIZE_LIMIT}" > "${x}"
249 - ((ret|=$?))
250 - done
251 - [[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
252 - exit $ret
253 - ;;
254 - --dequeue)
255 - [[ -n $2 ]] && __vecho "${0##*/}: --dequeue takes no additional arguments" 1>&2
256 - find "${ED}" -name '*.ecompress.dir' -print0 \
257 - | sed -e 's:\.ecompress\.dir::g' -e "s:${ED%/}::g" \
258 - | ${XARGS} -0 ecompressdir
259 - find "${ED}" -name '*.ecompress.skip' -print0 | ${XARGS} -0 rm -f
260 - exit 0
261 - ;;
262 - --limit)
263 - SIZE_LIMIT=$2
264 - shift
265 - ;;
266 - --*)
267 - __helpers_die "${0##*/}: unknown arguments '$*'"
268 - exit 1
269 - ;;
270 - *)
271 - break
272 - ;;
273 - esac
274 - shift
275 -done
276 -
277 -# figure out the new suffix
278 -suffix=$(ecompress --suffix)
279 -
280 -# funk_up_dir(action, suffix, binary, [size_limit])
281 -# - action: compress or decompress
282 -# - suffix: the compression suffix to work with
283 -# - binary: the program to execute that'll compress/decompress
284 -# - size_limit: if compressing, skip files smaller than this
285 -# The directory we act on is implied in the ${dir} variable
286 -funk_up_dir() {
287 - local act=$1 suffix=$2 binary=$3 size_limit=$4
288 -
289 - local negate=""
290 - [[ ${act} == "compress" ]] && negate="!"
291 -
292 - local ret=0
293 - # first we act on all the files
294 - local args=(
295 - -type f
296 - ${negate} -iname "*${suffix}"
297 - )
298 - [[ -n ${size_limit} ]] && args+=( -size "+${size_limit}c" )
299 - find "${dir}" "${args[@]}" -print0 | ${XARGS} -0 ${binary}
300 - ((ret|=$?))
301 -
302 - # Repeat until nothing changes, in order to handle multiple
303 - # levels of indirection (see bug #470916).
304 - local -i indirection=0
305 - while true ; do
306 - local something_changed=
307 - while read -r -d $'\0' brokenlink ; do
308 - [[ -e ${brokenlink} ]] && continue
309 - olddest=$(readlink "${brokenlink}")
310 - # Ignore temporarily broken symlinks due to
311 - # _relocate_skip_dirs (bug #399595), and handle
312 - # absolute symlinks to files that aren't merged
313 - # yet (bug #405327).
314 - if [[ ${olddest} == /* ]] ; then
315 - [ -e "${D%/}${olddest}" ] && continue
316 - skip_dir_dest=${T}/ecompress-skip/${olddest#${EPREFIX}}
317 - else
318 - skip_dir_dest=${T}/ecompress-skip/${actual_dir#${ED%/}}/${brokenlink%/*}/${olddest}
319 - fi
320 - [[ -e ${skip_dir_dest} ]] && continue
321 - if [[ ${act} == "compress" ]] ; then
322 - newdest=${olddest}${suffix}
323 - else
324 - [[ ${olddest} == *${suffix} ]] || continue
325 - newdest=${olddest%${suffix}}
326 - fi
327 - if [[ "${newdest}" == /* ]] ; then
328 - [[ -f "${D%/}${newdest}" ]] || continue
329 - else
330 - [[ -f "${dir}/${brokenlink%/*}/${newdest}" ]] || continue
331 - fi
332 - something_changed=${brokenlink}
333 - rm -f "${brokenlink}"
334 - [[ ${act} == "compress" ]] \
335 - && ln -snf "${newdest}" "${brokenlink}${suffix}" \
336 - || ln -snf "${newdest}" "${brokenlink%${suffix}}"
337 - ((ret|=$?))
338 - done < <(find "${dir}" -type l -print0)
339 - [[ -n ${something_changed} ]] || break
340 - (( indirection++ ))
341 - if (( indirection >= 100 )) ; then
342 - # Protect against possibility of a bug triggering an endless loop.
343 - eerror "ecompressdir: too many levels of indirection for" \
344 - "'${actual_dir#${ED%/}}/${something_changed#./}'"
345 - break
346 - fi
347 - done
348 - return ${ret}
349 -}
350 -
351 -# _relocate_skip_dirs(srctree, dsttree)
352 -# Move all files and directories we want to skip running compression
353 -# on from srctree to dsttree.
354 -_relocate_skip_dirs() {
355 - local srctree="${1%/}" dsttree="${2%/}"
356 -
357 - [[ -d ${srctree} ]] || return 0
358 -
359 - find "${srctree}" -name '*.ecompress.skip' -print0 | \
360 - while read -r -d $'\0' src ; do
361 - src=${src%.ecompress.skip}
362 - dst="${dsttree}${src#${srctree}}"
363 - parent=${dst%/*}
364 - mkdir -p "${parent}"
365 - mv "${src}" "${dst}"
366 - mv "${src}.ecompress.skip" "${dst}.ecompress.skip"
367 - done
368 -}
369 -hide_skip_dirs() { _relocate_skip_dirs "${ED}" "${T}"/ecompress-skip/ ; }
370 -restore_skip_dirs() { _relocate_skip_dirs "${T}"/ecompress-skip/ "${ED}" ; }
371 -
372 -ret=0
373 -
374 -rm -rf "${T}"/ecompress-skip
375 -
376 -decompressors=(
377 - ".Z" "gunzip -f"
378 - ".gz" "gunzip -f"
379 - ".bz2" "bunzip2 -f"
380 - ".xz" "unxz -f"
381 - ".lzma" "unxz -f"
382 -)
383 -
384 -__multijob_init
385 -
386 -for dir in "$@" ; do
387 - dir=${dir#/}
388 - dir="${ED%/}/${dir#/}"
389 - if [[ ! -d ${dir} ]] ; then
390 - __vecho "${0##*/}: /${dir#${ED%/}} does not exist!"
391 - continue
392 - fi
393 - cd "${dir}"
394 - actual_dir=${dir}
395 - dir=. # use relative path to avoid 'Argument list too long' errors
396 -
397 - # hide all the stuff we want to skip
398 - hide_skip_dirs "${dir}"
399 -
400 - # since we've been requested to compress the whole dir,
401 - # delete any individual queued requests
402 - size_limit=${SIZE_LIMIT:-$(<"${actual_dir}.ecompress.dir")}
403 - rm -f "${actual_dir}.ecompress.dir"
404 - find "${dir}" -type f -name '*.ecompress.file' -print0 | ${XARGS} -0 rm -f
405 -
406 - # not uncommon for packages to compress doc files themselves
407 - for (( i = 0; i < ${#decompressors[@]}; i += 2 )) ; do
408 - # It's faster to parallelize at this stage than to try to
409 - # parallelize the compressors. This is because the find|xargs
410 - # ends up launching less compressors overall, so the overhead
411 - # of forking children ends up dominating.
412 - (
413 - __multijob_child_init
414 - funk_up_dir "decompress" "${decompressors[i]}" "${decompressors[i+1]}"
415 - ) &
416 - __multijob_post_fork
417 - : $(( ret |= $? ))
418 - done
419 -
420 - __multijob_finish
421 - : $(( ret |= $? ))
422 -
423 - # forcibly break all hard links as some compressors whine about it
424 - find "${dir}" -type f -links +1 -exec env file="{}" sh -c \
425 - 'cp -p "${file}" "${file}.ecompress.break" ; mv -f "${file}.ecompress.break" "${file}"' \;
426 -
427 - # now lets do our work
428 - if [[ -n ${suffix} ]] ; then
429 - __vecho "${0##*/}: $(ecompress --bin) /${actual_dir#${ED%/}/}"
430 - funk_up_dir "compress" "${suffix}" "ecompress" "${size_limit}"
431 - : $(( ret |= $? ))
432 - fi
433 -
434 - # finally, restore the skipped stuff
435 - restore_skip_dirs
436 -done
437 -
438 -[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
439 -exit ${ret}
440
441 diff --git a/bin/ecompress b/bin/ecompress
442 new file mode 100755
443 index 000000000..075f4225e
444 --- /dev/null
445 +++ b/bin/ecompress
446 @@ -0,0 +1,147 @@
447 +#!/bin/bash
448 +# Copyright 1999-2018 Gentoo Foundation
449 +# Distributed under the terms of the GNU General Public License v2
450 +
451 +source "${PORTAGE_BIN_PATH}"/isolated-functions.sh || exit 1
452 +
453 +if [[ -z $1 ]] ; then
454 + __helpers_die "${0##*/}: at least one argument needed"
455 + exit 1
456 +fi
457 +
458 +if ! ___eapi_has_prefix_variables; then
459 + ED=${D} EPREFIX=
460 +fi
461 +
462 +while [[ $# -gt 0 ]] ; do
463 + case $1 in
464 + --ignore)
465 + shift
466 +
467 + skip_dirs=()
468 + for skip; do
469 + if [[ -d ${ED%/}/${skip#/} ]]; then
470 + skip_dirs+=( "${ED%/}/${skip#/}" )
471 + else
472 + rm -f "${ED%/}/${skip#/}.ecompress" || die
473 + fi
474 + done
475 +
476 + if [[ ${#skip_dirs[@]} -gt 0 ]]; then
477 + find "${skip_dirs[@]}" -name '*.ecompress' -delete || die
478 + fi
479 +
480 + exit 0
481 + ;;
482 + --queue)
483 + shift
484 +
485 + find_args=()
486 + for path; do
487 + if [[ -e ${ED%/}/${path#/} ]]; then
488 + find_args+=( "${ED%/}/${path#/}" )
489 + fi
490 + done
491 +
492 + if [[ ${#find_args[@]} -gt 0 ]]; then
493 + find_args+=( -type f )
494 + [[ -n ${PORTAGE_DOCOMPRESS_SIZE_LIMIT} ]] &&
495 + find_args+=( -size "+${PORTAGE_DOCOMPRESS_SIZE_LIMIT}c" )
496 +
497 + while IFS= read -d '' -r path; do
498 + >> "${path}.ecompress" || die
499 + done < <(find "${find_args[@]}" -print0 || die)
500 + fi
501 +
502 + exit 0
503 + ;;
504 + --dequeue)
505 + [[ -n ${2} ]] && die "${0##*/}: --dequeue takes no additional arguments"
506 + break
507 + ;;
508 + *)
509 + die "${0##*/}: unknown arguments '$*'"
510 + exit 1
511 + ;;
512 + esac
513 + shift
514 +done
515 +
516 +# setup compression stuff
517 +PORTAGE_COMPRESS=${PORTAGE_COMPRESS-bzip2}
518 +[[ -z ${PORTAGE_COMPRESS} ]] && exit 0
519 +
520 +if [[ ${PORTAGE_COMPRESS_FLAGS+set} != "set" ]] ; then
521 + case ${PORTAGE_COMPRESS} in
522 + bzip2|gzip) PORTAGE_COMPRESS_FLAGS="-9";;
523 + esac
524 +fi
525 +
526 +guess_suffix() {
527 + set -e
528 + tmpdir="${T}"/.ecompress$$.${RANDOM}
529 + mkdir "${tmpdir}"
530 + cd "${tmpdir}"
531 + # we have to fill the file enough so that there is something
532 + # to compress as some programs will refuse to do compression
533 + # if it cannot actually compress the file
534 + echo {0..1000} > compressme
535 + ${PORTAGE_COMPRESS} ${PORTAGE_COMPRESS_FLAGS} compressme > /dev/null
536 + # If PORTAGE_COMPRESS_FLAGS contains -k then we need to avoid
537 + # having our glob match the uncompressed file here.
538 + suffix=$(echo compressme.*)
539 + [[ -z $suffix || "$suffix" == "compressme.*" ]] && \
540 + suffix=$(echo compressme*)
541 + suffix=${suffix#compressme}
542 + cd /
543 + rm -rf "${tmpdir}"
544 + echo "${suffix}"
545 +}
546 +
547 +# figure out the new suffix
548 +export PORTAGE_COMPRESS_SUFFIX=$(guess_suffix) || die
549 +
550 +fix_symlinks() {
551 + # Repeat until nothing changes, in order to handle multiple
552 + # levels of indirection (see bug #470916).
553 + local -i indirection=0
554 + while true ; do
555 + local something_changed=
556 + while read -r -d $'\0' brokenlink ; do
557 + [[ -e ${brokenlink} ]] && continue
558 + olddest=$(readlink "${brokenlink}")
559 + newdest=${olddest}${PORTAGE_COMPRESS_SUFFIX}
560 + if [[ "${newdest}" == /* ]] ; then
561 + [[ -f "${D%/}${newdest}" ]] || continue
562 + else
563 + [[ -f "${brokenlink%/*}/${newdest}" ]] || continue
564 + fi
565 + something_changed=${brokenlink}
566 + rm -f "${brokenlink}" &&
567 + ln -snf "${newdest}" "${brokenlink}${PORTAGE_COMPRESS_SUFFIX}"
568 + ((ret|=$?))
569 + done < <(find "${ED}" -type l -print0 || die)
570 +
571 + [[ -n ${something_changed} ]] || break
572 + (( indirection++ ))
573 + if (( indirection >= 100 )) ; then
574 + # Protect against possibility of a bug triggering an endless loop.
575 + eerror "ecompress: too many levels of indirection for" \
576 + "'${something_changed#${ED%/}}'"
577 + break
578 + fi
579 + done
580 +
581 + return ${ret}
582 +}
583 +
584 +export PORTAGE_COMPRESS PORTAGE_COMPRESS_FLAGS
585 +find "${ED}" -name '*.ecompress' -delete \
586 + -exec "${PORTAGE_BIN_PATH}"/ecompress-file {} +
587 +ret=${?}
588 +
589 +fix_symlinks
590 +: $(( ret |= ${?} ))
591 +[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
592 +
593 +exit ${ret}
594
595 diff --git a/bin/ecompress-file b/bin/ecompress-file
596 new file mode 100755
597 index 000000000..18269c91b
598 --- /dev/null
599 +++ b/bin/ecompress-file
600 @@ -0,0 +1,68 @@
601 +#!/bin/bash
602 +# Copyright 1999-2018 Gentoo Foundation
603 +# Distributed under the terms of the GNU General Public License v2
604 +
605 +source "${PORTAGE_BIN_PATH}"/isolated-functions.sh || exit 1
606 +
607 +compress_file() {
608 + mask_ext_re=""
609 + set -f
610 + local x
611 + for x in $PORTAGE_COMPRESS_EXCLUDE_SUFFIXES ; do
612 + mask_ext_re+="|$x"
613 + done
614 + set +f
615 + mask_ext_re="^(${mask_ext_re:1})\$"
616 + local filtered_args=()
617 + local had_precompressed=
618 + for x in "$@" ; do
619 + [[ ${x##*.} =~ $mask_ext_re ]] && continue
620 + [[ -s ${x} ]] || continue
621 +
622 + # handle precompressed files
623 + case ${x} in
624 + *.gz|*.Z)
625 + gunzip -f "${x}" || __helpers_die "gunzip failed"
626 + x=${x%.*}
627 + had_precompressed=1;;
628 + *.bz2)
629 + bunzip2 -f "${x}" || __helpers_die "bunzip2 failed"
630 + x=${x%.bz2}
631 + had_precompressed=1;;
632 + *.lzma|*.xz)
633 + unxz -f "${x}" || __helpers_die "unxz failed"
634 + x=${x%.*}
635 + had_precompressed=1;;
636 + esac
637 +
638 + filtered_args+=( "$x" )
639 + done
640 + [[ ${#filtered_args[@]} -eq 0 ]] && return 0
641 + set -- "${filtered_args[@]}"
642 +
643 + if [[ ${had_precompressed} ]]; then
644 + eqawarn "One or more compressed files were found in docompress-ed directories."
645 + eqawarn "Please fix the ebuild not to install compressed files (manpages,"
646 + eqawarn "documentation) when automatic compression is used."
647 + fi
648 +
649 + # If a compressed version of the file already exists, simply
650 + # delete it so that the compressor doesn't whine (bzip2 will
651 + # complain and skip, gzip will prompt for input)
652 + [[ -n ${PORTAGE_COMPRESS_SUFFIX} ]] && echo -n "${@/%/${PORTAGE_COMPRESS_SUFFIX}$'\001'}" | \
653 + tr '\001' '\000' | ${XARGS} -0 rm -f
654 +
655 + # forcibly break all hard links as some compressors whine about it
656 + while IFS= read -d '' -r x ; do
657 + cp -p "${x}" "${x}.ecompress.break" || die
658 + mv -f "${x}.ecompress.break" "${x}" || die
659 + done < <(find "${@}" -type f -links +1 -print0)
660 +
661 + # Finally, let's actually do some real work
662 + "${PORTAGE_COMPRESS}" ${PORTAGE_COMPRESS_FLAGS} "$@"
663 + ret=$?
664 + [[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
665 + return ${ret}
666 +}
667 +
668 +compress_file "${@%.ecompress}"
669
670 diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh
671 index ed66e90ca..8c88f8f35 100755
672 --- a/bin/misc-functions.sh
673 +++ b/bin/misc-functions.sh
674 @@ -43,125 +43,6 @@ install_symlink_html_docs() {
675 fi
676 }
677
678 -# replacement for "readlink -f" or "realpath"
679 -READLINK_F_WORKS=""
680 -canonicalize() {
681 - if [[ -z ${READLINK_F_WORKS} ]] ; then
682 - if [[ $(readlink -f -- /../ 2>/dev/null) == "/" ]] ; then
683 - READLINK_F_WORKS=true
684 - else
685 - READLINK_F_WORKS=false
686 - fi
687 - fi
688 - if ${READLINK_F_WORKS} ; then
689 - readlink -f -- "$@"
690 - return
691 - fi
692 -
693 - local f=$1 b n=10 wd=$(pwd)
694 - while (( n-- > 0 )); do
695 - while [[ ${f: -1} = / && ${#f} -gt 1 ]]; do
696 - f=${f%/}
697 - done
698 - b=${f##*/}
699 - cd "${f%"${b}"}" 2>/dev/null || break
700 - if [[ ! -L ${b} ]]; then
701 - f=$(pwd -P)
702 - echo "${f%/}/${b}"
703 - cd "${wd}"
704 - return 0
705 - fi
706 - f=$(readlink "${b}")
707 - done
708 - cd "${wd}"
709 - return 1
710 -}
711 -
712 -prepcompress() {
713 - local -a include exclude incl_d incl_f
714 - local f g i real_f real_d
715 - if ! ___eapi_has_prefix_variables; then
716 - local ED=${D}
717 - fi
718 -
719 - # Canonicalize path names and check for their existence.
720 - real_d=$(canonicalize "${ED}")
721 - for (( i = 0; i < ${#PORTAGE_DOCOMPRESS[@]}; i++ )); do
722 - real_f=$(canonicalize "${ED%/}/${PORTAGE_DOCOMPRESS[i]#/}")
723 - f=${real_f#"${real_d}"}
724 - if [[ ${real_f} != "${f}" ]] && [[ -d ${real_f} || -f ${real_f} ]]
725 - then
726 - include[${#include[@]}]=${f:-/}
727 - elif [[ ${i} -ge 3 ]]; then
728 - ewarn "prepcompress:" \
729 - "ignoring nonexistent path '${PORTAGE_DOCOMPRESS[i]}'"
730 - fi
731 - done
732 - for (( i = 0; i < ${#PORTAGE_DOCOMPRESS_SKIP[@]}; i++ )); do
733 - real_f=$(canonicalize "${ED%/}/${PORTAGE_DOCOMPRESS_SKIP[i]#/}")
734 - f=${real_f#"${real_d}"}
735 - if [[ ${real_f} != "${f}" ]] && [[ -d ${real_f} || -f ${real_f} ]]
736 - then
737 - exclude[${#exclude[@]}]=${f:-/}
738 - elif [[ ${i} -ge 1 ]]; then
739 - ewarn "prepcompress:" \
740 - "ignoring nonexistent path '${PORTAGE_DOCOMPRESS_SKIP[i]}'"
741 - fi
742 - done
743 -
744 - # Remove redundant entries from lists.
745 - # For the include list, remove any entries that are:
746 - # a) contained in a directory in the include or exclude lists, or
747 - # b) identical with an entry in the exclude list.
748 - for (( i = ${#include[@]} - 1; i >= 0; i-- )); do
749 - f=${include[i]}
750 - for g in "${include[@]}"; do
751 - if [[ ${f} == "${g%/}"/* ]]; then
752 - unset include[i]
753 - continue 2
754 - fi
755 - done
756 - for g in "${exclude[@]}"; do
757 - if [[ ${f} = "${g}" || ${f} == "${g%/}"/* ]]; then
758 - unset include[i]
759 - continue 2
760 - fi
761 - done
762 - done
763 - # For the exclude list, remove any entries that are:
764 - # a) contained in a directory in the exclude list, or
765 - # b) _not_ contained in a directory in the include list.
766 - for (( i = ${#exclude[@]} - 1; i >= 0; i-- )); do
767 - f=${exclude[i]}
768 - for g in "${exclude[@]}"; do
769 - if [[ ${f} == "${g%/}"/* ]]; then
770 - unset exclude[i]
771 - continue 2
772 - fi
773 - done
774 - for g in "${include[@]}"; do
775 - [[ ${f} == "${g%/}"/* ]] && continue 2
776 - done
777 - unset exclude[i]
778 - done
779 -
780 - # Split the include list into directories and files
781 - for f in "${include[@]}"; do
782 - if [[ -d ${ED%/}/${f#/} ]]; then
783 - incl_d[${#incl_d[@]}]=${f}
784 - else
785 - incl_f[${#incl_f[@]}]=${f}
786 - fi
787 - done
788 -
789 - # Queue up for compression.
790 - # ecompress{,dir} doesn't like to be called with empty argument lists.
791 - [[ ${#incl_d[@]} -gt 0 ]] && ecompressdir --limit ${PORTAGE_DOCOMPRESS_SIZE_LIMIT:-0} --queue "${incl_d[@]}"
792 - [[ ${#incl_f[@]} -gt 0 ]] && ecompress --queue "${incl_f[@]/#/${ED%/}}"
793 - [[ ${#exclude[@]} -gt 0 ]] && ecompressdir --ignore "${exclude[@]}"
794 - return 0
795 -}
796 -
797 __prepall() {
798 if has chflags $FEATURES ; then
799 # Save all the file flags for restoration at the end of prepall.
800 @@ -173,6 +54,11 @@ __prepall() {
801
802 [[ -d ${ED%/}/usr/share/info ]] && prepinfo
803
804 + # Apply compression.
805 + "${PORTAGE_BIN_PATH}"/ecompress --queue "${PORTAGE_DOCOMPRESS[@]}"
806 + "${PORTAGE_BIN_PATH}"/ecompress --ignore "${PORTAGE_DOCOMPRESS_SKIP[@]}"
807 + "${PORTAGE_BIN_PATH}"/ecompress --dequeue
808 +
809 ___eapi_has_dostrip || prepallstrip
810
811 if has chflags $FEATURES ; then
812 @@ -239,9 +125,6 @@ install_qa_check() {
813
814 export STRIP_MASK
815 __prepall
816 - prepcompress
817 - ecompressdir --dequeue
818 - ecompress --dequeue
819
820 if ___eapi_has_dostrip; then
821 "${PORTAGE_BIN_PATH}"/estrip --queue "${PORTAGE_DOSTRIP[@]}"
822
823 diff --git a/lib/portage/tests/bin/setup_env.py b/lib/portage/tests/bin/setup_env.py
824 index 9cc26df08..33b167989 100644
825 --- a/lib/portage/tests/bin/setup_env.py
826 +++ b/lib/portage/tests/bin/setup_env.py
827 @@ -82,6 +82,6 @@ for bin in os.listdir(os.path.join(bindir, 'ebuild-helpers')):
828 if bin.startswith('do') or \
829 bin.startswith('new') or \
830 bin.startswith('prep') or \
831 - bin in ('ecompress', 'ecompressdir', 'fowners', 'fperms'):
832 + bin in ('fowners', 'fperms'):
833 globals()[bin] = create_portage_wrapper(
834 os.path.join(bindir, 'ebuild-helpers', bin))