From 76e9d7112523ec9e792aefa594261e3faadcef9338fe70875be7f74bb4356843 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Fri, 10 Jan 2020 21:28:02 +0000 Subject: [PATCH 1/2] - compare archives in separate directory to preserve existing files - consider only files and symlinks in verify_before_processing OBS-URL: https://build.opensuse.org/package/show/openSUSE:Tools/build-compare?expand=0&rev=262 --- build-compare.changes | 6 ++ build-compare.spec | 2 +- pkg-diff.sh | 222 +++++++++++++++++++++++------------------- 3 files changed, 131 insertions(+), 99 deletions(-) diff --git a/build-compare.changes b/build-compare.changes index 0db0ae8..d09a72a 100644 --- a/build-compare.changes +++ b/build-compare.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri Jan 10 19:16:29 UTC 2020 - olaf@aepfle.de + +- compare archives in separate directory to preserve existing files +- consider only files and symlinks in verify_before_processing + ------------------------------------------------------------------- Tue Jan 7 13:59:43 UTC 2020 - olaf@aepfle.de diff --git a/build-compare.spec b/build-compare.spec index 355128c..c4ed427 100644 --- a/build-compare.spec +++ b/build-compare.spec @@ -21,7 +21,7 @@ Summary: Build Result Compare Script License: GPL-2.0+ Group: Development/Tools/Building Url: https://github.com/openSUSE/build-compare -Version: 20200109T124459.beb05d0 +Version: 20200110T222328.b5aa37b Release: 0 Source1: COPYING Source2: same-build-result.sh diff --git a/pkg-diff.sh b/pkg-diff.sh index 39a83c9..2a1713e 100644 --- a/pkg-diff.sh +++ b/pkg-diff.sh @@ -211,6 +211,14 @@ verify_before_processing() return 1 fi + # consider only files and symlinks + if test ! -f "old/$file"; then + return 0 + fi + if test ! -f "new/$file"; then + return 0 + fi + if cmp -b "old/$file" "new/$file" > "${cmpout}" ; then return 0 fi @@ -633,6 +641,110 @@ normalize_file() esac } +a_list() +{ + ar t "$1" +} +a_extract() +{ + ar x "$1" +} + +cpio_list() +{ + cpio --quiet --list --force-local < "$1" +} +cpio_extract() +{ + cpio --quiet --extract --force-local < "$1" +} + +squashfs_list() +{ + unsquashfs -no-progress -ls -dest '' "$1" | grep -Ev '^(Parallel unsquashfs:|[0-9]+ inodes )' +} +squashfs_extract() +{ + unsquashfs -no-progress -dest "." "$1" +} + +tar_list() +{ + tar tf "$1" +} +tar_extract() +{ + tar xf "$1" +} + +zip_list() +{ + unjar_l "$1" +} +zip_extract() +{ + unjar "$1" +} + +# returns 0 if content is identical +# returns 1 if at least one file differs +compare_archive() +{ + local file="$1" + local old="$2" + local new="$3" + local tool="$4" + local fn_list="$5" + local fn_extr="$6" + local f= + local -a content + local -i ret=1 + + test -x "$(type -P ${tool})" || return 1 + + mkdir -p "d/old/${file}" "d/new/${file}" + if pushd "d" > /dev/null + then + ${fn_list} "${old}" | ${sort} > 'co' + ${fn_list} "${new}" | ${sort} > 'cn' + if cmp -s 'co' 'cn' + then + if pushd "old/${file}" > /dev/null + then + "${fn_extr}" "${old}" + popd > /dev/null + fi + if pushd "new/${file}" > /dev/null + then + "${fn_extr}" "${new}" + popd > /dev/null + fi + readarray -t content < 'cn' + compare_archive_content "${file}" "${content[@]}" + for f in "${content[@]}" + do + if ! check_single_file "${file}/${f}" + then + ret=1 + if test -z "$check_all" + then + break + fi + fi + watchdog_touch + done + ret=$? + else + wprint "$file has different file list" + diff -u 'co' 'cn' + fi + popd > /dev/null + rm -rf "d" + fi + + return ${ret} +} + check_single_file() { local file="$1" @@ -660,111 +772,25 @@ check_single_file() case "$file" in *.a) - flist=`ar t "new/$file"` - pwd=$PWD - fdir=`dirname "$file"` - cd "old/$fdir" - ar x `basename "$file"` - cd "$pwd/new/$fdir" - ar x `basename "$file"` - cd "$pwd" - for f in $flist; do - if ! check_single_file "$fdir/$f"; then - return 1 - fi - watchdog_touch - done - return 0 + compare_archive "${file}" "`readlink -f \"old/$file\"`" "`readlink -f \"new/$file\"`" 'ar' 'a_list' 'a_extract' + return $? ;; *.cpio) - flist=`cpio --quiet --list --force-local < "new/$file" | $sort` - pwd=$PWD - fdir="$file.extract.$PPID.$$" - mkdir "old/$fdir" "new/$fdir" - cd "old/$fdir" - cpio --quiet --extract --force-local < "../${file##*/}" - cd "$pwd/new/$fdir" - cpio --quiet --extract --force-local < "../${file##*/}" - cd "$pwd" - for f in $flist; do - if ! check_single_file "$fdir/$f"; then - ret=1 - if test -z "$check_all"; then - break - fi - fi - watchdog_touch - done - rm -rf "old/$fdir" "new/$fdir" - return $ret + compare_archive "${file}" "`readlink -f \"old/$file\"`" "`readlink -f \"new/$file\"`" 'cpio' 'cpio_list' 'cpio_extract' + return $? ;; *.squashfs) - flist=`unsquashfs -no-progress -ls -dest '' "new/$file" | grep -Ev '^(Parallel unsquashfs:|[0-9]+ inodes )' | $sort` - fdir="$file.extract.$PPID.$$" - unsquashfs -no-progress -dest "old/$fdir" "old/$file" - unsquashfs -no-progress -dest "new/$fdir" "new/$file" - for f in $flist; do - if ! check_single_file "$fdir/$f"; then - ret=1 - if test -z "$check_all"; then - break - fi - fi - watchdog_touch - done - rm -rf "old/$fdir" "new/$fdir" - return $ret + compare_archive "${file}" "`readlink -f \"old/$file\"`" "`readlink -f \"new/$file\"`" 'unsquashfs' 'squashfs_list' 'squashfs_extract' + return $? ;; *.tar|*.tar.bz2|*.tar.gz|*.tgz|*.tbz2) - flist=`tar tf "new/$file"` - pwd=$PWD - fdir=`dirname "$file"` - cd "old/$fdir" - tar xf `basename "$file"` - cd "$pwd/new/$fdir" - tar xf `basename "$file"` - cd "$pwd" - for f in $flist; do - if ! check_single_file "$fdir/$f"; then - ret=1 - if test -z "$check_all"; then - break - fi - fi - watchdog_touch - done - return $ret - ;; + compare_archive "${file}" "`readlink -f \"old/$file\"`" "`readlink -f \"new/$file\"`" 'tar' 'tar_list' 'tar_extract' + return $? + ;; *.zip|*.egg|*.jar|*.war) - for dir in old new ; do - ( - cd $dir - unjar_l ./$file | $sort > flist - ) - done - if ! cmp -s old/flist new/flist; then - wprint "$file has different file list" - diff -u old/flist new/flist - return 1 - fi - flist=`cat new/flist` - pwd=$PWD - fdir=`dirname $file` - cd old/$fdir - unjar `basename $file` - cd $pwd/new/$fdir - unjar `basename $file` - cd $pwd - for f in $flist; do - if test -f new/$fdir/$f && ! check_single_file $fdir/$f; then - ret=1 - if test -z "$check_all"; then - break - fi - fi - watchdog_touch - done - return $ret;; + compare_archive "${file}" "`readlink -f \"old/$file\"`" "`readlink -f \"new/$file\"`" 'true' 'zip_list' 'zip_extract' + return $? + ;; *.bz2) bunzip2 -c old/$file > old/${file/.bz2/} bunzip2 -c new/$file > new/${file/.bz2/} From 6052501a808d25ed51d967350dd41c0de54093774fe555753b00744acf263325 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Wed, 15 Jan 2020 15:59:48 +0000 Subject: [PATCH 2/2] simplify compare_archive API OBS-URL: https://build.opensuse.org/package/show/openSUSE:Tools/build-compare?expand=0&rev=263 --- build-compare.spec | 2 +- pkg-diff.sh | 242 +++++++++++++++++++++++++++------------------ 2 files changed, 146 insertions(+), 98 deletions(-) diff --git a/build-compare.spec b/build-compare.spec index c4ed427..014f92e 100644 --- a/build-compare.spec +++ b/build-compare.spec @@ -21,7 +21,7 @@ Summary: Build Result Compare Script License: GPL-2.0+ Group: Development/Tools/Building Url: https://github.com/openSUSE/build-compare -Version: 20200110T222328.b5aa37b +Version: 20200115T165709.b82e1e5 Release: 0 Source1: COPYING Source2: same-build-result.sh diff --git a/pkg-diff.sh b/pkg-diff.sh index 2a1713e..7231c45 100644 --- a/pkg-diff.sh +++ b/pkg-diff.sh @@ -43,56 +43,6 @@ function wprint watchdog_reset } -function findunjarbin -{ - if [[ $(type -p fastjar) ]]; then - UNJAR=fastjar - elif [[ $(type -p jar) ]]; then - UNJAR=jar - elif [[ $(type -p unzip) ]]; then - UNJAR=unzip - else - echo "ERROR: jar, fastjar, or unzip is not installed (trying file $file)" - exit 1 - fi -} - -#usage unjar -function unjar() -{ - local file - file=$1 - - findunjarbin - case $UNJAR in - jar|fastjar) - # echo jar -xf $file - ${UNJAR} -xf $file - ;; - unzip) - unzip -oqq $file - ;; - esac -} - -# list files in given jar file -#usage unjar_l -function unjar_l() -{ - local file - file=$1 - - findunjarbin - case $UNJAR in - jar|fastjar) - ${UNJAR} -tf $file - ;; - unzip) - unzip -Z -1 $file - ;; - esac -} - filter_disasm() { [[ $nofilter ]] && return @@ -641,86 +591,184 @@ normalize_file() esac } -a_list() +archive_a() { - ar t "$1" -} -a_extract() -{ - ar x "$1" + local cmd=$1 + local file=$2 + case "${cmd}" in + f) + test -x "$(type -P ar)" && return 0 + echo "ERROR: ar missing for ${file}" + return 1 + ;; + l) + ar t "${file}" + test "$?" = "0" && return 0 + return 1 + ;; + x) + ar x "${file}" + test "$?" = "0" && return 0 + return 1 + ;; + esac } -cpio_list() +archive_cpio() { - cpio --quiet --list --force-local < "$1" -} -cpio_extract() -{ - cpio --quiet --extract --force-local < "$1" + local cmd=$1 + local file=$2 + case "${cmd}" in + f) + test -x "$(type -P cpio)" && return 0 + echo "ERROR: cpio missing for ${file}" + return 1 + ;; + l) + cpio --quiet --list --force-local < "${file}" + test "$?" = "0" && return 0 + return 1 + ;; + x) + cpio --quiet --extract --force-local < "${file}" + test "$?" = "0" && return 0 + return 1 + ;; + esac } -squashfs_list() +archive_squashfs() { - unsquashfs -no-progress -ls -dest '' "$1" | grep -Ev '^(Parallel unsquashfs:|[0-9]+ inodes )' -} -squashfs_extract() -{ - unsquashfs -no-progress -dest "." "$1" + local cmd=$1 + local file=$2 + case "${cmd}" in + f) + test -x "$(type -P unsquashfs)" && return 0 + echo "ERROR: unsquashfs missing for ${file}" + return 1 + ;; + l) + unsquashfs -no-progress -ls -dest '' "${file}" | grep -Ev '^(Parallel unsquashfs:|[0-9]+ inodes )' + test "$?" = "0" && return 0 + return 1 + ;; + x) + unsquashfs -no-progress -dest "." "${file}" + test "$?" = "0" && return 0 + return 1 + ;; + esac } -tar_list() +archive_tar() { - tar tf "$1" -} -tar_extract() -{ - tar xf "$1" + local cmd=$1 + local file=$2 + case "${cmd}" in + f) + test -x "$(type -P tar)" && return 0 + echo "ERROR: tar missing for ${file}" + return 1 + ;; + l) + tar tf "${file}" + test "$?" = "0" && return 0 + return 1 + ;; + x) + tar xf "${file}" + test "$?" = "0" && return 0 + return 1 + ;; + esac } -zip_list() +UNJAR= +archive_zip() { - unjar_l "$1" -} -zip_extract() -{ - unjar "$1" + local cmd=$1 + local file=$2 + case "${cmd}" in + f) + if test -x "$(type -P fastjar)" + then + UNJAR="${_}" + elif test -x "$(type -P jar)" + then + UNJAR="${_}" + elif test -x "$(type -P unzip)" + then + UNJAR="${_}" + else + echo "ERROR: jar/fastjar/unzip missing for ${file}" + return 1 + fi + return 0 + ;; + l) + case "${UNJAR##*/}" in + jar|fastjar) + "${UNJAR}" -tf "${file}" + ;; + unzip) + "${UNJAR}" -Z -1 "${file}" + ;; + esac + test "$?" = "0" && return 0 + return 1 + ;; + x) + case "${UNJAR##*/}" in + jar|fastjar) + "${UNJAR}" -xf "${file}" + ;; + unzip) + "${UNJAR}" -oqq "${file}" + ;; + esac + test "$?" = "0" && return 0 + return 1 + ;; + esac } # returns 0 if content is identical # returns 1 if at least one file differs +# handler f returns 1 if required tool for inspection is missing +# handler l lists content, returns 1 if tool failed +# handler x extracts content, returns 1 if tool failed compare_archive() { local file="$1" - local old="$2" - local new="$3" - local tool="$4" - local fn_list="$5" - local fn_extr="$6" - local f= + local handler="$2" + local old="`readlink -f \"old/$file\"`" + local new="`readlink -f \"new/$file\"`" + local f local -a content local -i ret=1 - test -x "$(type -P ${tool})" || return 1 + "${handler}" 'f' "${file}" || return 1 mkdir -p "d/old/${file}" "d/new/${file}" if pushd "d" > /dev/null then - ${fn_list} "${old}" | ${sort} > 'co' - ${fn_list} "${new}" | ${sort} > 'cn' + "${handler}" 'l' "${old}" | ${sort} > 'co' + test "${PIPESTATUS[0]}" = "0" || return 1 + "${handler}" 'l' "${new}" | ${sort} > 'cn' + test "${PIPESTATUS[0]}" = "0" || return 1 if cmp -s 'co' 'cn' then if pushd "old/${file}" > /dev/null then - "${fn_extr}" "${old}" + "${handler}" 'x' "${old}" || return 1 popd > /dev/null fi if pushd "new/${file}" > /dev/null then - "${fn_extr}" "${new}" + "${handler}" 'x' "${new}" || return 1 popd > /dev/null fi readarray -t content < 'cn' - compare_archive_content "${file}" "${content[@]}" for f in "${content[@]}" do if ! check_single_file "${file}/${f}" @@ -772,23 +820,23 @@ check_single_file() case "$file" in *.a) - compare_archive "${file}" "`readlink -f \"old/$file\"`" "`readlink -f \"new/$file\"`" 'ar' 'a_list' 'a_extract' + compare_archive "${file}" 'archive_a' return $? ;; *.cpio) - compare_archive "${file}" "`readlink -f \"old/$file\"`" "`readlink -f \"new/$file\"`" 'cpio' 'cpio_list' 'cpio_extract' + compare_archive "${file}" 'archive_cpio' return $? ;; *.squashfs) - compare_archive "${file}" "`readlink -f \"old/$file\"`" "`readlink -f \"new/$file\"`" 'unsquashfs' 'squashfs_list' 'squashfs_extract' + compare_archive "${file}" 'archive_squashfs' return $? ;; *.tar|*.tar.bz2|*.tar.gz|*.tgz|*.tbz2) - compare_archive "${file}" "`readlink -f \"old/$file\"`" "`readlink -f \"new/$file\"`" 'tar' 'tar_list' 'tar_extract' + compare_archive "${file}" 'archive_tar' return $? ;; *.zip|*.egg|*.jar|*.war) - compare_archive "${file}" "`readlink -f \"old/$file\"`" "`readlink -f \"new/$file\"`" 'true' 'zip_list' 'zip_extract' + compare_archive "${file}" 'archive_zip' return $? ;; *.bz2)