From: wang biao Date: Mon, 8 Apr 2024 03:01:57 +0000 (+0800) Subject: Upgrade version to 2023.06.18 X-Git-Tag: accepted/tizen/base/20240418.043804~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=db27c9453d41c985b1802dc848085b0a9dd32b48;p=platform%2Fupstream%2Fbuild-compare.git Upgrade version to 2023.06.18 Change-Id: If12e72333813bd95af632c8e5ba7ebb64706ca08 Signed-off-by: wang biao --- diff --git a/packaging/build-compare.changes b/packaging/build-compare.changes index 3d0dbde..e687537 100644 --- a/packaging/build-compare.changes +++ b/packaging/build-compare.changes @@ -1,4 +1,402 @@ ------------------------------------------------------------------- +Sat Jun 17 17:17:17 UTC 2023 - olaf@aepfle.de + +- Filter dune language version in dune-package files + +------------------------------------------------------------------- +Wed May 3 17:32:18 UTC 2023 - Oleg Girko + +- Fix filtering compiled Python modules to handle Python >= 3.7 + +------------------------------------------------------------------- +Fri Apr 28 21:21:21 UTC 2023 - olaf@aepfle.de + +- remove timestamps from png files + +------------------------------------------------------------------- +Sat Apr 8 23:58:34 UTC 2023 - Oleg Girko + +- Ignore more sections when comparing ELF executable files + +------------------------------------------------------------------- +Fri Nov 25 23:51:35 UTC 2022 - Stefan Brüns + +- Trim "PROVIDES" from source rpms (#59, bsc#1205998) + +------------------------------------------------------------------- +Mon Sep 19 08:02:40 UTC 2022 - Dirk Müller + +- move license to licensedir +- spec file cleanups + +------------------------------------------------------------------- +Fri Sep 2 07:15:18 UTC 2022 - Martin Kampas + +- fix compatibility with older sed (#55) + +------------------------------------------------------------------- +Tue Aug 23 06:53:29 UTC 2022 - Martin Kampas + +- handle more setuid/setgid ELF variants (#54) + +------------------------------------------------------------------- +Mon Jun 20 12:34:56 UTC 2022 - olaf@aepfle.de + +- fix objdump parsing for non-executable sections (#53) + +------------------------------------------------------------------- +Mon Jun 13 13:13:13 UTC 2022 - olaf@aepfle.de + +- fix objdump parsing (#52) + +------------------------------------------------------------------- +Fri Mar 4 12:34:56 UTC 2022 - olaf@aepfle.de + +- handle -a also in same-build-result.sh +- Find rpmlint.log in more places +- fix logic error in appstream comparison +- rework exit handling in same-build-result.sh +- Fix result in case no rpmlint.log exist +- remove count of checks and packages from rpmlint.log +- remove Check time report from rpmlint.log +- ELF diffing performance improvements +- unpack packages in parallel +- Add zstd handling + +------------------------------------------------------------------- +Wed Feb 23 08:13:27 UTC 2022 - Stefan Seyfried + +- Add extra handling for KMP versions + +------------------------------------------------------------------- +Tue Sep 21 19:19:19 UTC 2021 - Stephan Kulow + +- Fix build-compare for shadow package + +------------------------------------------------------------------- +Mon Sep 20 08:25:27 UTC 2021 - Andreas Schwab + +- Properly drop another duration from rpmlint.log + +------------------------------------------------------------------- +Mon Sep 6 07:15:06 UTC 2021 - bwiedemann@suse.de + +- Drop another duration from rpmlint.log + +------------------------------------------------------------------- +Wed Aug 11 20:30:40 UTC 2021 - olaf@aepfle.de + +- Handle another Date: variant in DocBook generated man pages + +------------------------------------------------------------------- +Mon Jul 27 06:06:06 UTC 2020 - bwiedemann@suse.de + +- Make output more diffable and readable +- Fix regression in compare_archive +- Fix unit tests + +------------------------------------------------------------------- +Fri May 29 19:20:21 UTC 2020 - olaf@aepfle.de + +- Remove usage of readarray to remain compatible with bash3 + +------------------------------------------------------------------- +Fri May 29 07:30:51 UTC 2020 - olaf@aepfle.de + +- Colltect a list of known rpm tags and use it to build the + queryformat string for the tags listed below (bsc#1172232) + conflict obsolete oldsuggests provide recommend require suggest supplement + +------------------------------------------------------------------- +Thu May 14 07:07:07 UTC 2020 - olaf@aepfle.de + +- Trim first line of man page to catch overly verbose tools (now Pandoc) + +------------------------------------------------------------------- +Wed May 13 13:13:13 UTC 2020 - olaf@aepfle.de + +- compare also posttrans scripts, and pretrans + verifyscript + +------------------------------------------------------------------- +Tue May 5 05:05:05 UTC 2020 - olaf@aepfle.de + +- handle oddly named ZIP archives +- touch watchdog every 15 instead of 57 minutes + +------------------------------------------------------------------- +Tue Mar 31 09:09:09 UTC 2020 - olaf@aepfle.de + +- gtk-doc: filter version info from html files + +------------------------------------------------------------------- +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 + +- this new decade must be handled in man pages created by docbook.xml +- use bash Process Substitution in diff_two_files +- use bash Process Substitution when processing ELF files +- move normalizing code from check_single_file into separate function +- better input verification in check_single_file +- split verification from diff_two_files into separate function +- move check for ignored files out of check_single_file +- separate helper functions from code in pkg-diff +- touch host watchdog when producing output and in loops (issue#35) +- add functions to touch host watchdog +- always run cleanup in check_compressed_file +- use EXIT handler in pkg-diff to remove tmpfiles + +------------------------------------------------------------------- +Wed Aug 14 13:27:38 UTC 2019 - John Vandenberg + +- pkg-diff.sh: Ignore R build timestamp & temp paths + https://github.com/openSUSE/build-compare/pull/34 + +------------------------------------------------------------------- +Tue Feb 19 09:30:20 UTC 2019 - olaf@aepfle.de + +- javadoc: filter dc.created +- Support filenames with spaces +- jar: always list files without date+size +- Fix differing jars reported as identical + +------------------------------------------------------------------- +Tue Aug 28 20:14:53 UTC 2018 - ol@infoserver.lv + +- Ignore value of Release header when comparing spec files + +------------------------------------------------------------------- +Fri Jul 6 14:01:17 UTC 2018 - olaf@aepfle.de + +- pkg-diff: fix diff returning 0 + +------------------------------------------------------------------- +Wed Jul 4 05:58:13 UTC 2018 - olaf@aepfle.de + +- Match also ELF pie executable (bsc#1097339) + +------------------------------------------------------------------- +Wed Jul 4 05:42:05 UTC 2018 - olaf@aepfle.de + +- Remove trailing space from two match patterns + +------------------------------------------------------------------- +Tue Jun 26 06:45:38 UTC 2018 - olaf@aepfle.de + +- Recognize "setuid ELF nn-bit xSB shared object" ELF binaries + +------------------------------------------------------------------- +Mon May 28 13:26:44 UTC 2018 - olaf@aepfle.de + +- Avoid large temporary files from hexdump output and avoid + diff(1) runing OOM by using a fifo (issue#24) + +------------------------------------------------------------------- +Fri Apr 13 07:10:30 UTC 2018 - olaf@aepfle.de + +- check rpm capabilities for recommends/suggests + +------------------------------------------------------------------- +Fri Dec 8 16:57:00 UTC 2017 - ol@infoserver.lv + +- Ignore /usr/lib/.build-id differences in package filelist + +------------------------------------------------------------------- +Mon Dec 4 10:21:44 UTC 2017 - olaf@aepfle.de + +- Treat .egg files as zip + +------------------------------------------------------------------- +Wed Nov 8 06:04:42 UTC 2017 - olaf@aepfle.de + +- srpm check requires cpio + +------------------------------------------------------------------- +Mon Nov 6 15:15:04 UTC 2017 - olaf@aepfle.de + +- Fix usage of cmp_spec and unrpm in srpm-check.sh + +------------------------------------------------------------------- +Fri Nov 3 14:03:04 UTC 2017 - olaf@aepfle.de + +- Catch empty rpm -qp --qf output for tags not understood by rpm + +------------------------------------------------------------------- +Fri Oct 20 06:53:18 UTC 2017 - olaf@aepfle.de + +- Remove newly introduced files-duplicate check from rpmlint + In case files are hardlinked, the source and destination is + scrambled in rpm output: the pkg will be republished. + In case files are not hardlinked, the source and destination + is scrambled in rpmlint output: the pkg will be republished + +------------------------------------------------------------------- +Thu Jul 27 12:05:25 UTC 2017 - olaf@aepfle.de + +- Compare also supplements and recomments (issue#18) + +------------------------------------------------------------------- +Fri Mar 31 13:44:11 UTC 2017 - olaf@aepfle.de + +- Handle timestamp and checksum in xen.efi + +------------------------------------------------------------------- +Wed Mar 22 19:05:36 UTC 2017 - olaf@aepfle.de + +- Handle _kf5_htmldir, it HAD to be different... + +------------------------------------------------------------------- +Tue Mar 21 11:17:26 UTC 2017 - olaf@aepfle.de + +- Handle /usr/share/vdr/locale/ + +------------------------------------------------------------------- +Sun Feb 12 08:41:01 UTC 2017 - olaf@aepfle.de + +- Remove warning file-contains-date-and-time from rpmlint.log + +------------------------------------------------------------------- +Thu Jan 5 11:01:53 UTC 2017 - olaf@aepfle.de + +- Fix name-version-release regex for release without dots + +------------------------------------------------------------------- +Wed Dec 14 08:44:11 UTC 2016 - olaf@aepfle.de + +- Remove warning about python mtime mismatch, a republish will not help (bsc#915948) +- Handle yet another variant of numbered anchor in html file + +------------------------------------------------------------------- +Wed Nov 9 06:48:22 UTC 2016 - olaf@aepfle.de + +- Ignore /etc/ld.so.cache +- Ignore /etc/machine-id + +------------------------------------------------------------------- +Tue Nov 8 08:06:30 UTC 2016 - olaf@aepfle.de + +- Ignore /etc/hosts +- Handle every path matching /share/man/ as man page + +------------------------------------------------------------------- +Mon Nov 7 03:54:00 UTC 2016 - ol@infoserver.lv + +- Ignore .gnu_debugdata section when comparing ELF files. + +------------------------------------------------------------------- +Wed Oct 12 16:40:24 CEST 2016 - ro@suse.de + +- pkg-diff.sh: use option --speed-large-files for diffing + disassembler output (bsc#1003528) + +------------------------------------------------------------------- +Wed Sep 21 07:18:37 UTC 2016 - olaf@aepfle.de + +- Handle broken symlinks + +------------------------------------------------------------------- +Thu Aug 25 14:27:34 UTC 2016 - olaf@aepfle.de + +- Update strip_numbered_anchors to catch more random identifiers + +------------------------------------------------------------------- +Wed Aug 24 13:22:12 UTC 2016 - liezhi.yang@windriver.com + +- functions.sh: improve deb and ipk checking +- Add support for deb and ipk packaging +- pkg-diff.sh: check for fifo (named fifo) +- pkg-diff.sh: remove space in the end for ftype +- pkg-diff.sh: check_single_file(): return at once when same +- functions.sh: run rpm once to make it faster + +------------------------------------------------------------------- +Fri Aug 5 13:44:51 UTC 2016 - olaf@aepfle.de + +- Handle unknown ELF files as different. + +------------------------------------------------------------------- +Wed Apr 6 07:06:58 UTC 2016 - olaf@aepfle.de + +- add used utilities to Requires + +------------------------------------------------------------------- +Tue Mar 8 18:00:40 UTC 2016 - olaf@aepfle.de + +- Remove hacks from /var/adm/update-scripts|messages case + +------------------------------------------------------------------- +Tue Mar 8 16:48:48 UTC 2016 - olaf@aepfle.de + +- Handle /var/adm/update-messages in scripts and filelist + +------------------------------------------------------------------- +Mon Mar 7 11:56:28 UTC 2016 - olaf@aepfle.de + +- Whitespace in javadoc case +- Whitespace changes in html case +- Move case kde/gtk html up in the case list +- Move case rdoc html up in the case list +- Add option -a to same-build-result.sh and loop through all rpms +- Rework sorting of rpm files in same-build-result.sh +- Better diagnostic if number of subpackages changes +- Create tmpfiles earlier in same-build-result.sh +- Handle all javadoc html files + +------------------------------------------------------------------- +Fri Mar 4 18:50:32 UTC 2016 - olaf@aepfle.de + +- Handle yet another variant of elc timestamps + +------------------------------------------------------------------- +Thu Mar 3 12:44:04 UTC 2016 - olaf@aepfle.de + +- Handle timestamp in dvi files +- Handle Last-modified HTML META tag +- Handle yet another variant of javadoc timestamps + +------------------------------------------------------------------- +Fri Jan 1 10:11:14 UTC 2016 - schwab@suse.de + +- Fix quoting in find expression + +------------------------------------------------------------------- +Thu Oct 22 06:29:44 UTC 2015 - olaf@aepfle.de + +- Remove filename-too-long-for-joliet from rpmlint.log + +------------------------------------------------------------------- +Mon Oct 12 13:59:31 UTC 2015 - olaf@aepfle.de + +- Filter out durations from rpmlint progress report + +------------------------------------------------------------------- +Fri Oct 2 09:00:52 UTC 2015 - olaf@aepfle.de + +- Handle texi2html 5.0 timestamps + +------------------------------------------------------------------- +Fri Aug 21 12:57:57 UTC 2015 - seife+obs@b1-systems.com + +- avoid -kmp packages with "filename-too-long-for-joliet" + triggering constant republishing + +------------------------------------------------------------------- +Wed Jul 15 09:50:58 UTC 2015 - olaf@aepfle.de + +- 2015.07.15 +- Handle more texi2html generated files and patterns + +------------------------------------------------------------------- +Wed Jun 17 14:25:06 UTC 2015 - olaf@aepfle.de + +- 2015.06.17 +- Fix regex to handle /lib/(modules|firmware)/version-release-any properly + +------------------------------------------------------------------- Tue Apr 28 11:52:12 UTC 2015 - olaf@aepfle.de - 2015.04.28 diff --git a/packaging/build-compare.spec b/packaging/build-compare.spec index fa2ac3c..4b380f2 100644 --- a/packaging/build-compare.spec +++ b/packaging/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: 2015.04.28 +Version: 2023.06.18 Release: 0 Source1: COPYING Source2: same-build-result.sh diff --git a/packaging/functions.sh b/packaging/functions.sh old mode 100644 new mode 100755 index 89057a5..e5af36b --- a/packaging/functions.sh +++ b/packaging/functions.sh @@ -10,61 +10,183 @@ RPM="rpm -qp --nodigest --nosignature" -check_header() -{ - $RPM --qf "$QF" "$1" +declare -a rpm_querytags +collect_rpm_querytags() { + rpm_querytags=( $(rpm --querytags) ) +} +# returns 0 if tag is known, returns 1 if unknown +rpmtag_known() { + local needle="\<${1}\>" + local haystack="${rpm_querytags[@]}" + [[ "${haystack}" =~ ${needle} ]] + return $? } -function is_prerelease_project() { - local proj_name=$1 - if [[ $proj_name =~ "prerelease" ]] || [[ $proj_name =~ "trbs" ]]; then - return 1 - fi +set_rpm_meta_global_variables() { + + local pkg=$1 + local rpm_tags= + local out=`mktemp` + local t v qt + local -a type variant list + +# Name, Version, Release +QF_NAME="%{NAME}" +QF_VER_REL="%{VERSION}-%{RELEASE}" +QF_NAME_VER_REL="%{NAME}-%{VERSION}-%{RELEASE}" + +QF_PROVIDES= +type=( + CONFLICT + OBSOLETE + OLDSUGGESTS + PROVIDE + RECOMMEND + REQUIRE + SUGGEST + SUPPLEMENT +) +variant=( + NAME + FLAGS + VERSION +) +for t in "${type[@]}" +do + unset list + list=() + for v in "${variant[@]}" + do + qt="${t}${v}" + rpmtag_known "${qt}" || continue + list+=("%{${qt}}") + done + QF_PROVIDES+="${t}\\n[${list[@]}\\n]\\n" +done + +# don't look at RELEASE, it contains our build number +QF_TAGS="%{NAME} %{VERSION} %{EPOCH}\\n" +QF_TAGS="${QF_TAGS}%{SUMMARY}\\n%{DESCRIPTION}\\n" +# the DISTURL tag can be used as checkin ID +QF_TAGS="${QF_TAGS}%{VENDOR} %{DISTRIBUTION} %{DISTURL}\\n" +QF_TAGS="${QF_TAGS}%{LICENSE}\\n" +QF_TAGS="${QF_TAGS}%{GROUP} %{URL} %{EXCLUDEARCH} %{EXCLUDEOS} %{EXCLUSIVEARCH}\\n" +QF_TAGS="${QF_TAGS}%{EXCLUSIVEOS} %{RPMVERSION} %{PLATFORM}\\n" +QF_TAGS="${QF_TAGS}%{PAYLOADFORMAT} %{PAYLOADCOMPRESSOR} %{PAYLOADFLAGS}\\n" + +# XXX We also need to check the existence (but not the content (!)) +# of SIGGPG (and perhaps the other SIG*) +# XXX We don't look at triggers +# Only the first ChangeLog entry; should be enough +QF_TAGS="${QF_TAGS}%{CHANGELOGTIME} %{CHANGELOGNAME} %{CHANGELOGTEXT}\\n" + +# scripts, might contain release number +QF_SCRIPT= +type=( + PRETRANS + PREIN + POSTIN + PREUN + POSTUN + POSTTRANS + VERIFYSCRIPT +) +variant=( + PROG + FLAGS + '' +) +for t in "${type[@]}" +do + unset list + list=() + for v in "${variant[@]}" + do + qt="${t}${v}" + rpmtag_known "${qt}" || continue + list+=("%{${qt}}") + done + QF_SCRIPT+="${t}\\n[${list[@]}\\n]\\n" +done - return 0 +# Now the files. We leave out mtime and size. For normal files +# the size will influence the MD5 anyway. For directories the sizes can +# differ, depending on which file system the package was built. To not +# have to filter out directories we simply ignore all sizes. +# Also leave out FILEDEVICES, FILEINODES (depends on the build host), +# FILECOLORS, FILECLASS (normally useful but file output contains mtimes), +# FILEDEPENDSX and FILEDEPENDSN. +# Also FILELANGS (or?) +QF_FILELIST="[%{FILENAMES} %{FILEFLAGS} %{FILESTATES} %{FILEMODES:octal} %{FILEUSERNAME} %{FILEGROUPNAME} %{FILERDEVS} %{FILEVERIFYFLAGS} %{FILELINKTOS}\n]\\n" +# ??? what to do with FILEPROVIDE and FILEREQUIRE? + +QF_CHECKSUM="[%{FILENAMES} %{FILEMD5S} %{FILEFLAGS}\n]\\n" + +QF_SOURCERPM="%{SOURCERPM}\\n" + +QF_ALL="\n___QF_NAME___\n${QF_NAME}\n___QF_NAME___\n" +QF_ALL="$QF_ALL\n___QF_TAGS___\n${QF_TAGS}\n___QF_TAGS___\n" +QF_ALL="$QF_ALL\n___QF_VER_REL___\n${QF_VER_REL}\n___QF_VER_REL___\n" +QF_ALL="$QF_ALL\n___QF_NAME_VER_REL___\n${QF_NAME_VER_REL}\n___QF_NAME_VER_REL___\n" +QF_ALL="$QF_ALL\n___QF_PROVIDES___\n${QF_PROVIDES}\n___QF_PROVIDES___\n" +QF_ALL="$QF_ALL\n___QF_SCRIPT___\n${QF_SCRIPT}\n___QF_SCRIPT___\n" +QF_ALL="$QF_ALL\n___QF_FILELIST___\n${QF_FILELIST}\n___QF_FILELIST___\n" +QF_ALL="$QF_ALL\n___QF_CHECKSUM___\n${QF_CHECKSUM}\n___QF_CHECKSUM___\n" +QF_ALL="$QF_ALL\n___QF_SOURCERPM___\n${QF_SOURCERPM}\n___QF_SOURCERPM___\n" } +check_header() +{ + $RPM --qf "$1" "$2" +} # Trim version-release string: # - it is used as direntry below certain paths # - it is assigned to some variable in scripts, at the end of a line # - it is used in PROVIDES, at the end of a line +# - special-case KMP package: +# PROVIDES version_k.*-release at end of line, trim release +# [ 23s] -acpi_call-kmp-default 8 1.2.2_k5.17.0_rc5_1.ga9b2c1d-6.110 +# [ 23s] +acpi_call-kmp-default 8 1.2.2_k5.17.0_rc5_1.ga9b2c1d-6.111 # Trim name-version-release string: # - it is used in update-scripts which are called by libzypp +# - special-case KMP package: +# [ 64s] PREIN +# [ 64s] /bin/sh (none) /usr/lib/module-init-tools/kernel-scriptlets/kmp-pre --name "acpi_call-kmp-default" \ +# [ 64s] - --version "1.2.2_k5.17.0_rc5_1.ga9b2c1d" --release "6.112" --kernelrelease "5.17.0-rc5-1.ga9b2c1d" \ +# [ 64s] + --version "1.2.2_k5.17.0_rc5_1.ga9b2c1d" --release "6.113" --kernelrelease "5.17.0-rc5-1.ga9b2c1d" \ function trim_release_old() { + local rel_regex_l=${version_release_old_regex_l##*-} sed -e " - /\(\/boot\|\/lib\/modules\|\/lib\/firmware\|\/usr\/src\|$version_release_old_regex_l\$\)/{s,$version_release_old_regex_l,@VERSION@-@RELEASE_LONG@,g;s,$version_release_old_regex_s,@VERSION@-@RELEASE_SHORT@,g} + /\(\/boot\|\/lib\/modules\|\/lib\/firmware\|\/usr\/src\|$version_release_old_regex_l\$\|$version_release_old_regex_l)\)/{s,$version_release_old_regex_l,@VERSION@-@RELEASE_LONG@,g;s,$version_release_old_regex_s,@VERSION@-@RELEASE_SHORT@,g} s/\(\/var\/adm\/update-scripts\/\)${name_ver_rel_old_regex_l}\([^[:blank:]]\+\)/\1@NAME_VER_REL@\2/g + s/\(\/var\/adm\/update-messages\/\)${name_ver_rel_old_regex_l}\([^[:blank:]]\+\)/\1@NAME_VER_REL@\2/g + s/\(^[^[:blank:]].*-kmp-.*[[:blank:]].*_k.*-\)${rel_regex_l}$/\1@RELEASE_LONG@/g + s/--release \"${rel_regex_l}\" --kernel/--release \"@RELEASE_LONG@\" --kernel/g + /\/usr\/lib\/\.build-id/d " } function trim_release_new() { + local rel_regex_l=${version_release_new_regex_l##*-} sed -e " - /\(\/boot\|\/lib\/modules\|\/lib\/firmware\|\/usr\/src\|$version_release_new_regex_l\$\)/{s,$version_release_new_regex_l,@VERSION@-@RELEASE_LONG@,g;s,$version_release_new_regex_s,@VERSION@-@RELEASE_SHORT@,g} + /\(\/boot\|\/lib\/modules\|\/lib\/firmware\|\/usr\/src\|$version_release_new_regex_l\$\|$version_release_new_regex_l)\)/{s,$version_release_new_regex_l,@VERSION@-@RELEASE_LONG@,g;s,$version_release_new_regex_s,@VERSION@-@RELEASE_SHORT@,g} s/\(\/var\/adm\/update-scripts\/\)${name_ver_rel_new_regex_l}\([^[:blank:]]\+\)/\1@NAME_VER_REL@\2/g + s/\(\/var\/adm\/update-messages\/\)${name_ver_rel_new_regex_l}\([^[:blank:]]\+\)/\1@NAME_VER_REL@\2/g + s/\(^[^[:blank:]].*-kmp-.*[[:blank:]].*_k.*-\)${rel_regex_l}$/\1@RELEASE_LONG@/g + s/--release \"${rel_regex_l}\" --kernel/--release \"@RELEASE_LONG@\" --kernel/g + /\/usr\/lib\/\.build-id/d " } # Get single directory or filename with long or short release string function grep_release_old() { - grep -E "(/boot|/lib/modules|/lib/firmware|/usr/src)/[^/]+(${version_release_old_regex_l}(\$|[^/]+\$)|${version_release_old_regex_s}(\$|[^/]+\$))" + grep -E "(/boot|/lib/modules|/lib/firmware|/usr/src|/var/adm/update-scripts)/[^/]*(${version_release_old_regex_l}(\$|[^/]+\$)|${version_release_old_regex_s}(\$|[^/]+\$))" } function grep_release_new() { - grep -E "(/boot|/lib/modules|/lib/firmware|/usr/src)/[^/]+(${version_release_new_regex_l}(\$|[^/]+\$)|${version_release_new_regex_s}(\$|[^/]+\$))" -} - -function check_provides() -{ - local pkg=$1 - # provides destroy this because at least the self-provide includes the - # -buildnumber :-( - QF="[%{PROVIDENAME} %{PROVIDEFLAGS} %{PROVIDEVERSION}\\n]\\n" - QF="$QF [%{REQUIRENAME} %{REQUIREFLAGS} %{REQUIREVERSION}\\n]\\n" - QF="$QF [%{CONFLICTNAME} %{CONFLICTFLAGS} %{CONFLICTVERSION}\\n]\\n" - QF="$QF [%{OBSOLETENAME} %{OBSOLETEFLAGS} %{OBSOLETEVERSION}\\n]\\n" - check_header "$pkg" + grep -E "(/boot|/lib/modules|/lib/firmware|/usr/src|/var/adm/update-scripts)/[^/]*(${version_release_new_regex_l}(\$|[^/]+\$)|${version_release_new_regex_s}(\$|[^/]+\$))" } #usage unpackage $dir @@ -95,177 +217,215 @@ function unpackage() CPIO_OPTS="--extract --unconditional --preserve-modification-time --make-directories --quiet" rpm2cpio $file | cpio ${CPIO_OPTS} ;; + *.ipk|*.deb) + ar x $file + tar xf control.tar.gz + rm control.tar.gz + tar xf data.tar.[xg]z + rm data.tar.[xg]z + ;; esac popd 1>/dev/null } +# Run diff command on the files +# $1: printed info +# $2: file1 +# $3: file2 +# $4, $5: rpm_meta_old and rpm_meta_new, for cleanup. +function comp_file() +{ + echo "comparing $1" + if ! diff --label old-$1 --label new-$1 -au $2 $3; then + if test -z "$check_all"; then + rm $2 $3 $4 $5 + return 1 + fi + difffound=1 + fi + return 0 +} + +# Get var's value from specfile. +# $1: var name +# $2: specfile +function get_value() +{ + sed -n -e "/^___${1}___/,/^___${1}___/p" $2 | sed -e "/^___${1}___/d" +} + +# Set version_release_old_regex_s, version_release_old_regex_l and +# name_ver_rel_old_regex_l, also the new ones. +function set_regex() { + local rel_old=${version_release_old##*-} + local rel_new=${version_release_new##*-} + + # Short version without B_CNT + # release may not contain a dot + case "${rel_old}" in + *.*) + version_release_old_regex_s=${version_release_old%.*} + ;; + *) + version_release_old_regex_s=${version_release_old} + ;; + esac + # Remember to quote the . which is in release + version_release_old_regex_s=${version_release_old_regex_s//./\\.} + # Long version with B_CNT + version_release_old_regex_l=${version_release_old//./\\.} + name_ver_rel_old_regex_l=${name_ver_rel_old//./\\.} + + case "${rel_new}" in + *.*) + version_release_new_regex_s=${version_release_new%.*} + ;; + *) + version_release_new_regex_s=${version_release_new} + ;; + esac + version_release_new_regex_s=${version_release_new_regex_s//./\\.} + version_release_new_regex_l=${version_release_new//./\\.} + name_ver_rel_new_regex_l=${name_ver_rel_new//./\\.} +} + +# Trim a block starting with a keyword and ending with an empty line +# $1: enable +# $2: keyword +function trim_section() { + if test "${1}" -gt 0 ; then + sed -e "/^${2}$/,/^$/d" + else + cat + fi +} + # Compare just the rpm meta data of two rpms # Returns: # 0 in case of same content # 1 in case of errors or difference # 2 in case of differences that need further investigation -# Sets $files with list of files that need further investigation -function cmp_spec () +# Sets ${files[@]} array with list of files that need further investigation +function cmp_rpm_meta () { local RES - local file1 file2 local f local sh=$1 local oldrpm=$2 local newrpm=$3 + local tmpdir="$(mktemp -d)" + local file1="$tmpdir/file1" + local file2="$tmpdir/file2" + local rpm_meta_old="$tmpdir/rpm-meta-old" + local rpm_meta_new="$tmpdir/rpm-meta-new" - QF="%{NAME}" - - # don't look at RELEASE, it contains our build number - QF="$QF %{VERSION} %{EPOCH}\\n" - QF="$QF %{SUMMARY}\\n%{DESCRIPTION}\\n" - QF="$QF %{VENDOR}\\n" - QF="$QF %{LICENSE} %{LICENSE}\\n" - QF="$QF %{GROUP} %{URL} %{EXCLUDEARCH} %{EXCLUDEOS} %{EXCLUSIVEARCH}\\n" - QF="$QF %{EXCLUSIVEOS} %{RPMVERSION} %{PLATFORM}\\n" - QF="$QF %{PAYLOADFORMAT} %{PAYLOADCOMPRESSOR} %{PAYLOADFLAGS}\\n" - - - # XXX We also need to check the existence (but not the content (!)) - # of SIGGPG (and perhaps the other SIG*) - - # XXX We don't look at triggers - - QF="$QF [%{VERIFYSCRIPTPROG} %{VERIFYSCRIPT}]\\n" - - # Only the first ChangeLog entry; should be enough - QF="$QF %{CHANGELOGTIME} %{CHANGELOGNAME} %{CHANGELOGTEXT}\\n" - - file1=`mktemp` - file2=`mktemp` - - check_header $oldrpm > $file1 - check_header $newrpm > $file2 - - if [ -n $newrpm ]; then - # if the rpm is from prerelease projects, do not compare project name. - QF="%{DISTRIBUTION}" - dist=$(check_header $newrpm | sed -r 's/(.*)\/.*/\1/') - if ! is_prerelease_project $dist; then - echo "This is a prerelease project. Do not compare the project name." - QF="%{DISTURL}\\n" - echo `check_header $oldrpm | sed -r 's/.*\/(.*\/.*)/\1/'` >> $file1 - echo `check_header $newrpm | sed -r 's/.*\/(.*\/.*)/\1/'` >> $file2 - else - QF="%{DISTURL} %{DISTRIBUTION}\\n" - echo "This is not a prerelease project. Compare the project name." - check_header $oldrpm >> $file1 - check_header $newrpm >> $file2 - fi + collect_rpm_querytags + set_rpm_meta_global_variables $oldrpm + + check_header "$QF_ALL" $oldrpm > $rpm_meta_old + check_header "$QF_ALL" $newrpm > $rpm_meta_new + + # rpm returns 0 even in case of error + if test -s $rpm_meta_old && test -s $rpm_meta_new ; then + : some output provided, all query tags understood by rpm + else + ls -l $rpm_meta_old $rpm_meta_new + echo "empty 'rpm -qp' output..." + rm -rf "$tmpdir" + return 1 fi - - # the DISTURL tag can be used as checkin ID - #echo "$QF" - echo "comparing rpmtags" - if ! diff -au $file1 $file2; then - if test -z "$check_all"; then - rm $file1 $file2 - return 1 - fi + + name_new="$(get_value QF_NAME $rpm_meta_new)" + version_release_new="$(get_value QF_VER_REL $rpm_meta_new)" + name_ver_rel_new="$(get_value QF_NAME_VER_REL $rpm_meta_new)" + + version_release_old="$(get_value QF_VER_REL $rpm_meta_old)" + name_ver_rel_old="$(get_value QF_NAME_VER_REL $rpm_meta_old)" + + set_regex + + # Check the whole spec file at first, return 0 immediately if they + # are the same. + trim_release_old < $rpm_meta_old > $file1 + trim_release_new < $rpm_meta_new > $file2 + echo "comparing the rpm tags of $name_new" + if diff --speed-large-files --label old-rpm-tags --label new-rpm-tags -au0 $file1 $file2; then + rm -rf "$tmpdir" + return 0 fi - - # Remember to quote the . which is in release - version_release_old=$($RPM --qf "%{VERSION}-%{RELEASE}" "$oldrpm") - version_release_new=$($RPM --qf "%{VERSION}-%{RELEASE}" "$newrpm") - name_ver_rel_old=$($RPM --qf "%{NAME}-%{VERSION}-%{RELEASE}" "$oldrpm") - name_ver_rel_new=$($RPM --qf "%{NAME}-%{VERSION}-%{RELEASE}" "$newrpm") - # Short version without B_CNT - version_release_old_regex_s=${version_release_old%.*} - version_release_old_regex_s=${version_release_old_regex_s//./\\.} - version_release_new_regex_s=${version_release_new%.*} - version_release_new_regex_s=${version_release_new_regex_s//./\\.} - # Long version with B_CNT - version_release_old_regex_l=${version_release_old//./\\.} - version_release_new_regex_l=${version_release_new//./\\.} - name_ver_rel_old_regex_l=${name_ver_rel_old//./\\.} - name_ver_rel_new_regex_l=${name_ver_rel_new//./\\.} + + get_value QF_TAGS $rpm_meta_old > $file1 + get_value QF_TAGS $rpm_meta_new > $file2 + if ! comp_file rpmtags $file1 $file2 $rpm_meta_old $rpm_meta_new; then + rm -rf "$tmpdir" + return 1 + fi + # This might happen when?! echo "comparing RELEASE" if [ "${version_release_old%.*}" != "${version_release_new%.*}" ] ; then - case $($RPM --qf '%{NAME}' "$newrpm") in + case $name_new in kernel-*) # Make sure all kernel packages have the same %RELEASE echo "release prefix mismatch" if test -z "$check_all"; then + rm -rf "$tmpdir" return 1 fi + difffound=1 ;; # Every other package is allowed to have a different RELEASE *) ;; esac fi - - check_provides $oldrpm | trim_release_old | sort > $file1 - check_provides $newrpm | trim_release_new | sort > $file2 - - echo "comparing PROVIDES" - if ! diff -au $file1 $file2; then - if test -z "$check_all"; then - rm $file1 $file2 - return 1 - fi - fi - # scripts, might contain release number - QF="[%{PREINPROG} %{PREIN}\\n]\\n[%{POSTINPROG} %{POSTIN}\\n]\\n[%{PREUNPROG} %{PREUN}\\n]\\n[%{POSTUNPROG} %{POSTUN}\\n]\\n" - check_header $oldrpm | trim_release_old > $file1 - check_header $newrpm | trim_release_new > $file2 + # Built packages provide the sourcerpm, for the sourcerpm itself it is "(none)" + [ "x$(get_value QF_SOURCERPM $rpm_meta_new)" == "x(none)" ] && is_sourcerpm=1 || is_sourcerpm=0 - echo "comparing scripts" - if ! diff -au $file1 $file2; then - if test -z "$check_all"; then - rm $file1 $file2 - return 1 - fi + # FIXME: PROVIDE needs to be handled independent from the other tags + get_value QF_PROVIDES $rpm_meta_old | trim_section ${is_sourcerpm} 'PROVIDE' | trim_release_old | sort > $file1 + get_value QF_PROVIDES $rpm_meta_new | trim_section ${is_sourcerpm} 'PROVIDE' | trim_release_new | sort > $file2 + if ! comp_file PROVIDES $file1 $file2 $rpm_meta_old $rpm_meta_new; then + rm -rf "$tmpdir" + return 1 fi - + + get_value QF_SCRIPT $rpm_meta_old | trim_release_old > $file1 + get_value QF_SCRIPT $rpm_meta_new | trim_release_new > $file2 + if ! comp_file scripts $file1 $file2 $rpm_meta_old $rpm_meta_new; then + rm -rf "$tmpdir" + return 1 + fi + # First check the file attributes and later the md5s - - # Now the files. We leave out mtime and size. For normal files - # the size will influence the MD5 anyway. For directories the sizes can - # differ, depending on which file system the package was built. To not - # have to filter out directories we simply ignore all sizes. - # Also leave out FILEDEVICES, FILEINODES (depends on the build host), - # FILECOLORS, FILECLASS (normally useful but file output contains mtimes), - # FILEDEPENDSX and FILEDEPENDSN. - # Also FILELANGS (or?) - QF="[%{FILENAMES} %{FILEFLAGS} %{FILESTATES} %{FILEMODES:octal} %{FILEUSERNAME} %{FILEGROUPNAME} %{FILERDEVS} %{FILEVERIFYFLAGS} %{FILELINKTOS}\n]\\n" - # ??? what to do with FILEPROVIDE and FILEREQUIRE? - - check_header $oldrpm | trim_release_old > $file1 - check_header $newrpm | trim_release_new > $file2 - - echo "comparing filelist" - if ! diff -au $file1 $file2; then - if test -z "$check_all"; then - rm $file1 $file2 - return 1 - fi + get_value QF_FILELIST $rpm_meta_old | trim_release_old > $file1 + get_value QF_FILELIST $rpm_meta_new | trim_release_new > $file2 + if ! comp_file filelist $file1 $file2 $rpm_meta_old $rpm_meta_new; then + rm -rf "$tmpdir" + return 1 fi - + # now the md5sums. if they are different, we check more detailed # if there are different filenames, we will already have aborted before # file flag 64 means "ghost", filter those out. - QF="[%{FILENAMES} %{FILEMD5S} %{FILEFLAGS}\n]\\n" - check_header $oldrpm |grep -v " 64$"| trim_release_old > $file1 - check_header $newrpm |grep -v " 64$"| trim_release_new > $file2 - + get_value QF_CHECKSUM $rpm_meta_old | grep -v " 64$" | trim_release_old > $file1 + get_value QF_CHECKSUM $rpm_meta_new | grep -v " 64$" | trim_release_new > $file2 RES=2 # done if the same + files=() echo "comparing file checksum" if cmp -s $file1 $file2; then RES=0 + else + # Get only files with different MD5sums + while read + do + : "${REPLY}" + files+=( "${REPLY}" ) + done < <(diff -U0 $file1 $file2 | sed --regexp-extended -n -e '/^\+\//{s/^\+//;s/ [0-9a-f]+ [0-9]+$//;p}') fi - - # Get only files with different MD5sums - files=`diff -U0 $file1 $file2 | fgrep -v +++ | grep ^+ | cut -b2- | awk '{print $1}'` - if test -f "$sh"; then + if test -n "$sh"; then echo "creating rename script" # Create a temporary helper script to rename files/dirs with release in it for f in `$RPM --qf '[%{FILENAMES} %{FILEFLAGS}\n]\n' "$oldrpm" | grep_release_old | grep -vw 64$ | awk '{ print $1}'` @@ -278,8 +438,23 @@ function cmp_spec () echo mv -v \"new/${f}\" \"new/`echo ${f} | trim_release_new`\" done >> "${sh}" fi - # - rm $file1 $file2 + + rm -rf "$tmpdir" + [ "$difffound" = 1 ] && RES=1 return $RES } + +function adjust_controlfile() { + version_release_old="`sed -ne 's/^Version: \(.*\)/\1/p' $1/control`" + name_ver_rel_old="`sed -n -e 's/^Package: \(.*\)/\1/p' $1/control`-`sed -n -e 's/^Version: \(.*\)/\1/p' $1/control`" + version_release_new="`sed -ne 's/^Version: \(.*\)/\1/p' $2/control`" + name_ver_rel_new="`sed -n -e 's/^Package: \(.*\)/\1/p' $2/control`-`sed -n -e 's/^Version: \(.*\)/\1/p' $2/control`" + set_regex + trim_release_old < $1/control > $1/control.fixed + mv $1/control.fixed $1/control + trim_release_new < $2/control > $2/control.fixed + mv $2/control.fixed $2/control +} + + # vim: tw=666 ts=2 shiftwidth=2 et diff --git a/packaging/pkg-diff.sh b/packaging/pkg-diff.sh old mode 100644 new mode 100755 index 1ac4190..13d1e5f --- a/packaging/pkg-diff.sh +++ b/packaging/pkg-diff.sh @@ -5,188 +5,253 @@ # # Written by Michael Matz and Stephan Coolo # Enhanced by Andreas Jaeger +declare -i watchdog_host_timeout_seconds='3600' +declare -i watchdog_touch_percent_prior_timeout='25' +declare -i watchdog_next_touch_seconds=0 -FUNCTIONS=${0%/*}/functions.sh - -check_all= -case $1 in - -a | --check-all) - check_all=1 - shift -esac - -if test "$#" != 2; then - echo "usage: $0 [-a|--check-all] old.rpm new.rpm" - exit 1 -fi - -# Always clean up on exit -local_tmpdir=`mktemp -d` -if test -z "${local_tmpdir}" -then - exit 1 -fi -function _exit() +function watchdog_reset { - chmod -R u+w "${local_tmpdir}" - rm -rf "${local_tmpdir}" -} -trap _exit EXIT -# Let further mktemp refer to private tmpdir -export TMPDIR=$local_tmpdir + local uptime idle + local -i next_touch now -self_script=$(cd $(dirname $0); echo $(pwd)/$(basename $0)) + read uptime idle < /proc/uptime -source $FUNCTIONS + now="${uptime%.*}" + next_touch=$(( ${now} + ( (${watchdog_host_timeout_seconds} * ${watchdog_touch_percent_prior_timeout}) / 100 ) )) + watchdog_next_touch_seconds=${next_touch} +} -oldpkg=`readlink -f $1` -newpkg=`readlink -f $2` -rename_script=`mktemp` +function watchdog_touch +{ + local uptime idle + local -i next_touch now -if test ! -f "$oldpkg"; then - echo "can't open $1" - exit 1 -fi + read uptime idle < /proc/uptime -if test ! -f "$newpkg"; then - echo "can't open $2" - exit 1 -fi + now="${uptime%.*}" + if test "${now}" -lt "${watchdog_next_touch_seconds}" + then + return + fi + echo 'build-compare touching host-watchdog.' + watchdog_reset +} -#usage unjar -function unjar() +function wprint { - local file - file=$1 - - 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 - - case $UNJAR in - jar|fastjar) - # echo jar -xf $file - ${UNJAR} -xf $file - ;; - unzip) - unzip -oqq $file - ;; - esac + echo "$@" + watchdog_reset } -# list files in directory -#usage unjar_l -function unjar_l() +filter_disasm() { - local file - file=$1 - - 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 + [[ $nofilter ]] && return + sed -e ' + s/^ *[0-9a-f]\+:// + s/\$0x[0-9a-f]\+/$something/ + s/callq *[0-9a-f]\+/callq / + s/# *[0-9a-f]\+/# / + s/\(0x\)\?[0-9a-f]\+(/offset(/ + s/[0-9a-f]\+ :/\1:/ + s/<\(.*\)+0x[0-9a-f]\+>/<\1 + ofs>/ + ' +} - case $UNJAR in - jar|fastjar) - ${UNJAR} -tf $file - ;; - unzip) - unzip -l $file - ;; - esac +filter_xenefi() { + # PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows + perl -e "open fh, '+<', '$f'; seek fh, 0x80 + 0x08, SEEK_SET; print fh 'time'; seek fh, 0x80 + 0x58, SEEK_SET; print fh 'chck';" } -filter_disasm() -{ - sed -e 's/^ *[0-9a-f]\+://' -e 's/\$0x[0-9a-f]\+/$something/' -e 's/callq *[0-9a-f]\+/callq /' -e 's/# *[0-9a-f]\+/# /' -e 's/\(0x\)\?[0-9a-f]\+(/offset(/' -e 's/[0-9a-f]\+ :/\1:/' -e 's/<\(.*\)+0x[0-9a-f]\+>/<\1 + ofs>/' +filter_pyc() { + perl -e ' + my $ts_off = 4; + my $f = shift; + open fh, "+<", $f; + my $data; + die "Unexpected EOF while reading $f" if read(fh, $data, 2) < 2; + my $magic1 = unpack "v", $data; + die "Unexpected EOF while reading $f" if read(fh, $data, 2) < 2; + my $magic2 = unpack "v", $data; + die "File $f is not a compiled Python module" if $magic2 != 0x0a0d; + if ($magic1 >= 3392 && $magic1 < 20000) { + $ts_off += 4; + die "Unexpected EOF while reading $f" if read(fh, $data, 4) < 4; + my $flags = unpack "V", $data; + $ts_off += 8 if $flags & 0x1; + } + seek fh, $ts_off, SEEK_SET; + print fh "0000"; + close fh; + ' "$f" } -echo "Comparing `basename $oldpkg` to `basename $newpkg`" +filter_dvi() { + # Opcodes 247: pre; i[1], num[4], den[4], mag[4], k[1], x[k] + perl -e " + my \$rec; + open fh, '+<', '$f'; + my \$dummy = read fh, \$rec, 15; + (\$pre, \$i, \$num, \$den, \$mag, \$k) = unpack('C2 N3 C', \$rec); + seek fh, 15, SEEK_SET; + while (\$k > 0) { + print fh '0'; + \$k--; + } + " +} -case $oldpkg in - *.rpm) - cmp_spec $rename_script $oldpkg $newpkg - RES=$? - case $RES in - 0) - echo "RPM meta information is identical" - if test -z "$check_all"; then - exit 0 - fi - ;; - 1) - echo "RPM meta information is different" - if test -z "$check_all"; then - exit 1 - fi - ;; - 2) - echo "RPM file checksum differs." - RES=0 - ;; - *) - echo "Wrong exit code!" - exit 1 - ;; - esac - ;; -esac +filter_png() { + perl -e ' + use strict; + use warnings; + my $a, my $b, my $c, my $d, my $f; + open ($f, "+<", shift); + $d = read($f, $c, 8); + ($a,$b) = unpack("N2", $c); + unless($a == 0x89504e47 && $b == 0x0d0a1a0a) { + die("bogus png file."); + } + sub fn { + my ($fd, $l) = @_; + my $d = sprintf("%d", $l + 4); + $d = pack("a$d", ""); + print($fd $d); + } + for ($d = read($f, $c, 8); $d > 0; $d = read($f, $c, 8)) { + ($a,$b) = unpack("N a4", $c); + if ($b eq "tIME") { + fn($f, $a); + } elsif ($b eq "tEXt") { + $d = read($f, $c, $a); + $b = unpack("Z$a", $c); + if ($b eq "date:create" || $b eq "date:modify") { + $d = seek($f, -$a, 1); + fn($f, $a); + } + } else { + $d = seek($f, $a + 4, 1); + } + } + close($f); + ' "$f" +} -file1=`mktemp` -file2=`mktemp` +filter_emacs_lisp() { + sed -i -e ' + s|^;;; .ompiled by abuild@.* on ... ... .. ..:..:.. ....|;;; compiled by abuild@buildhost on Wed Jul 01 00:00:00 2009| + s|^;;; from file .*\.el|;;; from file /home/abuild/rpmbuild/BUILD/anthy-9100h/src-util/elc.8411/anthy-azik.el| + s|^;;; emacs version .*|;;; emacs version 21.5 (beta34) "kale" XEmacs Lucid.| + s|^;;; bytecomp version .*|;;; bytecomp version 2.28 XEmacs; 2009-08-09.| + ' "$f" +} -dir=`mktemp -d` -echo "Extracting packages" -unpackage $oldpkg $dir/old -unpackage $newpkg $dir/new +filter_pdf() { + # PDF files contain a unique ID, remove it + # Format of the ID is: + # /ID [<9ACE247A70CF9BEAFEE15E116259BD6D> <9ACE247A70CF9BEAFEE15E116259BD6D>] + # with optional spaces. pdftex creates also: + # /CreationDate (D:20120103083206Z) + # /ModDate (D:20120103083206Z) + # and possibly XML metadata as well + sed -i \ + '/obj/,/endobj/{ + s%/ID \?\[ \?<[^>]\+> \?<[^>]\+> \?\]%/IDrandom%g; + s%/CreationDate \?(D:[^)]*)%/CreationDate (D: XXX)%g; + s%/ModDate \?(D:[^)]*)%/ModDate (D: XXX)%g; + s%[^<]*%XXX%g; + s%[^<]*%XXX%g; + s%[^<]*%XXX%g; + s%[^<]*%XXX%g; + s%[^<]*%XXX%g; + }' "$f" +} -# files is set in cmp_spec for rpms, so if RES is empty we should assume -# it wasn't an rpm and pick all files for comparison. -if [ -z $RES ]; then - oldfiles=`cd $dir/old; find . -type f` - newfiles=`cd $dir/new; find . -type f` +filter_ps() { + sed -i -e ' + /^%%CreationDate:[[:blank:]]/d + /^%%Creator:[[:blank:]]groff[[:blank:]]version[[:blank:]]/d + /^%DVIPSSource:[[:blank:]]/d + ' "$f" +} - files=`echo -e "$oldfiles\n$newfiles" | sort -u` -fi +filter_mo() { + sed -i -e "s,POT-Creation-Date: ....-..-.. ..:..+....,POT-Creation-Date: 1970-01-01 00:00+0000," "$f" +} -cd $dir -bash $rename_script +filter_linuxrc_config() { + sed -i '/^InitrdID:/s@^.*@InitrdID: something@' "$f" +} -dfile=`mktemp` +# call specified filter on old and new file +filter_generic() +{ + filtertype=$1 + [[ $nofilter ]] && return + local f + for f in "old/$file" "new/$file" ; do + eval "filter_$filtertype $f" + done +} -diff_two_files() +# returns 0 if both files are identical +# returns 1 if files differ or one is missing +# returns 2 if files must be processed further +verify_before_processing() { - if test ! -e old/$file; then - echo "Missing in old package: $file" + local file="$1" + local cmpout="$2" + + if test ! -e "old/$file"; then + wprint "Missing in old package: $file" return 1 fi - if test ! -e new/$file; then - echo "Missing in new package: $file" + if test ! -e "new/$file"; then + wprint "Missing in new package: $file" return 1 fi - if cmp -s old/$file new/$file; then + # consider only files and symlinks + if test ! -f "old/$file"; then + return 0 + fi + if test ! -f "new/$file"; then return 0 fi - echo "$file differs ($ftype)" - hexdump -C old/$file > $file1 & - hexdump -C new/$file > $file2 & - wait - diff -u $file1 $file2 | head -n 200 + if cmp -b "old/$file" "new/$file" > "${cmpout}" ; then + return 0 + fi + + if test -s "${cmpout}" ; then + # cmp produced output for futher processing + return 2 + fi + + # cmp failed + return 1 +} + +diff_two_files() +{ + local offset length + + verify_before_processing "${file}" "${dfile}" + case "$?" in + 0) return 0 ;; + 1) return 1 ;; + *) ;; + esac + + offset=`sed 's@^.*differ: byte @@;s@,.*@@' < $dfile` + wprint "$file differs at offset '$offset' ($ftype)" + offset=$(( ($offset >> 6) << 6 )) + length=512 + diff -u \ + --label "old $file (hex)" \ + --label "new $file (hex)" \ + <( hexdump -C -s $offset -n $length "old/$file" ) \ + <( hexdump -C -s $offset -n $length "new/$file" ) | $buildcompare_head return 1 } @@ -194,10 +259,12 @@ trim_man_first_line() { # Handles the first line if it is like: #.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28) + #.\" Automatically generated by Pandoc 2.9.2.1 #.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.43.3. local f=$1 + [[ $nofilter ]] && return sed -i -e '1{ - s|^\.\\"[[:blank:]]\+Automatically[[:blank:]]generated[[:blank:]]by[[:blank:]]Pod::Man[[:blank:]].*|.\\" Overly verbose Pod::Man| + s|^\.\\"[[:blank:]]\+Automatically[[:blank:]]generated[[:blank:]]by[[:blank:]].*|.\\" Automatically generated by SomeTool| s|^\.\\"[[:blank:]]\+DO[[:blank:]]NOT[[:blank:]]MODIFY[[:blank:]]THIS[[:blank:]]FILE![[:blank:]]\+It[[:blank:]]was[[:blank:]]generated[[:blank:]]by[[:blank:]]help2man[[:blank:]].*|.\\" Overly verbose help2man| }' $f } @@ -222,10 +289,7 @@ trim_man_TH() # .TH "GCM-CALIBRATE" "1" "03 February 2012" "" "" #.TH Locale::Po4a::Xml.pm 3pm "2015-01-30" "Po4a Tools" "Po4a Tools" local f=$1 - - #.TH dos2unix 1 "2016-08-30" "dos2unix" "2016-08-30" - sed -i -e 's|\(\.TH dos2unix.*\)"[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}"\(.*\)"[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}"|\1"uuu2000-05-05"\2"uuu2000-05-05"|g' $f - + [[ $nofilter ]] && return # (.TH quoted section) (quoted_date)(*) sed -i -e 's|^\([[:blank:]]*\.TH[[:blank:]]\+"[^"]\+"[[:blank:]]\+[^[:blank:]]\+\)[[:blank:]]\+\("[^"]\+"\)\([[:blank:]]\+.*\)\?|\1 "qq2000-01-01"\3|' $f # (.TH unquoted section) (quoted_date)(*) @@ -239,13 +303,33 @@ trim_man_TH() strip_numbered_anchors() { # Remove numbered anchors on Docbook / HTML files. - # This should be save since we remove them from old and new files. - # A trailing or tag will stay also on both files. + # + # + # + # 1 TeX + # + # + #
+ #
+ + [[ $nofilter ]] && return for f in old/$file new/$file; do - sed -i -e 's%<[ ]*a[ ]\+name[^<]*[0-9]\+[^<]*%%g' \ - -e 's%<[ ]*a[ ]\+href[^<]*#[^<]*[0-9]\+[^<]*%%g' \ - -e 's%<[^<]*id="ftn\.[^<]*[0-9]\+[^<]*%%g' $f + sed -ie ' + 1 { + : N + $ { + s@\(]\+id=\n\?"\)\(id[a-z0-9]\+\)\("[^>]*>\)@\1a_idN\3@g + s@\(]\+name=\n\?"\)\(id[a-z0-9]\+\)\("[^>]*>\)@\1a_nameN\3@g + s@\(]\+href="#\)\([^"]\+\)\("[^>]*>\)@\1href_anchor\3@g + s@\(]\+href="[^#]\+#\)\([^"]\+\)\("[^>]*>\)@\1href_anchor\3@g + s@\(]\+id="\)\([\.a-z0-9]\+\)\("[^>]*>\)@\1div_idN\3@g + } + N + b N + }' $f & done + wait } @@ -256,7 +340,7 @@ check_compressed_file() local tmpdir=`mktemp -d` local ftype local ret=0 - echo "$ext file with odd filename: $file" + wprint "$ext file with odd filename: $file" if test -n "$tmpdir"; then mkdir $tmpdir/{old,new} cp --parents --dereference old/$file $tmpdir/ @@ -284,11 +368,18 @@ check_compressed_file() xz -d new/$file.xz & wait ;; + zst) + mv old/$file{,.zst} + mv new/$file{,.zst} + zstd -d old/$file.zst & + zstd -d new/$file.zst & + wait + ;; esac ftype=`/usr/bin/file old/$file | sed 's@^[^:]\+:[[:blank:]]*@@'` case $ftype in POSIX\ tar\ archive) - echo "$ext content is: $ftype" + wprint "$ext content is: $ftype" mv old/$file{,.tar} mv new/$file{,.tar} if ! check_single_file ${file}.tar; then @@ -296,15 +387,21 @@ check_compressed_file() fi ;; ASCII\ cpio\ archive\ *) - echo "$ext content is: $ftype" + wprint "$ext content is: $ftype" mv old/$file{,.cpio} mv new/$file{,.cpio} if ! check_single_file ${file}.cpio; then ret=1 fi ;; + fifo*pipe*) + ftype_new="`/usr/bin/file new/$file | sed -e 's@^[^:]\+:[[:blank:]]*@@' -e 's@[[:blank:]]*$@@'`" + if [ "$ftype_new" != "$ftype" ]; then + ret=1 + fi + ;; *) - echo "unhandled $ext content: $ftype" + wprint "unhandled $ext content: $ftype" if ! diff_two_files; then ret=1 fi @@ -317,485 +414,853 @@ check_compressed_file() return $ret } -check_single_file() +# returns 0 if file should be skipped +file_is_on_ignorelist() { local file="$1" - case $file in + local ret=0 + + case "${file}" in + # Just debug information, we can skip them + *.exe.mdb|*.dll.mdb) ;; + + # binary dump of TeX and Metafont formats, we can ignore them for good + /var/lib/texmf/web2c/*/*fmt|\ + /var/lib/texmf/web2c/metafont/*.base|\ + /var/lib/texmf/web2c/metapost/*.mem) ;; + + # ruby documentation, file just contains a timestamp and nothing else + */created.rid) ;; + + # R binary cache of DESCRIPTION + /usr/lib*/R/library/*/Meta/package.rds) ;; + + # binary cache of interpreted R code + /usr/lib*/R/library/*/R/*.rd[bx]) ;; + + # LibreOffice log file + /usr/lib/libreoffice/solver/inc/*/deliver.log) ;; + + # packaged by libguestfs + */ld.so.cache|*/etc/machine-id) ;; + + # everything else will be processed + *) ret=1 ;; + esac + + return ${ret} +} + +# void +normalize_file() +{ + local file="$1" + local f + + case "$file" in *.spec) - sed -i -e "s,Release:.*$release1,Release: @RELEASE@," old/$file - sed -i -e "s,Release:.*$release2,Release: @RELEASE@," new/$file - ;; - *.exe.mdb|*.dll.mdb) - # Just debug information, we can skip them - echo "$file skipped as debug file." - return 0 - ;; - *.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 - done - return 0 - ;; - *.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 - local ret=0 - for f in $flist; do - if ! check_single_file $fdir/$f; then - ret=1 - if test -z "$check_all"; then - break - fi - fi - done - rm -rf old/$fdir new/$fdir - return $ret - ;; - *.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" - local ret=0 - for f in $flist; do - if ! check_single_file $fdir/$f; then - ret=1 - if test -z "$check_all"; then - break - fi - fi - done - rm -rf old/$fdir new/$fdir - return $ret - ;; - *.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 - local ret=0 - for f in $flist; do - if ! check_single_file $fdir/$f; then - ret=1 - if test -z "$check_all"; then - break - fi - fi - done - return $ret - ;; - *.zip|*.jar|*.war) - cd old - unjar_l ./$file |sort > flist - # 10-05-2010 14:39 - sed -i -e "s, [0-9][0-9]-[0-9][0-9]-[0-9]\+ [0-9][0-9]:[0-9][0-9] , date ," flist - # 2012-02-03 07:59 - sed -i -e "s, 20[0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9] , date ," flist - cd ../new - unjar_l ./$file |sort> flist - sed -i -e "s, [0-9][0-9]-[0-9][0-9]-[0-9]\+ [0-9][0-9]:[0-9][0-9] , date ,; " flist - sed -i -e "s, 20[0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9] , date ," flist - cd .. - if ! cmp -s old/flist new/flist; then - echo "$file has different file list" - diff -u old/flist new/flist - return 1 - fi - flist=`grep date new/flist | sed -e 's,.* date ,,'` - pwd=$PWD - fdir=`dirname $file` - cd old/$fdir - unjar `basename $file` - cd $pwd/new/$fdir - unjar `basename $file` - cd $pwd - local ret=0 - 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 - done - return $ret;; - *.pyc|*.pyo) - perl -e "open fh, '+<', 'old/$file'; seek fh, 4, SEEK_SET; print fh '0000';" - perl -e "open fh, '+<', 'new/$file'; seek fh, 4, SEEK_SET; print fh '0000';" - ;; - *.bz2) - bunzip2 -c old/$file > old/${file/.bz2/} - bunzip2 -c new/$file > new/${file/.bz2/} - check_single_file ${file/.bz2/} - return $? - ;; - *.gz) - gunzip -c old/$file > old/${file/.gz/} - gunzip -c new/$file > new/${file/.gz/} - check_single_file ${file/.gz/} - return $? - ;; - *.rpm) - $self_script -a old/$file new/$file - return $? - ;; - *png) - # Try to remove timestamps, only if convert from ImageMagick is installed - if [[ $(type -p convert) ]]; then - convert old/$file +set date:create +set date:modify old/${file}.$PPID.$$ - convert new/$file +set date:create +set date:modify new/${file}.$PPID.$$ - mv -f old/${file}.$PPID.$$ old/${file} - mv -f new/${file}.$PPID.$$ new/${file} - if ! diff_two_files; then - return 1 - fi - return 0 - fi - ;; - /usr/share/locale/*/LC_MESSAGES/*.mo|/usr/share/locale-bundle/*/LC_MESSAGES/*.mo) - for f in old/$file new/$file; do - sed -i -e "s,POT-Creation-Date: ....-..-.. ..:..+....,POT-Creation-Date: 1970-01-01 00:00+0000," $f - done - ;; - /usr/share/doc/packages/*/*.html|\ - /usr/share/doc/kde/HTML/*/*/*.html|/usr/share/doc/*/html/*.html) - for f in old/$file new/$file; do - # texi2html output, e.g. in kvm, indent, qemu - sed -i -e "s|^ - # - # - # - sed -i -e ' - /^/{ - : next - n - /^<\/head>/{ - b end_head - } - s/^\(\)/\1 some-date-removed-by-build-compare \5/ - t next - s/^\(\)/\1 some-date-removed-by-build-compare \3/ - t next - s/^// - b next + sed -i -e "s,Release:.*$release1,Release: @RELEASE@," "old/$file" + sed -i -e "s,Release:.*$release2,Release: @RELEASE@," "new/$file" + ;; + */xen*.efi) + filter_generic xenefi + ;; + *.pyc|*.pyo) + filter_generic pyc + ;; + *.dvi) + filter_generic dvi + ;; + *.png) + filter_generic png + ;; + /usr/share/locale/*/LC_MESSAGES/*.mo|\ + /usr/share/locale-bundle/*/LC_MESSAGES/*.mo|\ + /usr/share/vdr/locale/*/LC_MESSAGES/*.mo) + filter_generic mo + ;; + */rdoc/files/*.html) + # ruby documentation + # Mon Sep 20 19:02:43 +0000 2010 + for f in old/$file new/$file; do + sed -i -e 's%[A-Z][a-z][a-z] [A-Z][a-z][a-z] [0-9]\+ [0-9]\+:[0-9]\+:[0-9]\+ +0000 201[0-9]%Mon Sep 20 19:02:43 +0000 2010%g' $f + done + strip_numbered_anchors + ;; + /usr/share/doc/HTML/*/*/index.cache|\ + /usr/share/doc//HTML/*/*/*/index.cache|\ + /usr/share/doc/kde/HTML/*/*/index.cache|\ + /usr/share/doc/kde/HTML/*/*/*/index.cache|\ + /usr/share/gtk-doc/html/*/*.html|\ + /usr/share/gtk-doc/html/*/*.devhelp2) + # various kde and gtk packages + strip_numbered_anchors + for f in old/$file new/$file; do + sed -i -e ' + /^/{ + : next + n + /^<\/head>/{ + b end_head } - : end_head + s/^// + b next + } + : end_head ' $f - # Gjdoc HtmlDoclet: - sed -i -e 's%Generated by Gjdoc HtmlDoclet [0-9,.]*, part of GNU Classpath Tools, on .*, 20.. [0-9]*:..:.. \(a\|p\)\.m\. GMT.%Generated by Gjdoc.%' $f - sed -i -e 's%, on [A-Z][a-z]* [0-9]*, 20?? [0-9]*:??:?? \(a|p\)\.m\. GMT.

