checkapk.in 2.31 KB
Newer Older
Natanael Copa's avatar
Natanael Copa committed
1 2
#!/bin/sh

3 4 5 6 7 8
# checkapk - find ABI breakages in package upgrades
# Copyright (c) 2012 Natanael Copa <natanael.copa@gmail.com>
#
# Distributed under GPL-2
#

9
program_version=@VERSION@
10 11 12 13
datadir=@datadir@

if ! [ -f "$datadir/functions.sh" ]; then
	echo "$datadir/functions.sh: not found" >&2
Natanael Copa's avatar
Natanael Copa committed
14
	exit 1
15 16
fi
. "$datadir/functions.sh"
Natanael Copa's avatar
Natanael Copa committed
17 18


19
usage() {
20 21 22
	cat >&2 <<-__EOF__
		$program $program_version - find ABI breakages in package upgrades
		Usage: $program
Natanael Copa's avatar
Natanael Copa committed
23

24
		Run in the directory of a built package.
Natanael Copa's avatar
Natanael Copa committed
25

26
	__EOF__
27 28 29 30 31 32
}

if [ $# -gt 0 ]; then
	usage
	exit 2
fi
33

34
if ! [ -f "$ABUILD_CONF" ] && ! [ -f "$ABUILD_USERCONF" ]; then
35 36
	die "no abuild.conf found"
fi
Natanael Copa's avatar
Natanael Copa committed
37 38

if ! [ -f APKBUILD ]; then
39
	die 'must be run in the directory of a built package'
Natanael Copa's avatar
Natanael Copa committed
40 41
fi

42 43 44 45
if ! [ -n "$CARCH" ]; then
	die "failed to detect CARCH"
fi

Natanael Copa's avatar
Natanael Copa committed
46 47 48 49
. ./APKBUILD

startdir="$PWD"
tmpdir=$(mktemp -d -t checkpkg-script.XXXXXX)
50
trap "rm -rf '$tmpdir'" INT EXIT
51
cd "$tmpdir" || die "failed to create temp dir"
Natanael Copa's avatar
Natanael Copa committed
52 53

for i in $pkgname $subpackages; do
54
	_pkgname=${i%%:*}
Natanael Copa's avatar
Natanael Copa committed
55 56
	pkg=${_pkgname}-$pkgver-r$pkgrel
	pkgfile=${pkg}.apk
57 58
	repodir=${startdir%/*}
	repo=${repodir##*/}
Natanael Copa's avatar
Natanael Copa committed
59

60
	for filepath in "$PKGDEST"/$pkgfile "$REPODEST"/$repo/$CARCH/$pkgfile "$startdir"/$pkgfile; do
Natanael Copa's avatar
Natanael Copa committed
61 62 63 64
		if [ -f "$filepath" ]; then
			break
		fi
	done
65
	[ -f "$filepath" ] || die "can't find $pkgfile"
Natanael Copa's avatar
Natanael Copa committed
66

67 68
	# generate a temp repositories file with only the http(s) repos
	grep -E "^https?:" /etc/apk/repositories > $tmpdir/repositories
Natanael Copa's avatar
Natanael Copa committed
69 70 71

	oldpkg=$(apk fetch --repositories-file $tmpdir/repositories --simulate 2>&1 | sed 's/^Downloading //')
	if [ "${oldpkg}" = "${pkg}" ]; then
72
		die "the built package ($_pkgname) is already in the repo"
Natanael Copa's avatar
Natanael Copa committed
73 74
	fi

75
	apk fetch --quiet --repositories-file $tmpdir/repositories --stdout $_pkgname \
Natanael Copa's avatar
Natanael Copa committed
76
		| tar -zt | grep -v '^\.SIGN\.' | sort > filelist-$_pkgname-old \
77
		|| die "failed to download old pkg, maybe run 'apk update'?"
Natanael Copa's avatar
Natanael Copa committed
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94

	tar -ztf "$filepath" | grep -v '^\.SIGN\.' | sort > "filelist-$_pkgname"

	diff -u "filelist-$_pkgname-old" "filelist-$_pkgname"

	if diff "filelist-$_pkgname-old" "filelist-$_pkgname" | grep '\.so' > /dev/null 2>&1; then
		mkdir -p pkg
		cd pkg
		tar -zxf "$filepath" > /dev/null
		diff "../filelist-$_pkgname-old" "../filelist-$_pkgname" | awk '/>.*\.so/{$1 = ""; print $0}' | while read i; do
			echo "${i}: " "$(objdump -p "$i" | grep SONAME)"
		done
		cd ..
	else
		msg "No soname differences for $_pkgname."
	fi
done