checkapk.in 2.27 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
10
11
12
13
abuild_ver=@VERSION@
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
20
usage() {
	cat >&2 <<__EOF__
21
22
$program $abuild_ver - 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
27
28
29
30
31
32
__EOF__
}

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
cd "$tmpdir" || die "failed to create temp dir"
Natanael Copa's avatar
Natanael Copa committed
51
52
53
54
55

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

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

	# generate a temp repositories file with only the http repos
	grep ^http: /etc/apk/repositories > $tmpdir/repositories

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

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

	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

msg "Files saved to $tmpdir"