%, on January 1, 2009 0:00:00 a.m. GMT.

%' $f - sed -i -e 's%\), on [a-zA-Z]* [0-9][0-9], 20.. [0-9]*:..:.. \(a\|p\)\.m\. GMT.

%%' $f - # deprecated-list is randomly ordered, sort it for comparison - case $f in - */deprecated-list.html) - sort -o $f $f - ;; - esac - done - ;; - /usr/share/javadoc/gjdoc.properties |\ - /usr/share/javadoc/*/gjdoc.properties) - for f in old/$file new/$file; do - sed -i -e 's|^#[A-Z][a-z]\{2\} [A-Z][a-z]\{2\} [0-9]\{2\} ..:..:.. GMT 20..$|#Fri Jan 01 11:27:36 GMT 2009|' $f - done - ;; - */fonts.scale|*/fonts.dir|*/encodings.dir) - for f in old/$file new/$file; do - # sort files before comparing - sort -o $f $f - done - ;; - /var/adm/perl-modules/*) - for f in old/$file new/$file; do - sed -i -e 's|^=head2 ... ... .. ..:..:.. ....: C|=head2 Wed Jul 1 00:00:00 2009: C|' $f - done - ;; - /usr/share/man/man3/*3pm) - for f in old/$file new/$file; do - sed -i -e 's| 3 "20..-..-.." "perl v5....." "User Contributed Perl Documentation"$| 3 "2009-01-01" "perl v5.10.0" "User Contributed Perl Documentation"|' $f - trim_man_TH $f - trim_man_first_line $f - done - ;; - /usr/share/man/*/man*|/usr/share/man/man*|/usr/lib/texmf/doc/man/*/*) - - for f in old/$file new/$file; do - trim_man_TH $f - trim_man_first_line $f - # generated by docbook xml: - #.\" Date: 09/13/2010 - sed -i -e 's|Date: [0-1][0-9]/[0-9][0-9]/201[0-9]|Date: 09/13/2010|' $f - done - ;; - *.elc) - # emacs lisp files - for f in old/$file new/$file; do - sed -i -e 's|Compiled by abuild@.* on ... ... .. ..:..:.. 20..$|compiled by abuild@buildhost on Wed Jul 01 00:00:00 2009|' $f - done - ;; - /var/lib/texmf/web2c/*/*fmt |\ - /var/lib/texmf/web2c/metafont/*.base|\ - /var/lib/texmf/web2c/metapost/*.mem) - # binary dump of TeX and Metafont formats, we can ignore them for good - echo "difference in $file ignored." - return 0 - ;; - */libtool) - for f in old/$file new/$file; do - sed -i -e 's|^# Libtool was configured on host [A-Za-z0-9]*:$|# Libtool was configured on host x42:|' $f - done - ;; - /etc/mail/*cf|/etc/sendmail.cf) - # from sendmail package - for f in old/$file new/$file; do - # - ##### built by abuild@build33 on Thu May 6 11:21:17 UTC 2010 - sed -i -e 's|built by abuild@[a-z0-9]* on ... ... [0-9]* [0-9]*:[0-9][0-9]:[0-9][0-9] .* 20[0-9][0-9]|built by abuild@build42 on Thu May 6 11:21:17 UTC 2010|' $f - done - ;; - /usr/share/doc/kde/HTML/*/*/index.cache|/usr/share/doc/kde/HTML/*/*/*/index.cache|\ - /usr/share/gtk-doc/html/*/*.html|/usr/share/gtk-doc/html/*/*.devhelp2) - # various kde and gtk packages - strip_numbered_anchors - ;; - */created.rid) - # ruby documentation - # file just contains a timestamp and nothing else, so ignore it - echo "Ignore $file" - return 0 - ;; - */rdoc/files/*.html) - # ruby documentation - # Mon Sep 20 19:02:43 +0000 2010 - for f in old/$file new/$file; do - sed -i -e 's%[A-Z][a-z][a-z] [A-Z][a-z][a-z] [0-9]\+ [0-9]\+:[0-9]\+:[0-9]\+ +0000 201[0-9]%Mon Sep 20 19:02:43 +0000 2010%g' $f - done - strip_numbered_anchors - ;; + done + ;; + /usr/share/doc/packages/*/*.html|\ + /usr/share/doc/packages/*/*/*.html|\ + /usr/share/doc/*/html/*.html|\ + /usr/share/doc/kde/HTML/*/*/*.html) + for f in old/$file new/$file; do + sed -i -e ' + s|META NAME="Last-modified" CONTENT="[^"]\+"|META NAME="Last-modified" CONTENT="Thu Mar 3 10:32:44 2016"| + s||| + s| + # + # + # + # + # + # + sed -i -e ' + /^/{ + : next + n + /^<\/head>/{ + b end_head + } + s/^// + t next + s/^\(\)/\1 some-date-removed-by-build-compare \5/ + t next + s/^\(\)/\1 some-date-removed-by-build-compare \3/ + t next + s/^\(\)/\1 some-date-removed-by-build-compare \3/ + t next + s/^// + t next + s/^// + b next + } + : end_head + s%Generated by Gjdoc HtmlDoclet [0-9,.]*, part of GNU Classpath Tools, on .*, 20.. [0-9]*:..:.. \(a\|p\)\.m\. GMT.%Generated by Gjdoc.% + s%, on [A-Z][a-z]* [0-9]*, 20?? [0-9]*:??:?? \(a|p\)\.m\. GMT.

