summaryrefslogtreecommitdiffstats
path: root/buildrepo.in
blob: 0cf3a8ffd49298184ec583ac2c39caba4302fc0c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#!/bin/sh

program=${0##*/}

aportsdir=${APORTSDIR:-$HOME/aports}
repodir=${REPODIR:-$HOME/packages}

if [ -f /etc/abuild.conf ]; then
	. /etc/abuild.conf
fi

if [ -z "$CARCH" ]; then
	machine=$(uname -m)
	case $machine in
	i[3-9]86) CARCH=x86;;
	*) CARCH=$machine;;
	esac
fi

usage() {
	echo "usage: $program [-a APORTSDIR] [-d REPODIR] [-hp] [-l LOGPREFIX ]"
	echo "                [-r DEPREPO] REPOSITORY..."

	echo "options:"
	echo " -a  Set the aports base dir to APORTSDIR instead of $aportsdir"
	echo " -d  Set destination repository base dir to REPODIR instead of $repodir"
	echo " -h  Show this help and exit"
	echo " -l  Send build to logfile, prefixed by LOGPREFIX"
	echo " -k  Keep going, even if packages fails"
	echo " -p  Purge obsolete packages from REPODIR after build"
	echo " -r  Dependencies are found in DEPREPO"
	exit 1
}

is_in() {
	local needle="$1" arg=
	shift
	for arg; do
		[ "$needle" = "$arg" ] && return 0
	done
	return 1
}

check_arch() {
	[ "$1" = "all" ] || [ "$1" = "noarch" ] || is_in "$CARCH" $@
}

listpackages() {
	local repo="$1" i= pkgname= pkgver= pkgrel= subpackage= arch= subpkg= linguas=
	local lang= suffix=
	cd "$aportsdir/$repo"
	for i in */APKBUILD; do
		cd "$aportsdir/$repo"/${i%/*} || return 1
		pkgname=
		pkgver=
		pkgrel=
		subpackages=
		arch=
		linguas=
		. ./APKBUILD
		suffix="$pkgver-r$pkgrel.apk"

		if ! check_arch $arch; then
			continue
		fi
		for subpkg in $pkgname $subpackages; do
			echo ${subpkg%:*}-$suffix
		done
		for lang in $linguas; do
			echo $pkgname-lang-$lang-$suffix
		done
	done
}

all_exist() {
	while [ $# -gt 0 ]; do
		[ -e "$1" ] || return 1
		shift 1
	done
	return 0
}

list_needbuild() {
	local repo="$1" i=

	cd "$aportsdir/$repo" || return 0

	# first we try copy everything possible and find out which we need
	# to rebuild. By doing this we might save us for rebuilding
	# needed when running 'abuild -R'
	for apkbuild in */APKBUILD; do
		[ -f "$aportsdir/$repo/$apkbuild" ] || continue
		export REPODEST="$repodir"
		cd "$aportsdir/$repo"/${apkbuild%/*} || return 1
		pkgname=
		pkgver=
		pkgrel=
		subpackages=
		arch=
		. ./APKBUILD

		if ! check_arch $arch; then
			continue
		fi

		pkgs=
		for subpkg in $pkgname $subpackages; do
			pkgfile=${subpkg%:*}-$pkgver-r$pkgrel.apk
			if ! [ -f "$REPODEST/$repo/$CARCH/$pkgfile" ]; then
				pkgs="$pkgs $pkgfile"
			fi
		done
		if [ -z "$pkgs" ]; then
			continue
		fi

		# try link or copy the files if they are in the ports dir
		if all_exist $pkgs; then
			echo ">>> Copying " $pkgs >&2
			cp -p -l $pkgs "$repodir/$repo/$CARCH"/ 2>/dev/null \
				|| cp -p $pkgs "$repodir/$repo/$CARCH"/ \
				|| echo "$apkbuild"
		else
			echo "$apkbuild"
		fi
	done
}

do_build() {
	local repo="$1" i=
	cd "$aportsdir/$repo" || return 0
	local needbuild="$(list_needbuild $repo)"

	export REPODEST="$repodir"
	export ABUILD_BLACKLIST
	# build the postponed packages if any
	if [ -n "$needbuild" ]; then
		for i in $needbuild; do
			cd "$aportsdir/$repo"/${i%/*} || return 1
			if ! abuild -k -R; then
				[ -n "$keep_going" ] || return 1
				ABUILD_BLACKLIST="$ABUILD_BLACKLIST $i"
			fi
		done
	fi

	# kill old packages in repo
	if [ -n "$dopurge" ]; then
		echo ">>> Removing old packages from $repo..."
		local tmp=$(mktemp /tmp/$program-XXXXXX)
		local purgefiles
		cd "$repodir/$repo/$CARCH" || return 1
		trap 'rm -f "$tmp"; exit 1' INT
		( listpackages "$1") >$tmp || return 1
		purge=$(ls *.apk 2>/dev/null | grep -v -w -f $tmp)
		if [ -n "$purge" ]; then
			rm -f $purge
		fi
		rm -f "$tmp"
	fi

	# generate the repository index
	echo ">>> Generating Index for $repo..."
	cd "$repodir/$repo/$CARCH"
	local deps
	for i in $deprepo; do
		deps="--repo $repodir/$i"
	done
	oldindex=
	if [ -f APKINDEX.tar.gz ]; then
		oldindex="--index APKINDEX.tar.gz"
	fi
	tmpindex=$(mktemp).tar.gz
	apk index --rewrite-arch $CARCH $oldindex -o $tmpindex \
		--description "$repo $(cd $aportsdir && git describe)" \
		-- *.apk
	abuild-sign $tmpindex && mv $tmpindex APKINDEX.tar.gz
	chmod 644 APKINDEX.tar.gz
	rm -f tmp.*
}

while getopts "a:d:hkl:pr:" opt; do
	case "$opt" in
		a) aportsdir=$OPTARG;;
		d) repodir=$OPTARG;;
		h) usage >&2;;
		k) keep_going=1;;
		l) logprefix=$OPTARG;;
		p) dopurge=1;;
		r) deprepo="$deprepo $OPTARG";;
	esac
done
shift $(($OPTIND - 1))

[ $# -eq 0 ] && usage >&2

while [ $# -gt 0 ]; do
	if [ -n "$logprefix" ]; then
		do_build $1  >$logprefix.$1.log 2>&1 || exit 1
	else
		do_build $1 || exit 1
	fi
	deprepo="$deprepo $1"
	shift
done