apkbuilds @ 3.20

  1#!/bin/sh -eu
  2usage() {
  3	printf "%s\n\n" "Usage: $0 [command...] [flags...] [args...]"
  4	printf "%s\n" "$0 add-repo [-s] <name> <key>"
  5	printf "\t%s\n" "Trusts <key> and adds the local repo to /etc/apk/repositories"
  6	printf "\t%s\n\n" "-s: set this key as default in abuild.conf"
  7	printf "%s\n" "$0 build [-cu] [-v <pkgver>] <packages...>"
  8	printf "\t%s\n" "Builds packages"
  9	printf "\t%s\n" "-c: update checksums"
 10	printf "\t%s\n" "-u: update pkgrel"
 11	printf "\t%s\n\n" "-v <pkgver>: update pkgver"
 12	printf "%s\n" "$0 pkgver"
 13	printf "\t%s\n\n" "Prints the suggested package ver for this directory"
 14	printf "%s\n" "$0 upload <ssh server> <remote path> <packages...>"
 15	printf "\t%s\n" "Uploads packages via rsync and updates remote APKINDEX"
 16}
 17
 18get_pkgvar() (
 19	var="$1"
 20	set +u
 21	. APKBUILD
 22	eval 'printf "%s\n" "$'"$var"'"'
 23)
 24
 25find_repos() (
 26	find . -maxdepth 1 -type d -not -name . -not -name .git
 27)
 28
 29find_pkg_repo() (
 30	pkg=$1
 31	for repo in $(find_repos)
 32	do
 33		if [ -d "$repo"/"$pkg" ]
 34		then
 35			echo "$repo"
 36			return 0
 37		fi
 38	done
 39	return 1
 40)
 41
 42update_pkgrel() (
 43	pkg="$1"
 44	pkgver="$(get_pkgvar pkgver)"
 45	prev_ver=$(apk search -x "$pkg" | cut -c$((${#pkg}+2))-)
 46	prev_pkgver=$(printf "%s" "$prev_ver" | cut -d'-' -f1)
 47	prev_pkgrel=$(printf "%s" "$prev_ver" | cut -d'-' -f2 | cut -d'r' -f2-)
 48	if [ "$prev_pkgver" == "$pkgver" ]
 49	then
 50		pkgrel=$((prev_pkgrel + 1))
 51		sed -e "s/pkgrel=.*/pkgrel=$pkgrel/" -i APKBUILD
 52	fi
 53)
 54
 55update_pkgver() {
 56	pkgver="$1"
 57	prev_pkgver=$(apk search -x ${project} | cut -d '-' -f2)
 58	sed -e "s/pkgver=.*/pkgver=$pkgver/" -i APKBUILD
 59	if [ "$prev_pkgver" != "$pkgver" ]
 60	then
 61		sed -e "s/pkgrel=.*/pkgrel=0/" -i APKBUILD
 62	fi
 63}
 64
 65add_repo() {
 66	set_default=0
 67	while getopts s flag
 68	do
 69		case $flag in
 70			s) set_default=1 ;;
 71			*) usage && exit 1 ;;
 72		esac
 73	done
 74	shift $((OPTIND-1))
 75	echo "$@"
 76	if [ $# -ne 2 ]
 77	then
 78		usage
 79		exit 1
 80	fi
 81	repo="$1"
 82	key="$2"
 83	mkdir -p ~/packages/$repo
 84	echo ~/packages/$repo | cat - /etc/apk/repositories > /tmp/repositories
 85	sudo mv /tmp/repositories /etc/apk/repositories
 86	if ! [ -f "$key" ]
 87	then
 88		echo "Warning: generating new abuild key"
 89		key="$HOME/.abuild/abuild.rsa"
 90		mkdir -p $HOME/.abuild
 91		(
 92			umask 0007
 93			openssl genrsa -out "$key" 2048
 94		)
 95	fi
 96	pkey="$(basename "$key").pub"
 97	sudo openssl rsa -in $key -pubout \
 98		-out /etc/apk/keys/"$pkey"
 99	cp /etc/apk/keys/"$pkey" ~/.abuild/"$pkey"
100	if [ $set_default -eq 1 ]
101	then
102		echo "PACKAGER_PRIVKEY="'"'$key'"' >> \
103			~/.abuild/abuild.conf
104	fi
105}
106
107build() (
108	builddeps=0
109	checksum=0
110	updpkgrel=0
111	pkgver=""
112	# Disable progress on abuild-apk
113	cat <<-"EOF" | sudo tee /usr/local/bin/abuild-apk
114	#!/bin/sh
115	exec /usr/bin/abuild-apk --no-progress $@
116	EOF
117	sudo chmod +x /usr/local/bin/abuild-apk
118	export PATH=/usr/local/bin:$PATH
119	while getopts Rcuv: flag
120	do
121		case $flag in
122			R) builddeps=1 ;;
123			c) checksum=1 ;;
124			u) updpkgrel=1 ;;
125			v) pkgver="$OPTARG" ;;
126			*) usage && exit 1 ;;
127		esac
128	done
129	shift $((OPTIND-1))
130	if [ $# -eq 0 ]
131	then
132		echo "No packages specified."
133		exit 1
134	fi
135	for pkg in $@
136	do
137		repo="$(find_pkg_repo "$pkg")"
138		(
139			cd "$repo"/"$pkg"
140			if [ -n "$pkgver" ]
141			then
142				update_pkgver "$pkgver"
143			fi
144			if [ $updpkgrel -eq 1 ]
145			then
146				update_pkgrel "$pkg"
147			fi
148			if [ $checksum -eq 1 ]
149			then
150				abuild checksum
151			fi
152			if [ $builddeps -eq 1 ]
153			then
154				abuild -R
155			else
156				abuild -r
157			fi
158		)
159	done
160)
161
162print_pkgver() {
163	if [ $# -ne 0 ]
164	then
165		usage
166		exit 1
167	fi
168	if [ -d .git ]
169	then
170		set +e
171		pkgver=$(git describe --abbrev=0 2>/dev/null)
172		if [ $? -ne 0 ]
173		then
174			pkgver=0
175		fi
176		set -e
177		if ! git describe --exact-match HEAD >/dev/null 2>&1
178		then
179			cdate=$(git show -s -1 --format='%ci' HEAD)
180			cdate=$(echo "$cdate" | cut -d' ' -f1 | sed -e 's/-//g')
181			pkgver="${pkgver}_git${cdate}"
182		fi
183	elif [ -d .hg ]
184	then
185		pkgver=$(hg id -T '{latesttag}')
186		if [ "$(hg id -T '{latesttagdistance}')" -ne 0 ]
187		then
188			pkgver="$(hg id -T '{latesttag}_hg{sub("-", "", date|shortdate)}')"
189		fi
190	else
191		pkgver=unknown_0000
192	fi
193	echo "$pkgver"
194}
195
196mirror_ver() (
197	mirror="$1"
198	pkg="$2"
199	apk policy "$pkg" | while read -r line
200	do
201		case "$line" in
202			*:)
203				ver="${line%:}"
204				ver="${ver## }"
205				;;
206			*$mirror*)
207				echo "$ver"
208				;;
209		esac
210	done
211)
212
213get_aver() {
214	aver="${REPOSITORY:-}"
215	if [ ${#aver} -eq 0 ]
216	then
217		. /etc/os-release
218		aver="v$(printf "%s" "$VERSION_ID" | cut -d. -f1-2)"
219	fi
220	echo "$aver"
221}
222
223upload_pkg() (
224	repo="$1"
225	pkg="$2"
226	arch="$(uname -m)"
227	aver="$(get_aver)"
228
229	set -x
230	path="$remote_path/$aver/$arch"
231	ssh "$remote" mkdir -p "$path"
232
233	url=$(echo "$remote" | cut -d@ -f2)
234	prev_ver=$(mirror_ver "$url" "$pkg")
235
236	for ver in $prev_ver
237	do
238		if [ "$prev_ver" != "none" ]
239		then
240			ssh "$remote" rm -f "$path/$pkg-$ver.apk"
241		fi
242	done
243	pkgver="$(get_pkgvar pkgver)"
244	pkgrel="$(get_pkgvar pkgrel)"
245
246	rsync --blocking-io -rsP \
247		~/packages/"$repo/$arch/$pkg-$pkgver-r$pkgrel.apk" "$remote":"$path/"
248	set +x
249)
250
251update_index() (
252	repo="$1"
253	arch="$(uname -m)"
254
255	. /etc/os-release
256	aver="$(get_aver)"
257
258	path="$remote_path/$aver/$arch"
259
260	set -x
261	ssh "$remote" \
262		find "$path" -type f -name '*.apk' -print0 |
263		ssh "$remote" xargs -0 apk index \
264			--rewrite-arch "$(uname -m)" \
265			-x "$path"/APKINDEX.tar.gz \
266			-o "$path"/APKINDEX.unsigned.tar.gz
267	rsync --blocking-io -rP \
268		"$remote:$path/APKINDEX.unsigned.tar.gz" \
269		/tmp/APKINDEX.tar.gz
270	abuild-sign /tmp/APKINDEX.tar.gz
271	rsync --blocking-io -rP /tmp/APKINDEX.tar.gz "$remote:$path/"
272	set +x
273)
274
275upload() (
276	if [ $# -lt 2 ]
277	then
278		usage
279		exit 1
280	fi
281	remote="$1"
282	remote_path="$2"
283	shift 2
284	if [ $# -eq 0 ]
285	then
286		echo "No packages specified"
287		exit 1
288	fi
289	repos=""
290	for pkg in $@
291	do
292		repo=$(find_pkg_repo "$pkg")
293		if ! echo "$repos" | grep "$repo" >/dev/null
294		then
295			repos="$repo $repos"
296		fi
297		(
298			cd "$repo"/"$pkg"
299			arch="$(get_pkgvar arch)"
300			subpkgs="$pkg:_:$arch $(get_pkgvar subpackages)"
301			for subpkg in $subpkgs
302			do
303				name="$(echo "$subpkg" | cut -d':' -f1)"
304				upload_pkg "$repo" "$name"
305			done
306		)
307	done
308	for repo in $repos
309	do
310		update_index $repo
311	done
312)
313
314if [ $# -lt 1 ]
315then
316	usage
317	exit 1
318fi
319cmd="$1"
320shift
321
322case "$cmd" in
323	add-repo)
324		add_repo "$@"
325		;;
326	build)
327		build "$@"
328		;;
329	pkgver)
330		print_pkgver "$@"
331		;;
332	upload)
333		upload "$@"
334		;;
335	help|-h)
336		usage
337		;;
338esac