%, on January 1, 2009 0:00:00 a.m. GMT.

% + s%\), on [a-zA-Z]* [0-9][0-9], 20.. [0-9]*:..:.. \(a\|p\)\.m\. GMT.

%% + ' $f + # deprecated-list is randomly ordered, sort it for comparison + case $f in + */deprecated-list.html) + [[ $nofilter ]] || sort -o $f $f + ;; + esac + done + ;; + /usr/share/javadoc/gjdoc.properties|\ + /usr/share/javadoc/*/gjdoc.properties) + for f in old/$file new/$file; do + sed -i -e 's|^#[A-Z][a-z]\{2\} [A-Z][a-z]\{2\} [0-9]\{2\} ..:..:.. GMT 20..$|#Fri Jan 01 11:27:36 GMT 2009|' $f + done + ;; + */fonts.scale|\ + */fonts.dir|\ + */encodings.dir) + for f in old/$file new/$file; do + # sort files before comparing + [[ $nofilter ]] || sort -o $f $f + done + ;; + /var/adm/perl-modules/*) + for f in old/$file new/$file; do + sed -i -e 's|^=head2 ... ... .. ..:..:.. ....: C|=head2 Wed Jul 1 00:00:00 2009: C|' $f + done + ;; + /usr/share/man/man3/*3pm) + for f in old/$file new/$file; do + sed -i -e 's| 3 "20..-..-.." "perl v5....." "User Contributed Perl Documentation"$| 3 "2009-01-01" "perl v5.10.0" "User Contributed Perl Documentation"|' $f + trim_man_TH $f + trim_man_first_line $f + done + ;; + */share/man/*|\ + /usr/lib/texmf/doc/man/*/*) + for f in old/$file new/$file; do + trim_man_TH $f + trim_man_first_line $f + # generated by docbook xml: + #.\" Date: 09/13/2010 + # Generator: DocBook XSL Stylesheets v1.78.1 + #.\" Date: 2021-08-05 + sed -i -e ' + s|Date: [0-1][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]|Date: DD/MM/YYYY| + s|Date: [0-9][0-9][0-9][0-9]-[0-1][0-9]-[0-3][0-9]|Date: YYYY-MM-DD| + ' $f + done + ;; + *.elc) + filter_generic emacs_lisp + ;; + */libtool) + for f in old/$file new/$file; do + sed -i -e 's|^# Libtool was configured on host [A-Za-z0-9]*:$|# Libtool was configured on host x42:|' $f + done + ;; + /etc/mail/*cf|\ + /etc/sendmail.cf) + # from sendmail package + for f in old/$file new/$file; do + # - ##### built by abuild@build33 on Thu May 6 11:21:17 UTC 2010 + sed -i -e 's|built by abuild@[a-z0-9]* on ... ... [0-9]* [0-9]*:[0-9][0-9]:[0-9][0-9] .* 20[0-9][0-9]|built by abuild@build42 on Thu May 6 11:21:17 UTC 2010|' $f + done + ;; + /usr/lib*/R/library/*/DESCRIPTION) + # Simulate R CMD INSTALL --built-timestamp='' + # Built: R 3.6.1; x86_64-suse-linux-gnu; 2019-08-13 04:19:49 UTC; unix + sed -i -e 's|\(Built: [^;]*; [^;]*; \)20[0-9][0-9]-[01][0-9]-[0123][0-9] [012][0-9]:[0-5][0-9]:[0-5][0-9] UTC\(; .*\)$|\1\2|' old/$file new/$file + ;; */Linux*Env.Set.sh) - # LibreOffice files, contains: - # Generated on: Mon Apr 18 13:19:22 UTC 2011 - for f in old/$file new/$file; do - sed -i -e 's%^# Generated on:.*UTC 201[0-9] *$%# Generated on: Sometime%g' $f - done - ;; - /usr/lib/libreoffice/solver/inc/*/deliver.log) - # LibreOffice log file - echo "Ignore $file" - return 0 + # LibreOffice files, contains: + # Generated on: Mon Apr 18 13:19:22 UTC 2011 + for f in old/$file new/$file; do + sed -i -e 's%^# Generated on:.*UTC 201[0-9] *$%# Generated on: Sometime%g' $f + done ;; - /var/adm/update-messages/*|/var/adm/update-scripts/*) - # encode version-release inside - oldfn=`echo "$file"|sed -e s/-$release2/-$release1/;` - + /var/adm/update-messages/*|\ + /var/adm/update-scripts/*) # fetchmsttfonts embeds the release number in the update shell script. - echo sed -i -e "s/-$release1/-$release2/g;" "old/$oldfn" - sed -i -e "s/-$release1/-$release2/g;" "old/$oldfn" - - if ! diff -u old/$oldfn new/$file; then - echo "$oldfn is not same as $file" - return 1 - fi - echo "$file and $oldfn are same" - return 0 + sed -i "s/${name_ver_rel_old_regex_l}/@NAME_VER_REL@/" old/$file + sed -i "s/${name_ver_rel_new_regex_l}/@NAME_VER_REL@/" new/$file ;; *.ps) - for f in "old/$file" "new/$file"; do - sed -i -e ' - /^%%CreationDate:[[:blank:]]/d - /^%%Creator:[[:blank:]]groff[[:blank:]]version[[:blank:]]/d - /^%DVIPSSource:[[:blank:]]/d - ' "$f" - done - ;; - *pdf) - # PDF files contain a unique ID, remove it - # Format of the ID is: - # /ID [<9ACE247A70CF9BEAFEE15E116259BD6D> <9ACE247A70CF9BEAFEE15E116259BD6D>] - # with optional spaces. pdftex creates also: - # /CreationDate (D:20120103083206Z) - # /ModDate (D:20120103083206Z) - # and possibly XML metadata as well - for f in "old/$file" "new/$file"; do - sed -i \ - '/obj/,/endobj/{ - s%/ID \?\[ \?<[^>]\+> \?<[^>]\+> \?\]%/IDrandom%g; - s%/CreationDate \?(D:[^)]*)%/CreationDate (D: XXX)%g; - s%/ModDate \?(D:[^)]*)%/ModDate (D: XXX)%g; - s%[^<]*%XXX%g; - s%[^<]*%XXX%g; - s%[^<]*%XXX%g; - s%[^<]*%XXX%g; - s%[^<]*%XXX%g; - }' "$f" + filter_generic ps + ;; + *.pdf) + filter_generic pdf + ;; + */linuxrc.config) + filter_generic linuxrc_config + ;; + */etc/hosts) + # packaged by libguestfs + sed -i 's/^127.0.0.1[[:blank:]].*/127.0.0.1 hst/' "old/$file" + sed -i 's/^127.0.0.1[[:blank:]].*/127.0.0.1 hst/' "new/$file" + ;; + */dune-package) + sed -i '1s@^(lang dune [^)]\+)@(lang dune 0.0)@' "old/$file" "new/$file" + ;; + esac +} + +archive_a() +{ + 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 +} + +archive_cpio() +{ + 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 +} + +archive_squashfs() +{ + 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 +} + +archive_tar() +{ + 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 +} + +UNJAR= +archive_zip() +{ + 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 handler="$2" + local old="`readlink -f \"old/$file\"`" + local new="`readlink -f \"new/$file\"`" + local f + local -a content + local -i ret=1 + local -a filelist + + "${handler}" 'f' "${file}" || return 1 + + mkdir -p "d/old/${file}" "d/new/${file}" + if pushd "d" > /dev/null + then + "${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 + "${handler}" 'x' "${old}" || return 1 + popd > /dev/null + fi + if pushd "new/${file}" > /dev/null + then + "${handler}" 'x' "${new}" || return 1 + popd > /dev/null + fi + while read + do + : "${REPLY}" + filelist+=( "${REPLY}" ) + done < 'cn' + ret=0 + for f in "${filelist[@]}" + do + if ! check_single_file "${file}/${f}" + then + ret=1 + if test -z "$check_all" + then + break + fi + fi + watchdog_touch done + 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" + local ret=0 + local i + local failed + local elfdiff elf_executable_sections + local sections + local -a pipestatus + + if file_is_on_ignorelist "${file}" + then + return 0 + fi + + verify_before_processing "${file}" "${dfile}" + case "$?" in + 0) return 0 ;; + 1) test -z "$check_all" && return 1 ;; + *) ;; + esac + + normalize_file "${file}" + + case "$file" in + *.a) + compare_archive "${file}" 'archive_a' + return $? + ;; + *.cpio) + compare_archive "${file}" 'archive_cpio' + return $? + ;; + *.squashfs) + compare_archive "${file}" 'archive_squashfs' + return $? + ;; + *.tar|*.tar.bz2|*.tar.gz|*.tgz|*.tbz2|*.tar.zst) + compare_archive "${file}" 'archive_tar' + return $? + ;; + *.zip|*.egg|*.jar|*.war) + compare_archive "${file}" 'archive_zip' + return $? + ;; + *.bz2) + bunzip2 -c old/$file > old/${file/.bz2/} + bunzip2 -c new/$file > new/${file/.bz2/} + check_single_file ${file/.bz2/} + return $? + ;; + *.gz) + gunzip -c old/$file > old/${file/.gz/} + gunzip -c new/$file > new/${file/.gz/} + check_single_file ${file/.gz/} + return $? ;; - */linuxrc.config) - echo "${file}" - sed -i '/^InitrdID:/s@^.*@InitrdID: something@' "old/$file" - sed -i '/^InitrdID:/s@^.*@InitrdID: something@' "new/$file" + *.zst) + zstd -dc old/$file > old/${file/.zst/} + zstd -dc new/$file > new/${file/.zst/} + check_single_file ${file/.zst/} + return $? + ;; + *.rpm) + $self_script -a old/$file new/$file + return $? ;; esac - ftype=`/usr/bin/file old/$file | sed 's@^[^:]\+:[[:blank:]]*@@'` + ftype=`/usr/bin/file "old/$file" | sed -e 's@^[^:]\+:[[:blank:]]*@@' -e 's@[[:blank:]]*$@@'` case $ftype in - PE32\ executable*Mono\/\.Net\ assembly*) - echo "PE32 Mono/.Net assembly: $file" - if [ -x /usr/bin/monodis ] ; then - monodis old/$file 2>/dev/null|sed -e 's/GUID = {.*}/GUID = { 42 }/;'> ${file1} - monodis new/$file 2>/dev/null|sed -e 's/GUID = {.*}/GUID = { 42 }/;'> ${file2} - if ! cmp -s ${file1} ${file2}; then - echo "$file differs ($ftype)" - diff -u ${file1} ${file2} + PE32\ executable*Mono\/\.Net\ assembly*) + wprint "PE32 Mono/.Net assembly: $file" + if [ -x /usr/bin/monodis ] ; then + monodis "old/$file" 2>/dev/null|sed -e 's/GUID = {.*}/GUID = { 42 }/;'> ${file1} + monodis "new/$file" 2>/dev/null|sed -e 's/GUID = {.*}/GUID = { 42 }/;'> ${file2} + if ! cmp -s "${file1}" "${file2}"; then + wprint "$file differs ($ftype)" + diff --speed-large-files -u \ + --label "old $file (monodis)" "${file1}" \ + --label "new $file (monodis)" "${file2}" return 1 fi else - echo "Cannot compare, no monodis installed" + wprint "Cannot compare, no monodis installed" return 1 fi ;; - ELF*executable*|ELF*[LM]SB\ relocatable*|ELF*[LM]SB\ shared\ object*) - objdump -d --no-show-raw-insn old/$file | filter_disasm > $file1 - if ! test -s $file1; then - # objdump has no idea how to handle it - if ! diff_two_files; then - ret=1 - break - fi - fi - elfdiff= - sed -i -e "s,old/,," $file1 - objdump -d --no-show-raw-insn new/$file | filter_disasm > $file2 - sed -i -e "s,new/,," $file2 - if ! diff -u $file1 $file2 > $dfile; then - echo "$file differs in assembler output" - head -n 200 $dfile - elfdiff="1" - fi - echo "" >$file1 - echo "" >$file2 - # Don't compare .build-id and .gnu_debuglink sections - sections="$(objdump -s new/$file | grep "Contents of section .*:" | sed -r "s,.* (.*):,\1,g" | grep -v -e "\.build-id" -e "\.gnu_debuglink" | tr "\n" " ")" - for section in $sections; do - objdump -s -j $section old/$file | sed "s,^old/,," > $file1 - objdump -s -j $section new/$file | sed "s,^new/,," > $file2 - if ! diff -u $file1 $file2 > $dfile; then - echo "$file differs in ELF section $section" - head -n 200 $dfile - elfdiff="1" - fi - done - if test -z "$elfdiff"; then - echo "$file: only difference was in build-id or gnu_debuglink, GOOD." + ELF*executable*|\ + set?id\ ELF*executable*|\ + ELF*[LM]SB\ relocatable*|\ + set?id\ ELF*[LM]SB\ relocatable*|\ + ELF*[LM]SB\ shared\ object*|\ + set?id\ ELF*[LM]SB\ shared\ object*|\ + ELF*[LM]SB\ pie\ executable*|\ + set?id\ ELF*[LM]SB\ pie\ executable*) + local sections=($( + $OBJDUMP -s new/$file | + sed -n --regexp-extended -e ' + /Contents of section .*:/ { + s,.* (.*):,-j \1,g + /\.build-id/d + /\.gnu_debuglink/d + /\.gnu_debugdata/d + /\.note\.package/d + /\.note\.go\.buildid/d + p + } + ')) + (cd old && exec $OBJDUMP -s ${sections[@]} ./$file ) > old/$file.objdump & + (cd new && exec $OBJDUMP -s ${sections[@]} ./$file ) > new/$file.objdump & + wait + if ! test -s old/$file.objdump + then + wprint "ELF section: objdump failed for old/$file" + elfdiff='failed' + fi + if ! test -s new/$file.objdump + then + wprint "ELF section: objdump failed for new/$file" + elfdiff='failed' + fi + if test -z "${elfdiff}" + then + diff --speed-large-files --unified \ + --label "old $file (objdump)" \ + --label "new $file (objdump)" \ + old/$file.objdump new/$file.objdump > $dfile + ret=$? + if test "$ret" != "0" + then + wprint "$file differs in ELF sections" + $buildcompare_head $dfile + elfdiff='elfdiff' + fi + fi + if test -z "$elfdiff" + then + rm old/$file.objdump new/$file.objdump & + return 0 + fi + watchdog_touch + (cd old && exec $OBJDUMP -d --no-show-raw-insn ./$file | filter_disasm + echo "${PIPESTATUS[@]}" > $file1 ) > old/$file.objdump & + (cd new && exec $OBJDUMP -d --no-show-raw-insn ./$file | filter_disasm + echo "${PIPESTATUS[@]}" > $file2 ) > new/$file.objdump & + wait + read i < ${file1} + pipestatus=( $i ) + if [[ ${pipestatus[*]} =~ [1-9] ]] + then + wprint "ELF disassembly: pipe command failed for old/$file" + elf_executable_sections='failed' + fi + read i < ${file2} + pipestatus=( $i ) + if [[ ${pipestatus[*]} =~ [1-9] ]] + then + wprint "ELF disassembly: pipe command failed for new/$file" + elf_executable_sections='failed' + fi + if test -n "${elf_executable_sections}" + then + # objdump had no idea how to handle it + rm old/$file.objdump new/$file.objdump & + if diff_two_files; then return 0 - fi - return 1 - ;; - *ASCII*|*text*) - if ! cmp -s old/$file new/$file; then - echo "$file differs ($ftype)" - diff -u old/$file new/$file | head -n 200 - return 1 - fi - ;; - directory|setuid\ directory|setuid,\ directory|sticky,\ directory) - # tar might package directories - ignore them here - return 0 - ;; - bzip2\ compressed\ data*) - if ! check_compressed_file "$file" "bz2"; then - return 1 - fi - ;; - gzip\ compressed\ data*) - if ! check_compressed_file "$file" "gzip"; then - return 1 - fi - ;; - XZ\ compressed\ data*) - if ! check_compressed_file "$file" "xz"; then - return 1 - fi - ;; - POSIX\ tar\ archive) - mv old/$file{,.tar} - mv new/$file{,.tar} - if ! check_single_file ${file}.tar; then - return 1 - fi - ;; - cpio\ archive) - mv old/$file{,.cpio} - mv new/$file{,.cpio} - if ! check_single_file ${file}.cpio; then - return 1 - fi - ;; - Squashfs\ filesystem,*) - echo "$file ($ftype)" - mv old/$file{,.squashfs} - mv new/$file{,.squashfs} - if ! check_single_file ${file}.squashfs; then - return 1 fi - ;; - symbolic\ link\ to\ *) - readlink "old/$file" > $file1 - readlink "new/$file" > $file2 - if ! diff -u $file1 $file2; then - echo "symlink target for $file differs" - return 1 - fi - ;; - block\ special\ *) - ;; - character\ special\ *) - ;; - *) - if ! diff_two_files; then - return 1 - fi - ;; + return 1 + fi + diff --speed-large-files --unified \ + --label "old $file (disasm)" \ + --label "new $file (disasm)" \ + old/$file.objdump new/$file.objdump > $dfile + ret=$? + rm old/$file.objdump new/$file.objdump & + if test "$ret" != "0" + then + wprint "$file differs in assembler output" + $buildcompare_head $dfile + elf_executable_sections='elf_executable_sections' + else + watchdog_touch + fi + if test -n "$elfdiff" || test -n "$elf_executable_sections" + then + return 1 + fi + ;; + *ASCII*|*text*) + if ! cmp -s "old/$file" "new/$file" ; then + wprint "$file differs ($ftype)" + diff -u "old/$file" "new/$file" | $buildcompare_head + return 1 + fi + ;; + directory|setuid\ directory|setuid,\ directory|sticky,\ directory) + # tar might package directories - ignore them here + return 0 + ;; + bzip2\ compressed\ data*) + if ! check_compressed_file "$file" "bz2" ; then + return 1 + fi + ;; + gzip\ compressed\ data*) + if ! check_compressed_file "$file" "gzip" ; then + return 1 + fi + ;; + XZ\ compressed\ data*) + if ! check_compressed_file "$file" "xz" ; then + return 1 + fi + ;; + Zstandard\ compressed\ data*) + if ! check_compressed_file "$file" "zst" ; then + return 1 + fi + ;; + Zip\ archive\ data,*) + if ! compare_archive "${file}" 'archive_zip' ; then + return 1 + fi + ;; + POSIX\ tar\ archive) + mv old/$file{,.tar} + mv new/$file{,.tar} + if ! check_single_file ${file}.tar; then + return 1 + fi + ;; + cpio\ archive) + mv old/$file{,.cpio} + mv new/$file{,.cpio} + if ! check_single_file ${file}.cpio; then + return 1 + fi + ;; + Squashfs\ filesystem,*) + wprint "$file ($ftype)" + mv old/$file{,.squashfs} + mv new/$file{,.squashfs} + if ! check_single_file ${file}.squashfs; then + return 1 + fi + ;; + broken\ symbolic\ link\ to\ *|symbolic\ link\ to\ *) + readlink "old/$file" > $file1 + readlink "new/$file" > $file2 + if ! diff -u $file1 $file2; then + wprint "symlink target for $file differs" + return 1 + fi + ;; + block\ special\ *) + ;; + character\ special\ *) + ;; + *) + if ! diff_two_files; then + return 1 + fi + ;; esac return 0 } +case "${0}" in + */*) FUNCTIONS=${0%/*}/functions.sh ;; + *) FUNCTIONS=functions.sh ;; +esac +: ${buildcompare_head:="head -n 200"} +nofilter=${buildcompare_nofilter} +sort=sort +[[ $nofilter ]] && sort=cat + +check_all= +case $1 in + -a | --check-all) + check_all=1 + shift +esac + +if test "$#" != 2; then + echo "usage: $0 [-a|--check-all] old.rpm new.rpm" + exit 1 +fi + +test -z $OBJDUMP && OBJDUMP=objdump + +# Always clean up on exit +local_tmpdir=`mktemp -d` +if test -z "${local_tmpdir}" +then + exit 1 +fi +function _exit() +{ + chmod -R u+w "${local_tmpdir}" + rm -rf "${local_tmpdir}" +} +trap _exit EXIT +# Let further mktemp refer to private tmpdir +export TMPDIR=$local_tmpdir + +self_script=$(cd $(dirname $0); echo $(pwd)/$(basename $0)) + +source $FUNCTIONS + +oldpkg=`readlink -f $1` +newpkg=`readlink -f $2` +rename_script=`mktemp` + +file1=`mktemp` +file2=`mktemp` +dir=`mktemp -d` +dfile=`mktemp` + +if test ! -f "$oldpkg"; then + echo "can't open $1" + exit 1 +fi + +if test ! -f "$newpkg"; then + echo "can't open $2" + exit 1 +fi + +echo "Comparing `basename $oldpkg` to `basename $newpkg`" + +case $oldpkg in + *.deb|*.ipk) + : cmp_deb_meta missing + RES=0 + ;; + *.rpm) + cmp_rpm_meta "$rename_script" "$oldpkg" "$newpkg" + RES=$? + case $RES in + 0) + echo "RPM meta information is identical" + if test -z "$check_all"; then + exit 0 + fi + ;; + 1) + echo "RPM meta information is different" + if test -z "$check_all"; then + exit 1 + fi + ;; + 2) + echo "RPM file checksum differs." + RES=0 + ;; + *) + echo "Wrong exit code!" + exit 1 + ;; + esac + ;; +esac + +wprint "Extracting packages" +unpackage $oldpkg $dir/old & +unpackage $newpkg $dir/new & +wait + +case $oldpkg in + *.deb|*.ipk) + adjust_controlfile $dir/old $dir/new + files=() + while read + do + : "${REPLY}" + files+=( "${REPLY}" ) + done < <(cd ${dir} ; find old new -type f | sed -e 's/^...//' | sort -u) + ;; +esac + +cd $dir +bash $rename_script + # We need /proc mounted for some tests, so check that it's mounted and # complain if not. PROC_MOUNTED=0 @@ -805,15 +1270,15 @@ if [ ! -d /proc/self/ ]; then PROC_MOUNTED=1 fi -# preserve cmp_spec result for check_all runs +# preserve cmp_rpm_meta result for check_all runs ret=$RES -for file in $files; do - if ! check_single_file $file; then - ret=1 - if test -z "$check_all"; then - break - fi - fi +for file in "${files[@]}"; do + if ! check_single_file "$file"; then + ret=1 + if test -z "$check_all"; then + break + fi + fi done if [ "$PROC_MOUNTED" -eq "1" ]; then @@ -821,10 +1286,8 @@ if [ "$PROC_MOUNTED" -eq "1" ]; then umount /proc fi -rm $file1 $file2 $dfile $rename_script -rm -rf $dir if test "$ret" = 0; then - echo "Package content is identical" + echo "Package content is identical" fi exit $ret # vim: tw=666 ts=2 shiftwidth=2 et diff --git a/packaging/same-build-result.sh b/packaging/same-build-result.sh index 701ccf2..5549207 100644 --- a/packaging/same-build-result.sh +++ b/packaging/same-build-result.sh @@ -13,9 +13,51 @@ CMPSCRIPT=${0%/*}/pkg-diff.sh SCMPSCRIPT=${0%/*}/srpm-check.sh -FUNCTIONS=${0%/*}/functions.sh -check_all=1 +declare -a exit_code +# exit_code[0]='' # binaries_differ +# exit_code[1]='' # rpmlint_differs +# exit_code[2]='' # appdata_differs +# exit_code[3]='' # srcrpm_differs +file1=`mktemp` +file2=`mktemp` +_x() { + rm -f ${file1} ${file2} +} +trap _x EXIT +# +remove_check_time_report() { + local f=$1 + awk ' + BEGIN { + ctr_seen=0; + } + /Check time report .*:$/ { + ctr_seen=1; + next; + } + /TOTAL[[:blank:]]+[0-9]/ { + if (ctr_seen == 1) { + ctr_seen=0; + next; + } + } + { + if (ctr_seen == 1) { + next; + } + print $0; + } + ' < "${f}" +} +# +check_all= +if test "$1" = "-a" +then + check_all="-a" + shift +fi +# OLDDIR="$1" shift NEWDIRS="$*" @@ -31,45 +73,34 @@ if [ -z "$NEWDIRS" ]; then exit 1 fi -source $FUNCTIONS - -first_rpm=$(find $NEWDIRS -name *.rpm | head -1) -dist=$(rpm -qp --nodigest --nosignature --qf "%{DISTRIBUTION}" $first_rpm | sed -r 's/(.*)\/.*/\1/') -prerelease=0 -if ! is_prerelease_project $dist; then - echo "This is a prerelease project. Do not check the existence of source rpm files." - - prerelease=1 - num_new_pkgs=`find $NEWDIRS -name '*.rpm' -and ! -name '*.delta.rpm' -and ! -name '*.src.rpm' | wc -l` - num_old_pkgs=`find $OLDDIR -name '*.rpm' -and ! -name '*.delta.rpm' -and ! -name '*.src.rpm' | wc -l` - if test $num_new_pkgs != $num_old_pkgs; then - echo "different number of subpackages" - find $OLDDIR $NEWDIRS -name '*.rpm' -and ! -name '*.delta.rpm' -and ! -name '*.src.rpm' - exit 1 - fi - -else - if test `find $NEWDIRS -name '*.rpm' -and ! -name '*.delta.rpm' | wc -l` != `find $OLDDIR -name '*.rpm' -and ! -name '*.delta.rpm' | wc -l`; then - echo "different number of subpackages" - find $OLDDIR $NEWDIRS -name '*.rpm' -and ! -name '*.delta.rpm' - exit 1 - fi +if test `find $NEWDIRS -name '*.rpm' -and ! -name '*.delta.rpm' | wc -l` != `find $OLDDIR -name '*.rpm' -and ! -name '*.delta.rpm' | wc -l`; then + echo "different number of subpackages" + find $OLDDIR -name '*.rpm' -and ! -name '*.delta.rpm' -print0 | xargs -0 rpm -qp --qf '%{NAME}\n' | sort > ${file1} + find $NEWDIRS -name '*.rpm' -and ! -name '*.delta.rpm' -print0 | xargs -0 rpm -qp --qf '%{NAME}\n' | sort > ${file2} + diff -u ${file1} ${file2} + exit 1 +fi - osrpm=$(find "$OLDDIR" -name \*src.rpm) - nsrpm=$(find $NEWDIRS -name \*src.rpm) +osrpm=$(find "$OLDDIR" -name \*src.rpm) +nsrpm=$(find $NEWDIRS -name \*src.rpm) - if test ! -f "$osrpm"; then - echo no old source rpm in $OLDDIR - exit 1 - fi +if test ! -f "$osrpm"; then + echo no old source rpm in $OLDDIR + exit 1 +fi - if test ! -f "$nsrpm"; then - echo no new source rpm in $NEWDIRS - exit 1 - fi +if test ! -f "$nsrpm"; then + echo no new source rpm in $NEWDIRS + exit 1 +fi - echo "compare $osrpm $nsrpm" - bash $SCMPSCRIPT "$osrpm" "$nsrpm" || exit 1 +echo "compare $osrpm $nsrpm" +if bash $SCMPSCRIPT $check_all "$osrpm" "$nsrpm" +then + : src.rpm identical +else + test -z "${check_all}" && exit 1 + exit_code[3]='srcrpm_differs' fi # technically we should not all exclude all -32bit but filter for different archs, @@ -79,15 +110,28 @@ fi # problem: a package can contain both noarch and arch subpackages, so we have to # take care of proper sorting of NEWRPMS, e.g. noarch/x.rpm and x86_64/w.rpm since OLDRPMS # has all the packages in a single directory and would sort this as w.rpm, x.rpm. -OLDRPMS=($(find "$OLDDIR" -type f -name \*rpm -a ! -name \*src.rpm -a ! -name \*.delta.rpm|sort|grep -v -- -32bit-|grep -v -- -64bit-|grep -v -- '-x86-.*\.ia64\.rpm')) -NEWRPMS=($(find $NEWDIRS -type f -name \*rpm -a ! -name \*src.rpm -a ! -name \*.delta.rpm|sort --field-separator=/ --key=7|grep -v -- -32bit-|grep -v -- -64bit-|grep -v -- '-x86-.*\.ia64\.rpm')) +find $OLDDIR -type f -name '*.rpm' \ + -a ! -name '*src.rpm' \ + -a ! -name '*.delta.rpm' \ + -a ! -name '*-32bit-*' \ + -a ! -name '*-64bit-*' \ + -a ! -name '*-x86-*.ia64.rpm' \ + > ${file1} +find $NEWDIRS -type f -name '*.rpm' \ + -a ! -name '*src.rpm' \ + -a ! -name '*.delta.rpm' \ + -a ! -name '*-32bit-*' \ + -a ! -name '*-64bit-*' \ + -a ! -name '*-x86-*.ia64.rpm' \ + > ${file2} +OLDRPMS=($( sort --field-separator=/ --key=` sed -n '1s@[^/]@@gp' ${file1} | wc -c ` ${file1} )) +NEWRPMS=($( sort --field-separator=/ --key=` sed -n '1s@[^/]@@gp' ${file2} | wc -c ` ${file2} )) # Get version-release from first RPM and keep for rpmlint check # Remember to quote the "." for future regexes ver_rel1=$(rpm -qp --nodigest --nosignature --qf "%{VERSION}-%{RELEASE}" "${OLDRPMS[0]}"|sed -e 's/\./\\./g') ver_rel2=$(rpm -qp --nodigest --nosignature --qf "%{VERSION}-%{RELEASE}" "${NEWRPMS[0]}"|sed -e 's/\./\\./g') -SUCCESS=1 rpmqp='rpm -qp --qf %{NAME} --nodigest --nosignature ' for opac in ${OLDRPMS[*]}; do npac=${NEWRPMS[0]} @@ -104,11 +148,7 @@ for opac in ${OLDRPMS[*]}; do echo "skipping -debuginfo package" ;; *) - bash $CMPSCRIPT "$opac" "$npac" || SUCCESS=0 - if test $SUCCESS -eq 0 -a -z "$check_all"; then - echo "differences between $opac and $npac" - exit 1 - fi + bash $CMPSCRIPT $check_all "$opac" "$npac" || exit_code[0]='binaries_differ' ;; esac done @@ -118,61 +158,87 @@ if [ -n "${NEWRPMS[0]}" ]; then exit 1 fi +OTHERDIR= # Compare rpmlint.log files if test -d /home/abuild/rpmbuild/OTHER; then OTHERDIR=/home/abuild/rpmbuild/OTHER elif test -d /usr/src/packages/OTHER; then OTHERDIR=/usr/src/packages/OTHER else - echo "no OTHERDIR" - OTHERDIR= + for newdir in $NEWDIRS + do + test -f "${newdir}/rpmlint.log" || continue + OTHERDIR="${newdir}" + break + done + test -n "$OTHERDIR" || echo "no OTHERDIR" fi if test -n "$OTHERDIR"; then - if [ $prerelease -eq 1 ] ; then - echo "do not compare rpmlint.log if it is a prerelease project!" + old_log=$OLDDIR/rpmlint.log + new_log=$OTHERDIR/rpmlint.log + if test -e ${old_log} && test -e ${new_log} ; then + echo "comparing ${old_log} and ${new_log}" + # Remove --time-report from rpmlint + # Sort the files first since the order of messages is not deterministic + # Remove release from files + remove_check_time_report ${old_log}|sort -u|sed -e "s,$ver_rel1,@VERSION@-@RELEASE@,g" -e "s|/tmp/rpmlint\..*spec|.spec|g" > $file1 + remove_check_time_report ${new_log}|sort -u|sed -e "s,$ver_rel2,@VERSION@-@RELEASE@,g" -e "s|/tmp/rpmlint\..*spec|.spec|g" > $file2 + # Remove odd warning about not-hardlinked files + # Remove odd warning about data and time, it comes and goes + # Remove warning about python mtime mismatch, a republish will not help + # Remove odd warning about filenames, they contain VERSION-RELEASE + # Remove durations from progress reports + # Remove odd output about number of checks and packages + sed -i -e " + /: W: files-duplicate /d + /: W: file-contains-date-and-time /d + /: W: python-bytecode-inconsistent-mtime /d + /: W: filename-too-long-for-joliet /d + /: I: \(filelist-initialization\|check-completed\) /s| [0-9]\+\.[0-9] s| x.x s| + s/; has taken [0-9]\+\.[0-9] s/; has taken x.x s/ + /^checks: [0-9]\+, packages: [0-9]\+/d + " $file1 $file2 + if ! cmp -s $file1 $file2; then + echo "rpmlint.log files differ:" + diff -u $file1 $file2 |head -n 20 + exit_code[1]='rpmlint_differs' + fi + rm $file1 $file2 else - if test -e $OLDDIR/rpmlint.log -a -e $OTHERDIR/rpmlint.log; then - file1=`mktemp` - file2=`mktemp` - echo "comparing $OLDDIR/rpmlint.log and $OTHERDIR/rpmlint.log" - # Sort the files first since the order of messages is not deterministic - # Remove release from files - sort -u $OLDDIR/rpmlint.log|sed -e "s,$ver_rel1,@VERSION@-@RELEASE@,g" -e "s|/tmp/rpmlint\..*spec|.spec|g" > $file1 - sort -u $OTHERDIR/rpmlint.log|sed -e "s,$ver_rel2,@VERSION@-@RELEASE@,g" -e "s|/tmp/rpmlint\..*spec|.spec|g" > $file2 - if ! cmp -s $file1 $file2; then - echo "rpmlint.log files differ:" - diff -u $file1 $file2 |head -n 20 - SUCCESS=0 - fi - rm $file1 $file2 - elif test -e $OTHERDIR/rpmlint.log; then + if test -e "${new_log}" + then + exit_code[1]='rpmlint_new' echo "rpmlint.log is new" - SUCCESS=0 + elif test -e "${old_log}" + then + exit_code[1]='rpmlint_old' + echo "rpmlint.log disappeared" + else + echo "No rpmlint.log available" fi fi - appdatas=`cd $OTHERDIR && find . -name *-appdata.xml` + appdatas=$(cd $OTHERDIR && find . -name "*-appdata.xml") for xml in $appdatas; do # compare appstream data - if test -e $OLDDIR/$xml -a -e $OTHERDIR/$xml; then + if test -e $OLDDIR/$xml && test -e $OTHERDIR/$xml; then file1=$OLDDIR/$xml file2=$OTHERDIR/$xml if ! cmp -s $file1 $file2; then echo "$xml files differ:" diff -u0 $file1 $file2 |head -n 20 - SUCCESS=0 + exit_code[2]='appdata_differs' fi elif test -e $OTHERDIR/$xml; then echo "$xml is new" - SUCCESS=0 + exit_code[2]='appdata_new' fi done fi - -if test $SUCCESS -eq 0; then +if test -n "${exit_code[*]}"; then exit 1 fi -echo 'compare validated built as identical !' +echo 'compare validated build as identical !' exit 0 # vim: tw=666 ts=2 shiftwidth=2 et diff --git a/packaging/srpm-check.sh b/packaging/srpm-check.sh old mode 100644 new mode 100755 index b0ceacb..722bbde --- a/packaging/srpm-check.sh +++ b/packaging/srpm-check.sh @@ -1,10 +1,11 @@ #!/bin/bash # # Copyright (c) 2009, 2010 SUSE Linux Product GmbH, Germany. +# Copyright (c) 2022 SUSE LLC # Licensed under GPL v2, see COPYING file for details. # -# Written by Michael Matz and Stephan Coolo -# Enhanced by Andreas Jaeger +# Written by Michael Matz and Stephan Kulow +# Enhanced by Andreas Jaeger and Dirk Müller # Compare two source RPMs @@ -18,25 +19,21 @@ case $1 in esac if test "$#" != 2; then - echo "usage: $0 [-a|--check-all] old.rpm new.rpm" - exit 1 + echo "usage: $0 [-a|--check-all] old.rpm new.rpm" + exit 1 fi source $FUNCTIONS -oldrpm=`readlink -f $1` -newrpm=`readlink -f $2` - -# Get version-release from first RPM and keep for rpmlint check -# Remember to quote the "." for future regexes -ver_rel_old=$(rpm -qp --nodigest --nosignature --qf "%{RELEASE}" "${oldrpm}"|sed -e 's/\./\\./g') -ver_rel_new=$(rpm -qp --nodigest --nosignature --qf "%{RELEASE}" "${newrpm}"|sed -e 's/\./\\./g') +oldrpm=$(readlink -f $1) +newrpm=$(readlink -f $2) +rename_script= # For source RPMs, we can just check the metadata in the spec file # if those are not the same, the source RPM has changed and therefore # the resulting files are needed. -cmp_spec +cmp_rpm_meta "$rename_script" "$oldrpm" "$newrpm" RES=$? case $RES in 0) @@ -58,41 +55,38 @@ esac # Now check that only the spec file has a changed release number and # nothing else -dir=`mktemp -d` -unrpm $oldrpm $dir/old -unrpm $newrpm $dir/new +dir=$(mktemp -d) +unpackage $oldrpm $dir/old & +unpackage $newrpm $dir/new & cd $dir +wait check_single_file() { local file=$1 case $file in *.spec) - sed -i -e "s,Release:.*${ver_rel_old}$,Release: @RELEASE@," old/$file - sed -i -e "s,Release:.*${ver_rel_new}$,Release: @RELEASE@," new/$file - if ! cmp -s old/$file new/$file; then - echo "$file differs (spec file)" - diff -u old/$file new/$file | head -n 20 - return 1 - fi - return 0 - ;; + sed -i -e 's,^Release:.*$,Release: @RELEASE@,' old/$file + sed -i -e 's,^Release:.*$,Release: @RELEASE@,' new/$file + diff --speed-large-files -su0 old/$file new/$file | head -n 20 + return "${PIPESTATUS[0]}" + ;; *) - echo "$file differs" - # Nothing else should be changed - ;; - esac - return 1 + echo "$file differs" + # Nothing else should be changed + ;; + esac + return 1 } ret=0 -for file in $files; do - if ! check_single_file $file; then - ret=1 - if test -z "$check_all"; then - break - fi - fi +for file in "${files[@]}"; do + if ! check_single_file $file; then + ret=1 + if test -z "$check_all"; then + break + fi + fi done rm -rf $dir