Signed-off-by: Michał Górny <mgo...@gentoo.org> --- eclass/tests/unpacker.sh | 47 ++++++++++++++++++++++++++++++++++++++++ eclass/unpacker.eclass | 38 ++++++++++++++++++++++++++++++++ 2 files changed, 85 insertions(+)
diff --git a/eclass/tests/unpacker.sh b/eclass/tests/unpacker.sh index 60b651759a52..bbbfa32623ab 100755 --- a/eclass/tests/unpacker.sh +++ b/eclass/tests/unpacker.sh @@ -136,6 +136,43 @@ test_deb() { "create_deb '${suffix}' '${tool_cmd}' \${archive} \${TESTFILE}" } +create_gpkg() { + local suffix=${1} + local tool=${2} + local archive=${3} + local infile=${4} + local gpkg_dir=${archive%.gpkg.tar} + + mkdir image metadata "${gpkg_dir}" || die + cp "${infile}" image/ || die + tar -c metadata | ${tool} > "${gpkg_dir}/metadata.tar${suffix}" + assert "packing metadata.tar${suffix} failed" + : > "${gpkg_dir}/metadata.tar${suffix}.sig" || die + tar -c image | ${tool} > "${gpkg_dir}/image.tar${suffix}" + assert "packing image.tar${suffix} failed" + : > "${gpkg_dir}/image.tar${suffix}.sig" || die + : > "${gpkg_dir}"/gpkg-1 || die + tar -cf "${archive}" --format=ustar \ + "${gpkg_dir}"/{gpkg-1,{metadata,image}.tar"${suffix}"} || die + rm -r image metadata "${gpkg_dir}" || die +} + +test_gpkg() { + local suffix=${1} + local tool=${2} + local tool_cmd + + if [[ -n ${tool} ]]; then + tool_cmd="${tool} -c" + else + tool_cmd=cat + fi + + test_unpack "test-${tool}-1.2.3-1.gpkg.tar" \ + "test-${tool}-1.2.3-1/image/test.in" "tar ${tool}" \ + "create_gpkg '${suffix}' '${tool_cmd}' \${archive} \${TESTFILE}" +} + test_reject_junk() { local suffix=${1} local archive=test${1} @@ -209,6 +246,16 @@ test_deb .xz xz test_deb .bz2 bzip2 test_deb .lzma lzma +test_gpkg +test_gpkg .gz gzip +test_gpkg .bz2 bzip2 +test_gpkg .lz4 lz4 +test_gpkg .lz lzip +test_gpkg .lzma lzma +test_gpkg .lzo lzop +test_gpkg .xz xz +test_gpkg .zst zstd + test_unpack test.zip test.in zip 'zip -q ${archive} ${TESTFILE}' # test handling non-adjusted zip with junk prepended test_unpack test.zip test.in zip \ diff --git a/eclass/unpacker.eclass b/eclass/unpacker.eclass index a64c5eae18aa..70a46ac19709 100644 --- a/eclass/unpacker.eclass +++ b/eclass/unpacker.eclass @@ -408,6 +408,42 @@ _unpacker_get_decompressor() { esac } +# @FUNCTION: unpack_gpkg +# @USAGE: <gpkg file> +# @DESCRIPTION: +# Unpack the image subarchive of a GPKG package on-the-fly, preserving +# the original directory structure (i.e. into <gpkg-dir>/image). +unpack_gpkg() { + [[ $# -eq 1 ]] || die "Usage: ${FUNCNAME} <file>" + + local gpkg=$(find_unpackable_file "$1") + unpack_banner "${gpkg}" + + local l images=() + while read -r l; do + case ${l} in + */image.tar*.sig) + ;; + */image.tar*) + images+=( "${l}" ) + ;; + esac + done < <(tar -tf "${gpkg}" || die "unable to list ${gpkg}") + + if [[ ${#images[@]} -eq 0 ]]; then + die "No image.tar found in ${gpkg}" + elif [[ ${#images[@]} -gt 1 ]]; then + die "More than one image.tar found in ${gpkg}" + fi + + local decomp=$(_unpacker_get_decompressor "${images[0]}") + local dirname=${images[0]%/*} + mkdir -p "${dirname}" || die + tar -xOf "${gpkg}" "${images[0]}" | ${decomp:-cat} | + tar --no-same-owner -xC "${dirname}" + assert "Unpacking ${gpkg} failed" +} + # @FUNCTION: _unpacker # @USAGE: <one archive to unpack> # @INTERNAL @@ -427,6 +463,8 @@ _unpacker() { # then figure out if there are any archiving aspects local arch="" case ${m} in + *.gpkg.tar) + arch="unpack_gpkg" ;; *.tgz|*.tbz|*.tbz2|*.txz|*.tar.*|*.tar) arch="tar --no-same-owner -xof" ;; *.cpio.*|*.cpio) -- 2.37.3