Compare commits
115 Commits
Author | SHA1 | Date |
---|---|---|
Piraty | a45d12d4c3 | |
Natanael Copa | 68d6aa65f4 | |
Natanael Copa | c48f8498e7 | |
Natanael Copa | eeca95d195 | |
Natanael Copa | 5023838d60 | |
Natanael Copa | 7e7b0a5ba3 | |
Natanael Copa | 645c3c07a7 | |
Natanael Copa | e4896c01b8 | |
Sertonix | 54fd3e4117 | |
Sertonix | 855992822d | |
Sertonix | 7276042237 | |
Sertonix | 6aa8fcc012 | |
Sertonix | 20b1f47c63 | |
Sertonix | 0e325a2354 | |
Natanael Copa | 22e17446f7 | |
Sertonix | 141da52d19 | |
Sertonix | 21b5a2298d | |
Sertonix | 20c0a15856 | |
Sertonix | 1804361f61 | |
Sertonix | f0051d2658 | |
Hugo Osvaldo Barrera | d65a054bc5 | |
Sertonix | 17648366cc | |
Sertonix | 2e27c5b202 | |
Sertonix | a9053617db | |
Sertonix | 73cc75b3e0 | |
Sertonix | 08d2d81587 | |
Timo Teräs | ec11f495cd | |
Sertonix | 8588378efa | |
Hugo Osvaldo Barrera | 2e987e10ff | |
Natanael Copa | 8da2501613 | |
Sertonix | 648529aa35 | |
Sertonix | f63c117df6 | |
Jingyun Hua | e3ba1238d3 | |
Hugo Osvaldo Barrera | 1861b23f0c | |
Hugo Osvaldo Barrera | 06ee1d3cfb | |
Celeste | 19bebd8497 | |
Timothy Legge | 5710eefb63 | |
Timothy Legge | b0fb5c7038 | |
Sertonix | 4ae1b39910 | |
Celeste | 39c2b44c63 | |
Celeste | 9e336571e1 | |
Celeste | 49983f5af5 | |
Celeste | fb262fad5e | |
Celeste | db578302aa | |
Celeste | bc4efd7f0c | |
Celeste | 9b513da2f4 | |
Celeste | a9e956dc16 | |
Celeste | 9e416f782a | |
Celeste | d05bc1a4af | |
Celeste | fc863565f1 | |
Celeste | 32c0815828 | |
Celeste | 81fb95d31a | |
Celeste | 250412d18c | |
Celeste | 54550dc597 | |
Celeste | 11c96f25d6 | |
Celeste | ad9324fd52 | |
Celeste | 4a55e30881 | |
Celeste | 157e390ffa | |
Timothy Legge | 60c00a4d39 | |
Timothy Legge | 99cda3db69 | |
Timothy Legge | 1dd67c1beb | |
Timothy Legge | 9cde1ad278 | |
Celeste | 0ad7489969 | |
Timothy Legge | 726e37920c | |
Celeste | 1c017bb5d5 | |
Timothy Legge | b0f60ee85a | |
Celeste | 28edb26d5b | |
Celeste | b48c12ea86 | |
Celeste | 6a8a61f9d8 | |
Celeste | 1c771b0d6a | |
Celeste | ef6aef38b1 | |
Celeste | 41a36bca95 | |
Celeste | 3336955a4a | |
Celeste | fe072f9866 | |
Celeste | 7101d6164a | |
Celeste | 1753907af0 | |
Timothy Legge | c704644b3c | |
Celeste | 37e99da359 | |
Celeste | 0bb1482c3a | |
Timothy Legge | 505a64bfa7 | |
Sertonix | cd32e245e2 | |
Natanael Copa | 84e29d94f9 | |
Sören Tempel | acfa7d6732 | |
Natanael Copa | fab41364f7 | |
Natanael Copa | 643637dd5d | |
Natanael Copa | 3a7fdeaaf0 | |
Natanael Copa | 08126de5f2 | |
Natanael Copa | c73b8f4ca7 | |
Natanael Copa | 852bb238f3 | |
Natanael Copa | 9ed6a92107 | |
Natanael Copa | c63cae3b15 | |
Natanael Copa | fcdfd871af | |
Natanael Copa | 1332d5b171 | |
Natanael Copa | 4128fa6392 | |
Natanael Copa | a6a95ad633 | |
ptrcnull | f688130443 | |
jvoisin | dd67240f01 | |
sudotac | 9fe0d14d7e | |
sudotac | 00aa9aab12 | |
jvoisin | 65b5d578b2 | |
psykose | 28b97249fa | |
psykose | 6c20db871b | |
psykose | cc17a1cc79 | |
Iztok Fister Jr | 617df473b0 | |
psykose | d4b2415fb1 | |
psykose | 0e555d58a7 | |
psykose | fc575e8361 | |
psykose | cbca6d4f48 | |
psykose | 21faeb7f47 | |
psykose | 446b68359f | |
psykose | 873a4b6654 | |
psykose | df31829660 | |
psykose | 535afd9544 | |
psykose | 5c25099d4f | |
psykose | 9855e304c7 |
|
@ -20,3 +20,7 @@ indent_style = space
|
|||
[Makefile]
|
||||
indent_size = 8
|
||||
indent_style = tab
|
||||
|
||||
[*.yml]
|
||||
indent_size = 2
|
||||
indent_style = space
|
||||
|
|
|
@ -5,7 +5,27 @@ tests:
|
|||
image:
|
||||
name: alpinelinux/abuild-ci
|
||||
stage: verify
|
||||
script: [pwd]
|
||||
script:
|
||||
- make
|
||||
- make check
|
||||
tags:
|
||||
- docker-alpine
|
||||
- x86_64
|
||||
|
||||
build-clang:
|
||||
image:
|
||||
name: alpinelinux/abuild-ci
|
||||
stage: verify
|
||||
script: [CC=clang make]
|
||||
tags:
|
||||
- docker-alpine
|
||||
- x86_64
|
||||
|
||||
build-scan:
|
||||
image:
|
||||
name: alpinelinux/abuild-ci
|
||||
stage: verify
|
||||
script: [scan-build --status-bugs make]
|
||||
tags:
|
||||
- docker-alpine
|
||||
- x86_64
|
||||
|
|
|
@ -168,6 +168,12 @@ file.
|
|||
Specifies packages that the package replaces. This is typically
|
||||
used for packages renamed by upstream.
|
||||
|
||||
*replaces_priority*
|
||||
Specifies the numeric value that is used by apk(8) when multiple
|
||||
packages with *replaces* include the same file. It is also used
|
||||
to decide which package should define the permissions of a directory
|
||||
even without *replaces* set.
|
||||
|
||||
*subpackages*
|
||||
Specifies subpackages or split packages built with this
|
||||
package. Typically, this will include _$pkgname-dev_ for development
|
||||
|
|
6
Makefile
6
Makefile
|
@ -1,5 +1,5 @@
|
|||
PACKAGE := abuild
|
||||
VERSION := 3.11.17
|
||||
VERSION := 3.13.0
|
||||
|
||||
prefix ?= /usr
|
||||
bindir ?= $(prefix)/bin
|
||||
|
@ -11,7 +11,7 @@ SCRIPTS := abuild abuild-keygen abuild-sign newapkbuild \
|
|||
abump apkgrel buildlab apkbuild-cpan apkbuild-pypi checkapk \
|
||||
apkbuild-gem-resolver
|
||||
USR_BIN_FILES := $(SCRIPTS) abuild-tar abuild-gzsplit abuild-sudo abuild-fetch abuild-rmtemp
|
||||
MAN_1_PAGES := newapkbuild.1 abuild.1
|
||||
MAN_1_PAGES := newapkbuild.1 abuild.1 abump.1
|
||||
MAN_5_PAGES := APKBUILD.5
|
||||
SAMPLES := sample.APKBUILD sample.initd sample.confd \
|
||||
sample.pre-install sample.post-install
|
||||
|
@ -127,7 +127,7 @@ Kyuafile: tests/Kyuafile
|
|||
echo "include('tests/Kyuafile')" >> $@
|
||||
|
||||
check: $(SCRIPTS) $(USR_BIN_FILES) functions.sh tests/Kyuafile Kyuafile tests/testdata/abuild.key.pub
|
||||
kyua test || (kyua report --verbose && exit 1)
|
||||
kyua --variable parallelism=$(shell nproc) test || (kyua report --verbose && exit 1)
|
||||
|
||||
install: $(USR_BIN_FILES) $(SAMPLES) $(MAN_PAGES) default.conf abuild.conf functions.sh
|
||||
install -d $(DESTDIR)/$(bindir) $(DESTDIR)/$(sysconfdir) \
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
#define PREFIX "/var/tmp/abuild."
|
||||
|
||||
static void fail() {
|
||||
static void fail(void) {
|
||||
errx(1, "%s", strerror(errno));
|
||||
}
|
||||
|
||||
|
|
|
@ -125,9 +125,11 @@ int main(int argc, const char *argv[])
|
|||
|
||||
argv[0] = path;
|
||||
/* set our uid to root so bbsuid --install works */
|
||||
setuid(0);
|
||||
if (setuid(0) < 0)
|
||||
err(1, "setuid(0) failed");
|
||||
/* set our gid to root so apk commit hooks run with the same gid as for "sudo apk add ..." */
|
||||
setgid(0);
|
||||
if (setgid(0) < 0)
|
||||
err(1, "setgid(0) failed");
|
||||
execv(path, (char * const*)argv);
|
||||
perror(path);
|
||||
return 1;
|
||||
|
|
|
@ -221,7 +221,8 @@ static int buf_padto(struct buf *b, size_t alignment)
|
|||
newsize = (oldsize + alignment - 1) & -alignment;
|
||||
if (buf_resize(b, newsize)) return -ENOMEM;
|
||||
b->size = newsize;
|
||||
memset(b->ptr + oldsize, 0, newsize - oldsize);
|
||||
if (b->ptr)
|
||||
memset(b->ptr + oldsize, 0, newsize - oldsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -260,6 +261,8 @@ static int buf_add_ext_header_hexdump(struct buf *b, const char *hdr, const unsi
|
|||
for (i = len; i > 9; i /= 10) len++;
|
||||
|
||||
if (buf_resize(b, b->size + len)) return -ENOMEM;
|
||||
if (b->ptr == NULL)
|
||||
return 0;
|
||||
b->size += snprintf(&b->ptr[b->size], len, "%u %s=", len, hdr);
|
||||
for (i = 0; i < valuelen; i++)
|
||||
b->size += snprintf(&b->ptr[b->size], 3, "%02x", (int)value[i]);
|
||||
|
|
|
@ -6,8 +6,7 @@ abuild(1)
|
|||
|
||||
# SYNOPSIS
|
||||
|
||||
*abuild* [options] [-P _REPODEST_] [-s _SRCDEST_] [-D _DESCRIPTION_] [cmd] ...++
|
||||
*abuild* [-c] -n _PKGNAME_[-_PKGVER_]
|
||||
*abuild* [options] [-P _REPODEST_] [-s _SRCDEST_] [-D _DESCRIPTION_] [cmd] ...
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
|
@ -29,7 +28,7 @@ other related operations.
|
|||
Set APKINDEX description (default: *$repo $(git describe)*)
|
||||
|
||||
*-f*
|
||||
Force specified cmd (skip checks: apk up to date, arch, libc)
|
||||
Force specified cmd (skip checks: apk up to date, arch)
|
||||
|
||||
*-F*
|
||||
Force run as root
|
||||
|
|
169
abuild.in
169
abuild.in
|
@ -1,4 +1,5 @@
|
|||
#!/bin/ash -e
|
||||
# vim: set filetype=sh:
|
||||
|
||||
# abuild - build apk packages (light version of makepkg)
|
||||
# Copyright (c) 2008-2015 Natanael Copa <ncopa@alpinelinux.org>
|
||||
|
@ -77,17 +78,17 @@ amove() {
|
|||
d="$(pwd -L)"
|
||||
|
||||
cd "$pkgdir"
|
||||
local pattern f
|
||||
local pattern f IFS=""
|
||||
for pattern; do
|
||||
for f in ${pattern#/}; do # let shell expand the pattern
|
||||
# strip trailing /
|
||||
f=${f%/}
|
||||
if [ "${f%/*}" != "$f" ]; then
|
||||
mkdir -p "$subpkgdir/${f%/*}"
|
||||
mv -v "$pkgdir"/$f "$subpkgdir/${f%/*}"
|
||||
mv -v "$pkgdir/$f" "$subpkgdir/${f%/*}"
|
||||
else
|
||||
mkdir -p "$subpkgdir"
|
||||
mv -v "$pkgdir"/$f "$subpkgdir/"
|
||||
mv -v "$pkgdir/$f" "$subpkgdir/"
|
||||
fi
|
||||
# cleanup
|
||||
rmdir -p "$f" 2>/dev/null || rmdir -p "${f%/*}" 2>/dev/null || true
|
||||
|
@ -179,30 +180,30 @@ spell_error() {
|
|||
}
|
||||
|
||||
verify_pkgname() {
|
||||
local name=${1%%=*}
|
||||
case "$name" in
|
||||
""|*" "*|-*) return 1;;
|
||||
case $1 in
|
||||
''|*[!a-zA-Z0-9._+-]*|[!a-zA-Z0-9]*) return 1;;
|
||||
esac
|
||||
return 0
|
||||
}
|
||||
|
||||
# check if apkbuild is basically sane
|
||||
default_sanitycheck() {
|
||||
local i= j= suggestion=
|
||||
local i= j=
|
||||
msg "Checking sanity of $APKBUILD..."
|
||||
[ -z "$pkgver" ] && die "Missing pkgver in APKBUILD"
|
||||
if [ -z "$nodeps" ]; then
|
||||
$APK version --check --quiet "$pkgver" ||\
|
||||
die "$pkgver is not a valid version"
|
||||
fi
|
||||
$APK version --check --quiet -- "$pkgver"-r0 || \
|
||||
die "$pkgver is not a valid version"
|
||||
[ -z "$pkgrel" ] && die "Missing pkgrel in APKBUILD"
|
||||
# give 0 as it is always valid and give the pkgrel
|
||||
$APK version --check --quiet 0-r"$pkgrel" || \
|
||||
die "$pkgrel is not a valid pkgrel"
|
||||
# warn when p1 should be _p1
|
||||
case "$pkgver" in
|
||||
*[0-9]p[0-9]) warning "pkgver should probably be $(echo "$pkgver" | sed -E -e 's/(.*[0-9])p([0-9])/\1_p\2/')";;
|
||||
# digit+letter+digit passes the apk2 version check
|
||||
case $pkgver in
|
||||
*[0-9][a-z][0-9]*)
|
||||
die "the digit+letter+digit version format is invalid. Use suffixes instead"
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -z "$pkgdesc" ] && die "Missing pkgdesc in APKBUILD"
|
||||
[ -z "$url" ] && die "Missing url in APKBUILD"
|
||||
[ -z "$license" ] && die "Missing license in APKBUILD"
|
||||
|
@ -318,6 +319,9 @@ default_sanitycheck() {
|
|||
check_secfixes_comment || return 1
|
||||
|
||||
makedepends_has 'g++' && ! options_has toolchain && warning "g++ should not be in makedepends"
|
||||
if makedepends_has 'go' && ! options_has 'net'; then
|
||||
warning "Go packages require network connection to build. Maybe add 'net' to options"
|
||||
fi
|
||||
|
||||
if ! options_has "!check" && [ -n "$REQUIRE_CHECK" ]; then
|
||||
(unset check; . "$APKBUILD"; type check >/dev/null 2>&1) || \
|
||||
|
@ -606,13 +610,19 @@ subpkg_set() {
|
|||
fi
|
||||
}
|
||||
|
||||
arch2dir() {
|
||||
local arch="$1"
|
||||
[ "$arch" = "noarch" -o "$arch" = "all" ] && arch="$CARCH"
|
||||
printf '%s\n' "$arch"
|
||||
}
|
||||
|
||||
cleanpkg() {
|
||||
local i
|
||||
msg "Cleaning built packages..."
|
||||
rm -f "$REPODEST/$repo/src/$pkgname-$pkgver-r$pkgrel.src.tar.gz"
|
||||
for i in $allpackages; do
|
||||
subpkg_set "$i"
|
||||
rm -f "$REPODEST/$repo/${subpkgarch/noarch/$CARCH}/$subpkgname-$pkgver-r$pkgrel.apk"
|
||||
rm -f "$REPODEST/$repo/$(arch2dir "$subpkgarch")/$subpkgname-$pkgver-r$pkgrel.apk"
|
||||
done
|
||||
subpkg_unset
|
||||
|
||||
|
@ -660,7 +670,7 @@ mkusers() {
|
|||
# helper to update config.sub to a recent version
|
||||
update_config_sub() {
|
||||
find . -name config.sub | (local changed=false; while read f; do
|
||||
if ! ./$f riscv64-alpine-linux-musl 2>/dev/null; then
|
||||
if ! ./$f loongarch64-alpine-linux-musl 2>/dev/null; then
|
||||
msg "Updating $f"
|
||||
cp "$sharedir"/${f##*/} "$f" || return 1
|
||||
changed=true
|
||||
|
@ -673,7 +683,7 @@ update_config_sub() {
|
|||
# helper to update config.guess to a recent version
|
||||
update_config_guess() {
|
||||
find . -name config.guess | (local changed=false; while read f; do
|
||||
if grep -q aarch64 "$f" && grep -q ppc64le "$f" && grep -q riscv64 "$f"; then
|
||||
if grep -q aarch64 "$f" && grep -q ppc64le "$f" && grep -q riscv64 "$f" && grep -q loongarch64 "$f"; then
|
||||
msg "No update needed for $f"
|
||||
else
|
||||
msg "Updating $f"
|
||||
|
@ -768,15 +778,18 @@ targz() {
|
|||
}
|
||||
|
||||
postcheck() {
|
||||
local dir="$1" name="$2" i= e=0
|
||||
local dir="$1" name="$2" i= j= e=0
|
||||
msg "Running postcheck for $name"
|
||||
# checking for FHS compat
|
||||
if ! options_has "!fhs"; then
|
||||
for i in "$dir"/srv/* "$dir"/usr/local/* "$dir"/opt/*; do
|
||||
if [ -e "$i" ]; then
|
||||
error "Packages must not put anything under /srv, /usr/local or /opt"
|
||||
e=1
|
||||
fi
|
||||
for i in srv usr/local opt tmp var/tmp var/lock var/empty home sys proc mnt dev; do
|
||||
for j in "$dir"/"$i"/* "$dir"/"$i"/.[!.]* "$dir"/"$i"/..?*; do
|
||||
if [ -L "$j" ] || [ -e "$j" ]; then
|
||||
error "Packages must not put anything under /$i"
|
||||
e=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
done
|
||||
if [ -d "$dir"/usr/var ]; then
|
||||
error "Found /usr/var, localstatedir is most likely wrong"
|
||||
|
@ -830,7 +843,7 @@ postcheck() {
|
|||
warning "Found /usr/share/man but package name doesn't end with -doc"
|
||||
fi
|
||||
# check for uncompressed man pages
|
||||
i=$(find "$dir"/usr/share/man -name '*.[0-8]' -type f | sed "s|^$dir|\t|")
|
||||
i=$(find "$dir"/usr/share/man -name '*.[0-8]' -type f | sed -e 's/^/\t/')
|
||||
if [ -n "$i" ]; then
|
||||
error "Found uncompressed man pages:"
|
||||
echo "$i"
|
||||
|
@ -853,7 +866,7 @@ postcheck() {
|
|||
e=1
|
||||
fi
|
||||
# check directory permissions
|
||||
i=$(find "$dir" -type d -perm -777 | sed "s|^$dir|\t|")
|
||||
i=$(find "$dir" -type d -perm -777 | sed -e 's/^/\t/')
|
||||
if [ -n "$i" ]; then
|
||||
warning "World writeable directories found:"
|
||||
echo "$i"
|
||||
|
@ -861,7 +874,7 @@ postcheck() {
|
|||
# check so we dont have any suid root binaries that are not PIE
|
||||
i=$(find "$dir" -type f -perm /6000 \
|
||||
| xargs scanelf --nobanner --etype ET_EXEC \
|
||||
| sed "s|ET_EXEC $dir|\t|")
|
||||
| sed -e 's/ET_EXEC /\t/')
|
||||
if [ -n "$i" ]; then
|
||||
warning "Found non-PIE files that have SUID:"
|
||||
echo "$i"
|
||||
|
@ -1034,12 +1047,12 @@ check_maintainer() {
|
|||
check_license() {
|
||||
local ret=0
|
||||
local license_list=/usr/share/spdx/license.lst
|
||||
local exclude="AND OR WITH ( )"
|
||||
if options_has "!spdx" || ! [ -f "$license_list" ]; then
|
||||
return 0
|
||||
fi
|
||||
local IFS="$IFS()"
|
||||
local i; for i in $license; do
|
||||
list_has "$i" $exclude && continue
|
||||
list_has "$i" AND OR WITH && continue
|
||||
if ! grep -q -x -F "$i" "$license_list"; then
|
||||
ret=1
|
||||
warning "\"$i\" is not a known license"
|
||||
|
@ -1084,7 +1097,7 @@ check_depends_dev() {
|
|||
check_provides() {
|
||||
local i
|
||||
for i in $provides; do
|
||||
if [ "${i%%[<>=]*}" = "$pkgname" ]; then
|
||||
if [ "${i%%[<>=~]*}" = "$pkgname" ]; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
@ -1145,7 +1158,6 @@ prepare_metafiles() {
|
|||
if [ -n "$FAKEROOTKEY" ]; then
|
||||
echo "# using $($FAKEROOT -v)" >> "$pkginfo"
|
||||
fi
|
||||
echo "# $(date -u -d @$SOURCE_DATE_EPOCH)" >> "$pkginfo"
|
||||
cat >> "$pkginfo" <<-EOF
|
||||
pkgname = $name
|
||||
pkgver = $pkgver-r$pkgrel
|
||||
|
@ -1287,6 +1299,13 @@ prepare_command_provides() {
|
|||
if ! [ -x "$i" ] || ! [ -f "$i" ]; then
|
||||
continue
|
||||
fi
|
||||
# exclude any provides: lines for commands that has '@' because '@'
|
||||
# is used as seperator between command name and repository. This
|
||||
# avoids potential conflicts
|
||||
# ref: https://gitlab.alpinelinux.org/alpine/abuild/-/issues/10074
|
||||
case "$i" in
|
||||
*@*) continue;;
|
||||
esac
|
||||
local f=${i##*/}
|
||||
echo $f >> "$controldir"/.provides-command
|
||||
done
|
||||
|
@ -1479,14 +1498,6 @@ trace_apk_deps() {
|
|||
autodeps="$autodeps pkgconfig"
|
||||
fi
|
||||
|
||||
# special case for libpthread: we need depend on libgcc
|
||||
if [ "$CLIBC" = "uclibc" ] && [ -f "$dir"/.needs-so ] \
|
||||
&& grep -q -w '^libpthread.so.*' "$dir"/.needs-so \
|
||||
&& ! grep -q -w "^depend = libgcc" "$dir"/.PKGINFO; then
|
||||
autodeps="$autodeps libgcc"
|
||||
msg " added libgcc (due to libpthread)"
|
||||
fi
|
||||
|
||||
[ -f "$dir"/.needs-so ] && for i in $(cat "$dir"/.needs-so); do
|
||||
# first check if its provided by same apkbuild
|
||||
grep -q -w "^$sonameprefix$i" "$dir"/.provides-so 2>/dev/null && continue
|
||||
|
@ -1736,7 +1747,7 @@ scan_python3_dependency() {
|
|||
fi
|
||||
local pyver="${site_pkg_dir##*usr/lib/python}"
|
||||
pyver="${pyver%%/*}"
|
||||
if [ -n "$pyver" ]; then
|
||||
if [ -n "$pyver" ] && [ "${subpkgname:-$pkgname}" != python3 ]; then
|
||||
echo "python3~$pyver" \
|
||||
>> "$controldir"/.python3-needs
|
||||
fi
|
||||
|
@ -1776,12 +1787,14 @@ human_size() {
|
|||
create_apks() {
|
||||
local file= dir= name= ver= apk= datadir= size=
|
||||
local gzip=$(command -v pigz || echo gzip)
|
||||
rmdir "$pkgdir"/usr/lib \
|
||||
"$pkgdir"/usr/bin \
|
||||
"$pkgdir"/usr/share \
|
||||
"$pkgdir"/usr \
|
||||
"$pkgdir"/etc/ \
|
||||
2>/dev/null || :
|
||||
if ! options_has "keepdirs"; then
|
||||
rmdir "$pkgdir"/usr/lib \
|
||||
"$pkgdir"/usr/bin \
|
||||
"$pkgdir"/usr/share \
|
||||
"$pkgdir"/usr \
|
||||
"$pkgdir"/etc/ \
|
||||
2>/dev/null || :
|
||||
fi
|
||||
if ! options_has "!tracedeps"; then
|
||||
for file in "$pkgbasedir"/.control.*/.PKGINFO; do
|
||||
dir="${file%/.PKGINFO}"
|
||||
|
@ -1853,8 +1866,8 @@ create_apks() {
|
|||
abuild-sign -q control.tar.gz || exit 1
|
||||
|
||||
msg "Create $apk"
|
||||
mkdir -p "$REPODEST"/$repo/${subpkgarch/noarch/$CARCH}
|
||||
cat control.tar.gz data.tar.gz > "$REPODEST"/$repo/${subpkgarch/noarch/$CARCH}/$apk
|
||||
mkdir -p "$REPODEST/$repo/$(arch2dir "$subpkgarch")"
|
||||
cat control.tar.gz data.tar.gz > "$REPODEST/$repo/$(arch2dir "$subpkgarch")/$apk"
|
||||
)
|
||||
done
|
||||
}
|
||||
|
@ -1896,9 +1909,9 @@ update_abuildrepo_index() {
|
|||
##NOARCH: These packages are really in $CARCH and do not need their
|
||||
# own repository. --rewrite-arch is used below to make sure the index
|
||||
# thinks they are for $CARCH and apk-tools will fetch them from
|
||||
# correct URL path. Remainder of the script uses ${subpkgarch/noarch/$CARCH}
|
||||
# correct URL path. Remainder of the script uses $(arch2dir "$subpkgarch")
|
||||
# when expanding to the target repository path.
|
||||
[ "$subpkgarch" = "noarch" ] && subpkgarch="$CARCH"
|
||||
[ "$subpkgarch" = "noarch" -o "$subpkgarch" = "all" ] && subpkgarch="$CARCH"
|
||||
list_has "$subpkgarch" "$allarch" || allarch="$allarch $subpkgarch"
|
||||
done
|
||||
subpkg_unset
|
||||
|
@ -2290,17 +2303,12 @@ check_arch() {
|
|||
return $ret
|
||||
}
|
||||
|
||||
# return true if libc is not masked in options
|
||||
check_libc() {
|
||||
! options_has "!libc_$CLIBC"
|
||||
}
|
||||
|
||||
# check if package is up to date
|
||||
apk_up2date() {
|
||||
local i s
|
||||
for i in $allpackages; do
|
||||
subpkg_set "$i"
|
||||
if [ ! -f "$REPODEST/$repo/${subpkgarch/noarch/$CARCH}/$subpkgname-$pkgver-r$pkgrel.apk" ]; then
|
||||
if [ ! -f "$REPODEST/$repo/$(arch2dir "$subpkgarch")/$subpkgname-$pkgver-r$pkgrel.apk" ]; then
|
||||
subpkg_unset
|
||||
return 1
|
||||
fi
|
||||
|
@ -2315,7 +2323,7 @@ apk_up2date() {
|
|||
else
|
||||
s="$startdir/${i##*/}"
|
||||
fi
|
||||
if [ "$s" -nt "$REPODEST/$repo/${pkgarch/noarch/$CARCH}/$pkgname-$pkgver-r$pkgrel.apk" ]; then
|
||||
if [ "$s" -nt "$REPODEST/$repo/$(arch2dir "$pkgarch")/$pkgname-$pkgver-r$pkgrel.apk" ]; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
@ -2327,7 +2335,7 @@ abuildindex_up2date() {
|
|||
|
||||
for i in $allpackages; do
|
||||
subpkg_set "$i"
|
||||
local dir="$REPODEST"/$repo/${subpkgarch/noarch/$CARCH}
|
||||
local dir="$REPODEST/$repo/$(arch2dir "$subpkgarch")"
|
||||
local idx="$dir"/APKINDEX.tar.gz
|
||||
local file="$dir"/$subpkgname-$pkgver-r$pkgrel.apk
|
||||
|
||||
|
@ -2345,7 +2353,6 @@ abuildindex_up2date() {
|
|||
|
||||
up2date() {
|
||||
check_arch || return 0
|
||||
check_libc || return 0
|
||||
apk_up2date && abuildindex_up2date
|
||||
}
|
||||
|
||||
|
@ -2359,17 +2366,17 @@ calcdeps() {
|
|||
builddeps="$builddeps $i"
|
||||
done
|
||||
for i in $EXTRADEPENDS_HOST $EXTRADEPENDS_TARGET $makedepends_host; do
|
||||
[ "$pkgname" = "${i%%[<>=]*}" ] && continue
|
||||
[ "$pkgname" = "${i%%[<>=~]*}" ] && continue
|
||||
list_has $i $hostdeps && continue
|
||||
subpackages_has ${i%%[<>=]*} || hostdeps="$hostdeps $i"
|
||||
subpackages_has ${i%%[<>=~]*} || hostdeps="$hostdeps $i"
|
||||
done
|
||||
else
|
||||
[ -z "$makedepends" ] && makedepends="$makedepends_build $makedepends_host"
|
||||
want_check && makedepends="$makedepends $checkdepends"
|
||||
for i in $EXTRADEPENDS_BUILD $EXTRADEPENDS_HOST $1 $depends $makedepends; do
|
||||
[ "$pkgname" = "${i%%[<>=]*}" ] && continue
|
||||
[ "$pkgname" = "${i%%[<>=~]*}" ] && continue
|
||||
list_has $i $builddeps && continue
|
||||
subpackages_has ${i%%[<>=]*} || builddeps="$builddeps $i"
|
||||
subpackages_has ${i%%[<>=~]*} || builddeps="$builddeps $i"
|
||||
done
|
||||
hostdeps="$EXTRADEPENDS_TARGET"
|
||||
fi
|
||||
|
@ -2507,23 +2514,19 @@ rootbld() {
|
|||
return
|
||||
fi
|
||||
|
||||
apk info -eq abuild-rootbld || die "rootbld: abuild-rootbld package not installed"
|
||||
$APK info -eq abuild-rootbld || die "rootbld: abuild-rootbld package not installed"
|
||||
|
||||
[ $CBUILD = $CHOST ] || die "rootbld: set CBUILD=$CHOST to build for $CHOST"
|
||||
|
||||
if ! [ $CBUILD_ARCH = "$(apk --print-arch)" ]; then
|
||||
local cachedir=/etc/apk/cache
|
||||
if ! [ $CBUILD_ARCH = "$($APK --print-arch)" ]; then
|
||||
# cross-building, so check for binfmt registration
|
||||
local qarch="$(rootbld_qemu_arch)"
|
||||
if ! [ -f "/proc/sys/fs/binfmt_misc/$qarch" ]; then
|
||||
if ! [ -f "/proc/sys/fs/binfmt_misc/qemu-$qarch" ]; then
|
||||
warning "rootbld: binfmt registration missing for $qarch binaries"
|
||||
fi
|
||||
# TODO: it's not safe to mix a cache dir between architectures,
|
||||
# so we have to use something other than /etc/apk/cache
|
||||
# to get a cache when cross-qemu-building.
|
||||
#local cachedir=""
|
||||
else
|
||||
# not cross-building in qemu, so use host cache
|
||||
local cachedir="/etc/apk/cache"
|
||||
# Old versions of apk have cache conflicts
|
||||
$APK info -eq 'cmd:apk>=2.14.1' || cachedir=""
|
||||
fi
|
||||
|
||||
logcmd "chroot building building $repo/$pkgname-$pkgver-r$pkgrel"
|
||||
|
@ -2622,7 +2625,10 @@ rootbld() {
|
|||
--setenv CARCH "$CARCH" \
|
||||
--setenv HOME "$HOME" \
|
||||
--setenv REPODEST "$REPODEST" \
|
||||
--setenv SRCDEST "$SRCDEST" \
|
||||
--setenv ABUILD_USERDIR "$ABUILD_USERDIR" \
|
||||
${ABUILD_BOOTSTRAP:+--setenv ABUILD_BOOTSTRAP "$ABUILD_BOOTSTRAP"} \
|
||||
${APORTS_BOOTSTRAP:+--setenv APORTS_BOOTSTRAP "$APORTS_BOOTSTRAP"} \
|
||||
--setenv SOURCE_DATE_EPOCH "$SOURCE_DATE_EPOCH" \
|
||||
--setenv ABUILD_LAST_COMMIT "$ABUILD_LAST_COMMIT" \
|
||||
--setenv PATH ${USE_CCACHE:+/usr/lib/ccache/bin:}/bin:/usr/bin:/sbin:/usr/sbin \
|
||||
|
@ -2716,7 +2722,7 @@ deplist_has() {
|
|||
local i
|
||||
shift
|
||||
for i in $@; do
|
||||
i=${i%%[<>=]*}
|
||||
i=${i%%[<>=~]*}
|
||||
[ "$needle" = "$i" ] && return 0
|
||||
[ "$needle" = "!$i" ] && return 1
|
||||
done
|
||||
|
@ -2772,12 +2778,9 @@ uninstalldeps() { undeps; }
|
|||
index() { update_abuildrepo_index; }
|
||||
|
||||
all() {
|
||||
if ! [ -n "$force" ]; then
|
||||
if ! check_arch; then
|
||||
echo "Package not available for the target architecture ($CARCH). Aborting."
|
||||
return 0
|
||||
fi
|
||||
check_libc || return 0
|
||||
if ! [ -n "$force" ] && ! check_arch; then
|
||||
echo "Package not available for the target architecture ($CARCH). Aborting."
|
||||
return 0
|
||||
fi
|
||||
if up2date && [ -z "$force" ]; then
|
||||
msg "Package is up to date"
|
||||
|
@ -2840,7 +2843,7 @@ usage() {
|
|||
-c Enable colored output
|
||||
-d Disable dependency checking
|
||||
-D Set APKINDEX description (default: \$repo \$(git describe))
|
||||
-f Force specified cmd (skip checks: apk up to date, arch, libc)
|
||||
-f Force specified cmd (skip checks: apk up to date, arch)
|
||||
-F Force run as root
|
||||
-h Show this help
|
||||
-k Keep built packages, even if APKBUILD or sources are newer
|
||||
|
@ -2848,7 +2851,7 @@ usage() {
|
|||
-m Disable colors (monochrome)
|
||||
-P Set REPODEST as the repository location for created packages
|
||||
-q Quiet
|
||||
-r Install missing dependencies from system repository (using sudo)
|
||||
-r Install missing dependencies from system repository (using \$SUDO_APK)
|
||||
-s Set source package destination directory
|
||||
-v Verbose: show every command as it is run (very noisy)
|
||||
|
||||
|
@ -2864,7 +2867,7 @@ usage() {
|
|||
fetch Fetch sources to \$SRCDEST (consider: 'abuild fetch verify')
|
||||
index Regenerate indexes in \$REPODEST
|
||||
listpkg List target packages
|
||||
package Install project into $pkgdir
|
||||
package Install project into \$pkgdir
|
||||
prepare Apply patches
|
||||
rootbld Build package in clean chroot
|
||||
rootpkg Run 'package', the split functions and create apks as fakeroot
|
||||
|
@ -2938,7 +2941,7 @@ repo=${startdir%/*}
|
|||
repo=${repo##*/}
|
||||
|
||||
aportsgit=${APORTSDIR:-${startdir}}
|
||||
repo_template=$aportsgit/$repo/.rootbld-repositories
|
||||
repo_template=$startdir/../.rootbld-repositories
|
||||
|
||||
SRCDEST=${SRCDEST:-$startdir}
|
||||
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
abump(1)
|
||||
|
||||
# NAME
|
||||
|
||||
*abump* - bump pkgver in an APKBUILD file
|
||||
|
||||
# SYNOPSIS
|
||||
|
||||
*abump* [-s _CVE-1_,...] [-f _ISSUE_] [-k|--keep] _PKGNAME-1.2.3_
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
*abump* updates the *pkgver* in an APKBUILD file, updates its checksums,
|
||||
rebuilds it, and finally creates a new commit commit with the changes resulting.
|
||||
|
||||
*abump* operates looks for the specified package in nested directories inside
|
||||
the current working, assuming a layout like that of the aports repository.
|
||||
|
||||
# OPTIONS
|
||||
|
||||
*-s, --security CVE1,...*
|
||||
Include CVE in the *secfixes* comment section.
|
||||
|
||||
*-f, --fixes ISSUE*
|
||||
Include *Fixes #ISSUE* in the commit message. This will close the upstream
|
||||
issue when the commit is merged into the aports master branch.
|
||||
|
||||
*-k, --keep*
|
||||
Keep existing packages.
|
||||
|
||||
*-h, --help*
|
||||
Print help information and exit.
|
||||
|
||||
# ENVIRONMENT
|
||||
|
||||
APORTSDIR
|
||||
Force operating on an alternate directory.
|
||||
|
||||
# EXAMPLES
|
||||
|
||||
```
|
||||
abump mml-1.0.0
|
||||
abump glibmm2.68-2.78.0
|
||||
abump telegram-desktop-4.11.8
|
||||
```
|
||||
|
||||
# SEE ALSO
|
||||
|
||||
abuild(1), apkgrel(1), newapkbuild(1), APKBUILD(5), apk(8).
|
||||
|
||||
# AUTHORS
|
||||
|
||||
Natanael Copa <_ncopa@alpinelinux.org_> and open source contributors.
|
6
abump.in
6
abump.in
|
@ -73,8 +73,8 @@ fixes #${fixes#\#}
|
|||
fi
|
||||
msg "$message"
|
||||
|
||||
sed -i -e "s/^pkgver=.*/pkgver=$ver/" \
|
||||
-e "s/^pkgrel=.*/pkgrel=0/" \
|
||||
sed -i -e "s/^pkgver=[^ ]*/pkgver=$ver/" \
|
||||
-e "s/^pkgrel=[^ ]*/pkgrel=0/" \
|
||||
APKBUILD
|
||||
|
||||
$ABUILD $abuild_opts checksum all
|
||||
|
@ -96,7 +96,7 @@ fixes #${fixes#\#}
|
|||
usage() {
|
||||
cat <<-__EOF__
|
||||
$program $program_version - bump pkgver in APKBUILDs
|
||||
Usage: $program [-s CVE-1,CVE-2,...] [-f ISSUE] [-R|--recursive] [-k|--keep] PKGNAME-1.2.3 ...
|
||||
Usage: $program [-s CVE-1,CVE-2,...] [-f ISSUE] [-k|--keep] PKGNAME-1.2.3 ...
|
||||
Options:
|
||||
-s, --security CVE1,CVE-2,... Security update
|
||||
-f, --fixes ISSUE Fixes ISSUE
|
||||
|
|
1086
apkbuild-cpan.in
1086
apkbuild-cpan.in
File diff suppressed because it is too large
Load Diff
495
apkbuild-pypi.in
495
apkbuild-pypi.in
|
@ -4,50 +4,52 @@ use strict;
|
|||
use warnings;
|
||||
use autodie qw(:all);
|
||||
use feature qw(:5.14);
|
||||
use experimental 'switch';
|
||||
use LWP::UserAgent;
|
||||
use LWP::ConnCache;
|
||||
use JSON;
|
||||
use URI;
|
||||
use Text::Wrap qw(wrap $columns);
|
||||
use File::Basename qw(dirname);
|
||||
|
||||
our $packager = '';
|
||||
my %pkgmap = ();
|
||||
my %licenses = ();
|
||||
|
||||
my $template = <<'EOF';
|
||||
# Automatically generated by apkbuild-pypi, template 3
|
||||
# Automatically generated by apkbuild-pypi, template 4
|
||||
[% authors %]
|
||||
pkgname=[% pkgname %]
|
||||
#_pkgreal is used by apkbuild-pypi to find modules at PyPI
|
||||
_pkgreal=[% pkgreal %]
|
||||
pkgver=[% pkgver %]
|
||||
pkgrel=[% pkgrel %]
|
||||
#_pkgreal is used by apkbuild-pypi to find modules at PyPI
|
||||
_pkgreal=[% pkgreal %]
|
||||
pkgdesc="[% pkgdesc %]"
|
||||
provides="[% provides %]"
|
||||
replaces="[% replaces %]"
|
||||
url="http://packages.python.org/pypi/[% pkgreal %]"
|
||||
url="[% url %]"
|
||||
arch="noarch"
|
||||
license="[% license %]"
|
||||
depends="python3"
|
||||
checkdepends="python3-dev"
|
||||
makedepends="py3-setuptools"
|
||||
subpackages=""
|
||||
depends=""
|
||||
makedepends="py3-gpep517 py3-setuptools py3-wheel"
|
||||
checkdepends="py3-pytest"
|
||||
subpackages="$pkgname-pyc"
|
||||
source="[% source %]"
|
||||
builddir="$srcdir/$_pkgreal-$pkgver"
|
||||
|
||||
builddir="[% builddir %]"
|
||||
options="[% options %]"[% options_comment %]
|
||||
[% compatibility %]
|
||||
build() {
|
||||
python3 setup.py build
|
||||
gpep517 build-wheel \
|
||||
--wheel-dir .dist \
|
||||
--output-fd 3 3>&1 >&2
|
||||
}
|
||||
|
||||
check() {
|
||||
python3 setup.py test
|
||||
python3 -m venv --clear --without-pip --system-site-packages .testenv
|
||||
.testenv/bin/python3 -m installer .dist/*.whl
|
||||
.testenv/bin/python3 -m pytest
|
||||
}
|
||||
|
||||
package() {
|
||||
PYTHONPATH=$pkgdir`python3 -c "import site; print(site.getsitepackages()[0])"` \
|
||||
python3 setup.py install \
|
||||
--prefix=/usr \
|
||||
--root="$pkgdir" \
|
||||
--single-version-externally-managed
|
||||
python3 -m installer -d "$pkgdir" \
|
||||
.dist/*.whl
|
||||
}
|
||||
|
||||
EOF
|
||||
|
@ -73,14 +75,31 @@ sub read_assignments_from_file {
|
|||
my %mline = $text =~ /^(\w+)\s*=\s*\"([^\"]*)\".*$/mg;
|
||||
my %hash = ( %sline, %mline );
|
||||
|
||||
my $authors = join("\n", $text =~ /^# Contributor: .*$/mg, $text =~ /^# Maintainer: .*$/mg);
|
||||
return \%hash if $filename ne 'APKBUILD';
|
||||
my $authors = join( "\n",
|
||||
$text =~ /^# Contributor: .*$/mg,
|
||||
$text =~ /^# Maintainer: .*$/mg );
|
||||
$hash{'authors'} = $authors if length($authors) > 1;
|
||||
|
||||
my $provides = $text =~ m/provides=\"(.*)\"".*/mg;
|
||||
$hash{'provides'} = $1 if length($provides) >= 1;
|
||||
if ($text =~ m/^provides=\"(.*)\"(.*)$/m) {
|
||||
$hash{'provides'} = $1;
|
||||
$hash{'provides_comment'} = $2;
|
||||
}
|
||||
|
||||
my $requires = $text =~ m/^requires=\"(.*)\"".*$/mg;
|
||||
$hash{'requires'} = $1 if length($requires) >= 1;
|
||||
if ($text =~ m/^replaces=\"(.*)\"(.*)$/m) {
|
||||
$hash{'replaces'} = $1;
|
||||
$hash{'replaces_comment'} = $2;
|
||||
}
|
||||
|
||||
# workaround for `builddir="$srcdir"/$_pkgname-$pkgver`
|
||||
if ($text =~ m/^builddir=\"(.*)\"([^\s]*)/m) {
|
||||
$hash{'builddir'} = $1 . $2;
|
||||
}
|
||||
|
||||
if ($text =~ m/^options=\"(.*)\"(.*)$/m) {
|
||||
$hash{'options'} = $1;
|
||||
$hash{'options_comment'} = $2;
|
||||
}
|
||||
|
||||
return \%hash;
|
||||
}
|
||||
|
@ -94,6 +113,7 @@ sub map_pypi_to_apk {
|
|||
sub map_license {
|
||||
my ($license) = @_;
|
||||
|
||||
$license //= '';
|
||||
$license =~ s/ or / /g;
|
||||
|
||||
return $license;
|
||||
|
@ -101,48 +121,131 @@ sub map_license {
|
|||
|
||||
sub get_source {
|
||||
my ($distdata) = @_;
|
||||
my $pkgname = $distdata->{info}{name};
|
||||
|
||||
my $source;
|
||||
for my $url (@{$distdata->{urls}}) {
|
||||
return $url->{url} if $url->{python_version} eq 'source'
|
||||
if ($url->{python_version} eq 'source') {
|
||||
$source = URI->new($url->{url});
|
||||
last;
|
||||
}
|
||||
}
|
||||
die "Unable to locate sources for $pkgname.\n" unless $source;
|
||||
|
||||
my $filename = ($source->path_segments)[-1];
|
||||
my $pretty_path = substr($pkgname, 0, 1) . "/$pkgname";
|
||||
my $pretty_url = $source->clone;
|
||||
$pretty_url->path("/packages/source/$pretty_path/$filename");
|
||||
|
||||
my $response = $ua->head($pretty_url);
|
||||
if ($response->is_success) {
|
||||
return $pretty_url->as_string;
|
||||
} else {
|
||||
return $source->as_string;
|
||||
}
|
||||
die "Unable to locate sources for $distdata->{name}.\n";
|
||||
}
|
||||
|
||||
sub read_apkbuild {
|
||||
return read_assignments_from_file('APKBUILD');
|
||||
}
|
||||
|
||||
sub format_line {
|
||||
my $line = shift;
|
||||
return "\t" . $line . "\n";
|
||||
}
|
||||
|
||||
sub format_source {
|
||||
my $srcurl = shift;
|
||||
my $orig_src = shift;
|
||||
|
||||
$orig_src =~ s/^\s+//mg;
|
||||
$orig_src =~ s/\s+/ /g;
|
||||
|
||||
my @sources = split (/\s/, $orig_src);
|
||||
|
||||
return $srcurl if @sources <= 1;
|
||||
|
||||
shift @sources if $sources[0] =~ m/pkgver/;
|
||||
my $patches;
|
||||
for my $patch (@sources) {
|
||||
next if $patch eq "";
|
||||
$patches .= format_line($patch);
|
||||
}
|
||||
|
||||
return $srcurl . "\n" . ($patches // '') . "\t";
|
||||
}
|
||||
|
||||
sub write_apkbuild {
|
||||
my ($distdata, $apkbuild) = @_;
|
||||
|
||||
my $replaces = undef;
|
||||
my $provides = undef;
|
||||
my $authors = undef;
|
||||
my $license = undef;
|
||||
my $url = undef;
|
||||
my $pkgname = undef;
|
||||
my $pkgdesc = undef;
|
||||
my $pkgrel = 0;
|
||||
my $builddir = undef;
|
||||
my $options = undef;
|
||||
my $options_comment = undef;
|
||||
my $orig_source = "";
|
||||
|
||||
if (our $use_homepage) {
|
||||
$url =
|
||||
$distdata->{info}{project_urls}{Homepage}
|
||||
|| $distdata->{info}{home_page};
|
||||
}
|
||||
|
||||
if (defined $apkbuild) {
|
||||
$authors = $apkbuild->{authors};
|
||||
$provides = $apkbuild->{provides};
|
||||
$replaces = $apkbuild->{replaces};
|
||||
$license = $apkbuild->{license};
|
||||
$url = $apkbuild->{url};
|
||||
$pkgname = $apkbuild->{pkgname};
|
||||
$pkgdesc = $apkbuild->{pkgdesc};
|
||||
$pkgrel = $apkbuild->{pkgrel};
|
||||
$builddir = $apkbuild->{builddir};
|
||||
$options = $apkbuild->{options} if defined $apkbuild->{options};
|
||||
$options_comment = $apkbuild->{options_comment} if defined $apkbuild->{options_comment};
|
||||
$orig_source = $apkbuild->{source};
|
||||
|
||||
if ($apkbuild->{pkgver} eq $distdata->{info}{version}) {
|
||||
$pkgrel++;
|
||||
}
|
||||
}
|
||||
|
||||
my $pkgreal = $distdata->{info}{name};
|
||||
my $srcurl = get_source($distdata);
|
||||
|
||||
my %repl = (
|
||||
authors => ($authors or "# Contributor: $packager\n# Maintainer: $packager"),
|
||||
pkgname => map_pypi_to_apk($distdata->{info}{name}),
|
||||
pkgreal => $distdata->{info}{name},
|
||||
pkgname => ($pkgname or map_pypi_to_apk($pkgreal)),
|
||||
pkgreal => $pkgreal,
|
||||
pkgver => $distdata->{info}{version},
|
||||
pkgrel => $pkgrel,
|
||||
source => get_source($distdata),
|
||||
license => map_license($distdata->{info}{license}),
|
||||
pkgdesc => $distdata->{info}{summary},
|
||||
provides => ($provides or ''),
|
||||
replaces => ($replaces or ''),
|
||||
source => format_source($srcurl, $orig_source),
|
||||
license => ($license or map_license($distdata->{info}{license})),
|
||||
url => ($url or "https://pypi.org/project/${pkgreal}/"),
|
||||
pkgdesc => ($pkgdesc or $distdata->{info}{summary} or "Python module for $pkgreal"),
|
||||
builddir => ($builddir or ''),
|
||||
options => ($options or ''),
|
||||
options_comment => ($options_comment or ''),
|
||||
);
|
||||
|
||||
$repl{compatibility} = "";
|
||||
if ($replaces) {
|
||||
my $comment = $apkbuild->{'replaces_comment'} // '';
|
||||
$repl{compatibility} .= "\nreplaces=\"$replaces\"" . $comment;
|
||||
}
|
||||
if ($provides) {
|
||||
my $comment = $apkbuild->{'provides_comment'} // '';
|
||||
$repl{compatibility} .= "\nprovides=\"$provides\"" . $comment;
|
||||
}
|
||||
$repl{compatibility} .= "\n" if $replaces or $provides;
|
||||
|
||||
$repl{source} =~ s/-$repl{pkgver}/-\$pkgver/g;
|
||||
$template =~ s/\[% (.*?) %\]/$repl{$1}/g;
|
||||
|
||||
open my $fh, '>:utf8', 'APKBUILD';
|
||||
|
@ -154,8 +257,15 @@ sub write_apkbuild {
|
|||
return \%repl;
|
||||
}
|
||||
|
||||
sub unpack_source {
|
||||
system('abuild checksum unpack');
|
||||
}
|
||||
|
||||
sub prepare_tree {
|
||||
system('abuild checksum unpack prepare');
|
||||
my %options = @_;
|
||||
|
||||
unpack_source if $options{unpack};
|
||||
system('abuild prepare');
|
||||
}
|
||||
|
||||
sub find_package_name {
|
||||
|
@ -188,42 +298,172 @@ sub find_package_name {
|
|||
|
||||
sub get_data {
|
||||
my ($package) = @_;
|
||||
my $response = $ua->get("https://pypi.python.org/pypi/$package/json");
|
||||
my $response = $ua->get("https://pypi.org/pypi/$package/json");
|
||||
$response->is_success or die $response->status_line;
|
||||
my $distdata = $json->decode($response->decoded_content);
|
||||
|
||||
return $distdata;
|
||||
}
|
||||
|
||||
sub get_deps {
|
||||
my ($data) = @_;
|
||||
sub parse_requires_dist {
|
||||
my $reqs = shift;
|
||||
|
||||
chdir "src/$data->{pkgreal}-$data->{pkgver}";
|
||||
my $reqs = `python3 ./setup.py --requires`;
|
||||
# Valid PyPI regex: https://peps.python.org/pep-0508/#names
|
||||
my $pypi_regex = qr/(?i)([A-Z0-9][A-Z0-9][A-Z0-9._-]*[A-Z0-9])/;
|
||||
|
||||
my @reqs = split /\n/, $reqs;
|
||||
my @depends =
|
||||
map { m/$pypi_regex/; $1 || () }
|
||||
grep { $_ !~ m/; extra ==/ }
|
||||
@$reqs;
|
||||
|
||||
foreach my $i (0 .. $#reqs) {
|
||||
$reqs[$i] =~ s/(\(|\s+).*$//;
|
||||
$reqs[$i] = map_pypi_to_apk($reqs[$i]);
|
||||
my @checkdeps =
|
||||
map { m/$pypi_regex/; $1 || () }
|
||||
grep { m/; extra == ["'](tests|pytest)["']/ }
|
||||
@$reqs;
|
||||
|
||||
my %reqs = (
|
||||
depends => \@depends,
|
||||
checkdeps => \@checkdeps,
|
||||
);
|
||||
|
||||
return \%reqs;
|
||||
}
|
||||
|
||||
sub format_depends {
|
||||
my $deps = shift;
|
||||
|
||||
$columns = 102;
|
||||
|
||||
$deps =~ s/ {2,}/ /g;
|
||||
$deps =~ s/^\s//g;
|
||||
$deps =~ s/\s$//g;
|
||||
|
||||
if ( length($deps) >= $columns ) {
|
||||
$deps = wrap( "\t", "\t", $deps );
|
||||
}
|
||||
$deps =~ s/\s$//g;
|
||||
|
||||
chdir '../..';
|
||||
if ( length($deps) >= $columns ) {
|
||||
$deps = "\n" . $deps . "\n\t";
|
||||
}
|
||||
return $deps;
|
||||
}
|
||||
|
||||
sub get_deps {
|
||||
my ($distdata, $data) = @_;
|
||||
|
||||
my $reqs = parse_requires_dist($distdata->{info}{requires_dist});
|
||||
my %depends = ('py3-pytest' => 'py3-pytest');
|
||||
|
||||
my @depends =
|
||||
map {
|
||||
my $apkname = map_pypi_to_apk($_);
|
||||
if (exists $depends{$apkname}) { () }
|
||||
else { $depends{$apkname} = $apkname }
|
||||
}
|
||||
@{$reqs->{depends}};
|
||||
|
||||
my @checkdeps =
|
||||
map {
|
||||
my $apkname = map_pypi_to_apk($_);
|
||||
exists($depends{$apkname}) ? () : $apkname
|
||||
}
|
||||
@{$reqs->{checkdeps}};
|
||||
|
||||
my $apk = read_file('APKBUILD');
|
||||
|
||||
$reqs = join ' ', @reqs;
|
||||
my $depends = format_depends(join ' ', @depends);
|
||||
|
||||
$apk =~ s/pymakedepends=""/pymakedepends="$reqs"/;
|
||||
$apk =~ s/^depends=""/depends="$depends"/m;
|
||||
|
||||
unshift @checkdeps, 'py3-pytest';
|
||||
my $checkdeps = format_depends(join ' ', @checkdeps);
|
||||
|
||||
$apk =~ s/^checkdepends="py3-pytest"/checkdepends="$checkdeps"/m;
|
||||
|
||||
# remove empty variables
|
||||
$apk =~ s/.*=""\n//g;
|
||||
$apk =~ s/.*="".{0,}\n//g;
|
||||
|
||||
open my $fh, '>:utf8', 'APKBUILD';
|
||||
|
||||
print $fh $apk;
|
||||
|
||||
say "Requires: $reqs";
|
||||
say "Requires: @depends\n\nCheckDepends: @checkdeps";
|
||||
}
|
||||
|
||||
sub write_old_deps {
|
||||
my ($data, $apkbuild) = @_;
|
||||
|
||||
my $apk = read_file('APKBUILD');
|
||||
|
||||
if (my $depends = $apkbuild->{depends}) {
|
||||
$apk =~ s/^depends=".*"/depends="$depends"/m;
|
||||
}
|
||||
|
||||
if (my $makedeps = $apkbuild->{makedepends}) {
|
||||
if ($makedeps =~ m/py3-gpep517/) {
|
||||
$apk =~ s/^makedepends=".*"/makedepends="$makedeps"/m;
|
||||
} else {
|
||||
$apk =~ s/^makedepends="(.*)"/makedepends="$1 $makedeps"/m;
|
||||
}
|
||||
}
|
||||
|
||||
if (my $checkdeps = $apkbuild->{checkdepends}) {
|
||||
if ($checkdeps =~ m/py3-pytest/) {
|
||||
$apk =~ s/^checkdepends=".*"/checkdepends="$checkdeps"/m;
|
||||
} else {
|
||||
$apk =~ s/^checkdepends="(.*)"/checkdepends="$1 $checkdeps"/m;
|
||||
}
|
||||
}
|
||||
|
||||
# remove empty variables
|
||||
$apk =~ s/.*="".{0,}\n//g;
|
||||
|
||||
open my $fh, '>:utf8', 'APKBUILD';
|
||||
|
||||
print $fh $apk;
|
||||
}
|
||||
|
||||
sub update_builddir {
|
||||
my $apkbuild = read_apkbuild;
|
||||
my $pkgreal = $apkbuild->{'_pkgreal'};
|
||||
my $pkgname = $apkbuild->{pkgname};
|
||||
my $pkgver = $apkbuild->{pkgver};
|
||||
my $oldbuilddir = $apkbuild->{builddir};
|
||||
|
||||
my $build_path = glob("
|
||||
src/*${pkgver}/pyproject.toml
|
||||
src/*${pkgver}/setup.py
|
||||
");
|
||||
|
||||
if ($build_path) {
|
||||
my $newbuilddir = dirname($build_path);
|
||||
|
||||
$newbuilddir =~ s/src/\$srcdir/;
|
||||
$newbuilddir =~ s/$pkgreal/\$_pkgreal/;
|
||||
$newbuilddir =~ s/$pkgver/\$pkgver/;
|
||||
|
||||
my $apk = read_file('APKBUILD');
|
||||
|
||||
if ($pkgname eq $pkgreal and
|
||||
$newbuilddir eq '$srcdir/$_pkgreal-$pkgver') {
|
||||
# this will be deleted by the remove empty
|
||||
# variables regex in get_deps/write_old_deps
|
||||
$apk =~ s/^builddir=".*"/builddir=""/m;
|
||||
|
||||
$newbuilddir = '<same as default, deleted>';
|
||||
} elsif ($newbuilddir eq $oldbuilddir) {
|
||||
return;
|
||||
} else {
|
||||
$apk =~ s/^builddir=".*"/builddir="$newbuilddir"/m;
|
||||
}
|
||||
|
||||
print "\n\$builddir redefined:\n\t",
|
||||
"OLD: $oldbuilddir, NEW: $newbuilddir\n\n";
|
||||
|
||||
open my $fh, '>:utf8', 'APKBUILD';
|
||||
print $fh $apk;
|
||||
}
|
||||
}
|
||||
|
||||
my $abuild_conf = read_assignments_from_file('/etc/abuild.conf');
|
||||
|
@ -234,95 +474,104 @@ $packager = $user_abuild_conf->{PACKAGER} if $user_abuild_conf->{PACKAGER};
|
|||
|
||||
sub usage {
|
||||
say <<'EOF';
|
||||
Usage: apkbuild-pypi [create <package> | check | recreate | upgrade | update]
|
||||
Usage: apkbuild-pypi [create <package> [homepage] | check | recreate [deps] | upgrade | update]
|
||||
|
||||
In the repository root:
|
||||
create <package>: Creates an APKBUILD for <package>
|
||||
create <package> homepage: Creates an APKBUILD for <package> with url= field set to project homepage, if available
|
||||
|
||||
In the package root:
|
||||
check : Reports current & latest version of the package
|
||||
recreate : Recreates the APKBUILD
|
||||
recreate [deps] : Recreates the APKBUILD [also recalculate dependencies]
|
||||
upgrade : Upgrades to the latest version of the package
|
||||
update : Updates APKBUILD metadata
|
||||
EOF
|
||||
}
|
||||
|
||||
given ($ARGV[0]) {
|
||||
when ('create') {
|
||||
my $package = $ARGV[1];
|
||||
$package or die usage;
|
||||
if (! defined $ARGV[0]) {
|
||||
die usage;
|
||||
} elsif ($ARGV[0] eq 'create') {
|
||||
my $package = $ARGV[1];
|
||||
$package or die usage;
|
||||
|
||||
my $distdata = get_data($package);
|
||||
my $apkname = map_pypi_to_apk($package);
|
||||
my $distdata = get_data($package);
|
||||
my $apkname = map_pypi_to_apk($package);
|
||||
|
||||
mkdir $apkname;
|
||||
chdir $apkname;
|
||||
mkdir $apkname;
|
||||
chdir $apkname;
|
||||
|
||||
my $data = write_apkbuild($distdata, undef);
|
||||
prepare_tree;
|
||||
if ($ARGV[2] and $ARGV[2] eq 'homepage') { our $use_homepage = 1; }
|
||||
|
||||
get_deps($data);
|
||||
} when ('recreate') {
|
||||
my $apkbuild = read_apkbuild;
|
||||
if (! defined $apkbuild->{_pkgreal}) {
|
||||
$apkbuild->{_pkgreal} = find_package_name($apkbuild);
|
||||
}
|
||||
my $distdata = get_data($apkbuild->{_pkgreal});
|
||||
my $pkgver = $distdata->{info}{version} =~ s/^[^0-9]+//r;
|
||||
if ($pkgver ne $apkbuild->{pkgver}) {
|
||||
#Reset pkgrel on upgrade on recreate
|
||||
say "Upgrading PyPI module from $apkbuild->{pkgver} to $pkgver";
|
||||
$apkbuild->{pkgrel}=0;
|
||||
}
|
||||
my $data = write_apkbuild($distdata, $apkbuild);
|
||||
my $data = write_apkbuild($distdata, undef);
|
||||
unpack_source;
|
||||
update_builddir;
|
||||
|
||||
prepare_tree;
|
||||
get_deps($data);
|
||||
} when ('upgrade') {
|
||||
my $apkbuild = read_apkbuild;
|
||||
|
||||
if (! defined $apkbuild->{_pkgreal}) {
|
||||
$apkbuild->{_pkgreal} = find_package_name($apkbuild);
|
||||
}
|
||||
|
||||
my $distdata = get_data($apkbuild->{_pkgreal});
|
||||
|
||||
my $pkgver = $distdata->{info}{version};
|
||||
|
||||
if ($pkgver ne $apkbuild->{pkgver}) {
|
||||
say "Upgrading PyPI package from $apkbuild->{pkgver} to $pkgver";
|
||||
|
||||
my $text = read_file('APKBUILD');
|
||||
|
||||
$text =~ s/^(pkgver)=.*$/$1=$pkgver/mg or
|
||||
die "Can't find pkgver line in APKBUILD";
|
||||
$text =~ s/^(pkgrel)=.*$/$1=0/mg or
|
||||
die "Can't find pkgrel line in APKBUILD";
|
||||
|
||||
open my $fh, '>:utf8', 'APKBUILD';
|
||||
print $fh $text;
|
||||
close $fh;
|
||||
} else {
|
||||
say "Already up to date with PyPI";
|
||||
}
|
||||
} when ('check') {
|
||||
my $apkbuild = read_apkbuild;
|
||||
|
||||
if (! defined $apkbuild->{_pkgreal}) {
|
||||
$apkbuild->{_pkgreal} = find_package_name($apkbuild);
|
||||
}
|
||||
my $distdata = get_data($apkbuild->{_pkgreal});
|
||||
|
||||
my $pkgver = $distdata->{info}{version};
|
||||
|
||||
|
||||
say "$apkbuild->{pkgname}: Latest version: $pkgver Packaged version: $apkbuild->{pkgver}";
|
||||
if ($pkgver ne $apkbuild->{pkgver}) {
|
||||
exit(1);
|
||||
}
|
||||
} when ('update') {
|
||||
prepare_tree;
|
||||
} default {
|
||||
die usage;
|
||||
get_deps($distdata, $data);
|
||||
prepare_tree( unpack => 0 );
|
||||
} elsif ($ARGV[0] eq 'recreate') {
|
||||
my $apkbuild = read_apkbuild;
|
||||
if (! defined $apkbuild->{_pkgreal}) {
|
||||
$apkbuild->{_pkgreal} = find_package_name($apkbuild);
|
||||
}
|
||||
my $distdata = get_data($apkbuild->{_pkgreal});
|
||||
my $pkgver = $distdata->{info}{version} =~ s/^[^0-9]+//r;
|
||||
if ($pkgver ne $apkbuild->{pkgver}) {
|
||||
#Reset pkgrel on upgrade on recreate
|
||||
say "Upgrading PyPI module from $apkbuild->{pkgver} to $pkgver";
|
||||
$apkbuild->{pkgrel}=0;
|
||||
}
|
||||
|
||||
my $data = write_apkbuild($distdata, $apkbuild);
|
||||
unpack_source;
|
||||
update_builddir;
|
||||
|
||||
if ($ARGV[1] and $ARGV[1] eq 'deps') { get_deps($distdata, $data); }
|
||||
else { write_old_deps($data, $apkbuild); }
|
||||
prepare_tree( unpack => 0 );
|
||||
} elsif ($ARGV[0] eq 'upgrade') {
|
||||
my $apkbuild = read_apkbuild;
|
||||
|
||||
if (! defined $apkbuild->{_pkgreal}) {
|
||||
$apkbuild->{_pkgreal} = find_package_name($apkbuild);
|
||||
}
|
||||
|
||||
my $distdata = get_data($apkbuild->{_pkgreal});
|
||||
|
||||
my $pkgver = $distdata->{info}{version};
|
||||
|
||||
if ($pkgver ne $apkbuild->{pkgver}) {
|
||||
say "Upgrading PyPI package from $apkbuild->{pkgver} to $pkgver";
|
||||
|
||||
my $text = read_file('APKBUILD');
|
||||
|
||||
$text =~ s/^(pkgver)=.*$/$1=$pkgver/mg or
|
||||
die "Can't find pkgver line in APKBUILD";
|
||||
$text =~ s/^(pkgrel)=.*$/$1=0/mg or
|
||||
die "Can't find pkgrel line in APKBUILD";
|
||||
|
||||
open my $fh, '>:utf8', 'APKBUILD';
|
||||
print $fh $text;
|
||||
close $fh;
|
||||
} else {
|
||||
say "Already up to date with PyPI";
|
||||
}
|
||||
} elsif ($ARGV[0] eq 'check') {
|
||||
my $apkbuild = read_apkbuild;
|
||||
|
||||
if (! defined $apkbuild->{_pkgreal}) {
|
||||
$apkbuild->{_pkgreal} = find_package_name($apkbuild);
|
||||
}
|
||||
my $distdata = get_data($apkbuild->{_pkgreal});
|
||||
|
||||
my $pkgver = $distdata->{info}{version};
|
||||
|
||||
|
||||
say "$apkbuild->{pkgname}: Latest version: $pkgver Packaged version: $apkbuild->{pkgver}";
|
||||
if ($pkgver ne $apkbuild->{pkgver}) {
|
||||
exit(1);
|
||||
}
|
||||
} elsif ($ARGV[0] eq 'update') {
|
||||
prepare_tree( unpack => 1 );
|
||||
} else {
|
||||
die usage;
|
||||
}
|
||||
|
|
69
checkapk.in
69
checkapk.in
|
@ -17,21 +17,41 @@ fi
|
|||
|
||||
|
||||
usage() {
|
||||
cat >&2 <<-__EOF__
|
||||
cat <<-__EOF__
|
||||
$program $program_version - find ABI breakages in package upgrades
|
||||
Usage: $program
|
||||
Usage: $program [-h|--help]
|
||||
|
||||
Run in the directory of a built package.
|
||||
|
||||
Options:
|
||||
-h, --help Print this help
|
||||
|
||||
__EOF__
|
||||
}
|
||||
|
||||
args=$(getopt -o h --long help \
|
||||
-n "$program" -- "$@")
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
usage >&2
|
||||
exit 2
|
||||
fi
|
||||
eval set -- "$args"
|
||||
while true; do
|
||||
case $1 in
|
||||
-h|--help) usage; exit 0;;
|
||||
--) shift; break;;
|
||||
*) exit 1;; # getopt error
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
usage
|
||||
usage >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if ! [ -f "$ABUILD_CONF" ] && ! [ -f "$ABUILD_USERCONF" ]; then
|
||||
if ! [ -f "$ABUILD_CONF" ] && ! [ -f "$ABUILD_USERCONF" ] && ! [ -f "$ABUILD_DEFCONF" ]; then
|
||||
die "no abuild.conf found"
|
||||
fi
|
||||
|
||||
|
@ -47,7 +67,7 @@ fi
|
|||
|
||||
startdir="$PWD"
|
||||
tmpdir=$(mktemp -d -t checkpkg-script.XXXXXX)
|
||||
trap "rm -rf '$tmpdir'" INT EXIT
|
||||
trap "rm -rf '$tmpdir'; exit" INT EXIT
|
||||
cd "$tmpdir" || die "failed to create temp dir"
|
||||
|
||||
# storage for downloaded/copied apks
|
||||
|
@ -79,11 +99,16 @@ for i in $pkgname $subpackages; do
|
|||
fi
|
||||
|
||||
# For our local repo (newsize) apk info might return multiple packages, e.g. if different
|
||||
# version of the package where build previously. Filter out this specific pkgver using awk.
|
||||
newsize=$(apk info --repositories-file /dev/null --repository "$REPODEST"/$repo --size $_pkgname | \
|
||||
awk "/^${pkg//+/\\+}/ { found = 1 } /^[0-9]+/ { if (found) { print \$0; exit } }")
|
||||
oldsize=$(apk info --repositories-file "$tmpdir"/repositories --size "$_pkgname" | \
|
||||
awk '/^[0-9]+/ { print $0 }' | head -1)
|
||||
# version of the package where built previously. However, for a repo only one of pkgname=pkgver-rpkgrel can exist.
|
||||
# Filter out this specific pkgver with grep, as it can have only one match, then take the second line:
|
||||
# 7zip-23.01-r0 installed size:
|
||||
# 1668 KiB
|
||||
newsize="$(apk info --repositories-file /dev/null --repository "$REPODEST"/$repo --size $_pkgname | \
|
||||
grep -F "$pkg" -A1 | \
|
||||
tail -n1)"
|
||||
oldsize="$(apk info --repositories-file "$tmpdir"/repositories --size "$_pkgname" | \
|
||||
grep -F "$_pkgname" -A1 | \
|
||||
tail -n1)"
|
||||
|
||||
if [ "$oldsize" = "$newsize" ]; then
|
||||
msg "No size differences for $_pkgname."
|
||||
|
@ -92,15 +117,17 @@ for i in $pkgname $subpackages; do
|
|||
fi
|
||||
|
||||
apk fetch --quiet --repositories-file "$tmpdir"/repositories --stdout "$_pkgname" > apks/old.apk \
|
||||
|| die "failed to download old pkg, maybe run 'apk update'?"
|
||||
|| msg2 "Old apk for $_pkgname missing. (new package/arch? broken internet?)"
|
||||
|
||||
# pre-uncompress to not decompress twice
|
||||
# we do a decompression + tar -t for the file list, but then later we might do a full extraction for sodiff.
|
||||
# to not decompress here and then later again, store the intermediate tar
|
||||
$gunzip -c 2>/dev/null < apks/old.apk > apks/old.tar
|
||||
tar -t -f apks/old.tar 2>/dev/null | grep -v '^\.SIGN\.' | sort > "filelist-$_pkgname-old"
|
||||
$gunzip -c "$filepath" < "$filepath" > apks/new.tar
|
||||
tar -t -f apks/new.tar | grep -v '^\.SIGN\.' | sort > "filelist-$_pkgname-new"
|
||||
$gunzip -c 2>/dev/null < apks/old.apk > apks/old.tar &
|
||||
$gunzip -c "$filepath" < "$filepath" > apks/new.tar &
|
||||
wait
|
||||
tar -t -f apks/old.tar 2>/dev/null | grep -v '^\.SIGN\.' | sort > "filelist-$_pkgname-old" &
|
||||
tar -t -f apks/new.tar | grep -v '^\.SIGN\.' | sort > "filelist-$_pkgname-new" &
|
||||
wait
|
||||
|
||||
diff -U3 "filelist-$_pkgname-old" "filelist-$_pkgname-new"
|
||||
|
||||
|
@ -108,18 +135,20 @@ for i in $pkgname $subpackages; do
|
|||
echo "SODIFF:"
|
||||
|
||||
mkdir -p "$_pkgname-pkg-old" "$_pkgname-pkg-new"
|
||||
tar -C "$_pkgname-pkg-old" -x -f apks/old.tar > /dev/null
|
||||
tar -C "$_pkgname-pkg-new" -x -f apks/new.tar > /dev/null
|
||||
tar -C "$_pkgname-pkg-old" 2>/dev/null -x -f apks/old.tar > /dev/null &
|
||||
tar -C "$_pkgname-pkg-new" -x -f apks/new.tar > /dev/null &
|
||||
wait
|
||||
|
||||
# filter to things that start with -+ but strip the header (---/+++)
|
||||
diff -U0 "filelist-$_pkgname-old" "filelist-$_pkgname-new" | grep -E '^(\+|\-)[A-Za-z0-9]+' | grep '\.so' | while read -r diff_sofile; do
|
||||
diff -U0 "filelist-$_pkgname-old" "filelist-$_pkgname-new" | grep -E '^(\+|-)[A-Za-z0-9]+' | grep '\.so' | while read -r diff_sofile; do
|
||||
case "$diff_sofile" in
|
||||
-*) path="$_pkgname-pkg-old"; sofile="${diff_sofile#\-}" ;;
|
||||
+*) path="$_pkgname-pkg-new"; sofile="${diff_sofile#\+}" ;;
|
||||
esac
|
||||
|
||||
# skip symlinks
|
||||
if ! [ -L "$path"/"$sofile" ]; then
|
||||
# skip symlinks (only adds duplicate output or is dangling), and things that aren't valid elfs
|
||||
# matching .so above matches anything with .so in the name, e.g. xyz.sourceforge
|
||||
if ! [ -L "$path"/"$sofile" ] && readelf -h "$path"/"$sofile" >/dev/null 2>&1; then
|
||||
echo "$diff_sofile: " "$(objdump -p "$path"/"$sofile" | grep SONAME)"
|
||||
fi
|
||||
done
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
export CFLAGS="-Os -fstack-clash-protection -Wformat -Werror=format-security"
|
||||
export CXXFLAGS="-Os -fstack-clash-protection -Wformat -Werror=format-security -D_GLIBCXX_ASSERTIONS=1"
|
||||
export CXXFLAGS="-Os -fstack-clash-protection -Wformat -Werror=format-security"
|
||||
export CXXFLAGS="$CXXFLAGS -D_GLIBCXX_ASSERTIONS=1 -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS=1 -D_LIBCPP_ENABLE_HARDENED_MODE=1"
|
||||
export LDFLAGS="-Wl,--as-needed,-O1,--sort-common"
|
||||
export GOFLAGS="-buildmode=pie -modcacherw -trimpath -buildvcs=false"
|
||||
# Do note that these should work with at least GDC and LDC
|
||||
|
|
|
@ -98,11 +98,11 @@ readconfig() {
|
|||
[ -n "${USE_COLORS+x}" ] && _USE_COLORS="$USE_COLORS"
|
||||
[ -n "${USE_CCACHE+x}" ] && _USE_CCACHE="$USE_CCACHE"
|
||||
: ${ABUILD_DEFCONF:=${ABUILD_SHAREDIR:-$sharedir}/default.conf}
|
||||
[ -f "$ABUILD_DEFCONF" ] && . "$ABUILD_DEFCONF"
|
||||
: ${ABUILD_CONF:=$sysconfdir/abuild.conf}
|
||||
[ -f "$ABUILD_CONF" ] && . "$ABUILD_CONF"
|
||||
: ${ABUILD_USERDIR:=$HOME/.abuild}
|
||||
: ${ABUILD_USERCONF:=$ABUILD_USERDIR/abuild.conf}
|
||||
[ -f "$ABUILD_DEFCONF" ] && . "$ABUILD_DEFCONF"
|
||||
[ -f "$ABUILD_CONF" ] && . "$ABUILD_CONF"
|
||||
[ -f "$ABUILD_USERCONF" ] && . "$ABUILD_USERCONF"
|
||||
APORTSDIR=${_APORTSDIR-$APORTSDIR}
|
||||
|
||||
|
|
|
@ -141,7 +141,7 @@ abuild_fetch_locking_body() {
|
|||
pid1=\$!
|
||||
|
||||
# give enough time for abuild-fetch to call curl
|
||||
sleep 0.2
|
||||
sleep 0.5
|
||||
|
||||
# the first stamp should not exist, second instance should block the retry
|
||||
if [ -e stamp3 ]; then
|
||||
|
|
|
@ -23,13 +23,17 @@ init_tests \
|
|||
abuild_invalid_pkgnames \
|
||||
abuild_invalid_subpkgnames \
|
||||
abuild_invalid_subpkg_version \
|
||||
abuild_provide_pkgname \
|
||||
abuild_subpackage_arch \
|
||||
abuild_large_doc_subpackage \
|
||||
abuild_bigdocs \
|
||||
abuild_warn_pkgver_patch_version \
|
||||
abuild_pkgver_digit_letter_digit \
|
||||
abuild_multiline_license \
|
||||
abuild_license_spdx \
|
||||
abuild_git_ceiling \
|
||||
abuild_package_size_zero \
|
||||
abuild_package_size_nonzero \
|
||||
abuild_keepdirs \
|
||||
abuild_amove \
|
||||
abuild_doc \
|
||||
abuild_dev \
|
||||
|
@ -45,7 +49,8 @@ init_tests \
|
|||
abuild_command_provides \
|
||||
abuild_gocache_dir \
|
||||
abuild_cargo_home_dir \
|
||||
abuild_fish_comp_split
|
||||
abuild_fish_comp_split \
|
||||
abuild_deps
|
||||
|
||||
export ABUILD_SHAREDIR=$(atf_get_srcdir)/..
|
||||
export ABUILD_CONF=/dev/null
|
||||
|
@ -411,6 +416,9 @@ abuild_valid_pkgnames_body() {
|
|||
TESTSUBNAME=foo atf_check -s exit:0 \
|
||||
-e match:"Checking sanity" \
|
||||
abuild sanitycheck
|
||||
TESTNAME="more_+-2.0-complicated" atf_check -s exit:0 \
|
||||
-e match:"Checking sanity" \
|
||||
abuild sanitycheck
|
||||
}
|
||||
|
||||
abuild_invalid_pkgnames_body() {
|
||||
|
@ -426,6 +434,12 @@ abuild_invalid_pkgnames_body() {
|
|||
TESTNAME="foo with spaces" atf_check -s exit:1 \
|
||||
-e match:"Checking sanity" \
|
||||
abuild sanitycheck
|
||||
TESTNAME="width@at" atf_check -s exit:1 \
|
||||
-e match:"Checking sanity" \
|
||||
abuild sanitycheck
|
||||
TESTNAME="width=equal" atf_check -s exit:1 \
|
||||
-e match:"Checking sanity" \
|
||||
abuild sanitycheck
|
||||
}
|
||||
|
||||
abuild_invalid_subpkgnames_body() {
|
||||
|
@ -449,6 +463,42 @@ abuild_invalid_subpkg_version_body() {
|
|||
abuild all
|
||||
}
|
||||
|
||||
abuild_provide_pkgname_body() {
|
||||
init_keys
|
||||
cp -ra "$testrepo"/test-pkgname .
|
||||
cd test-pkgname
|
||||
TESTNAME=provided atf_check -s exit:1 \
|
||||
-e match:"provides must not contain" \
|
||||
abuild sanitycheck
|
||||
TESTNAME=test TESTPROVIDES='test~1' atf_check -s exit:1 \
|
||||
-e match:"provides must not contain" \
|
||||
abuild sanitycheck
|
||||
TESTNAME=test TESTPROVIDES='test=1' atf_check -s exit:1 \
|
||||
-e match:"provides must not contain" \
|
||||
abuild sanitycheck
|
||||
TESTNAME=test TESTPROVIDES='test>1' atf_check -s exit:1 \
|
||||
-e match:"provides must not contain" \
|
||||
abuild sanitycheck
|
||||
TESTNAME=test TESTPROVIDES='test<=1' atf_check -s exit:1 \
|
||||
-e match:"provides must not contain" \
|
||||
abuild sanitycheck
|
||||
}
|
||||
|
||||
abuild_subpackage_arch_body() {
|
||||
init_keys
|
||||
cp -ra "$testrepo" .
|
||||
cd testrepo/subpackage-arch
|
||||
arch="$(abuild -A)"
|
||||
|
||||
for i in noarch all "$arch"; do
|
||||
TESTSUBARCH="$i" abuild all
|
||||
|
||||
[ -f "$REPODEST/testrepo/$arch/test-pkgname-$i-1.0-r0.apk" ] || \
|
||||
atf_fail "Failed to place $i arch subpackage correctly"
|
||||
rm -rf "$REPODEST/testrepo"
|
||||
done
|
||||
}
|
||||
|
||||
abuild_large_doc_subpackage_body() {
|
||||
init_keys
|
||||
cp -ra "$testrepo"/large-doc-subpkg .
|
||||
|
@ -467,14 +517,11 @@ abuild_bigdocs_body() {
|
|||
abuild all
|
||||
}
|
||||
|
||||
abuild_warn_pkgver_patch_version_body() {
|
||||
abuild_pkgver_digit_letter_digit_body() {
|
||||
cp -ra "$testrepo"/test-pkgname .
|
||||
cd test-pkgname
|
||||
TESTPKGVER=1.0_p1 atf_check -s exit:0 \
|
||||
-e not-match:'WARNING' \
|
||||
abuild sanitycheck
|
||||
TESTPKGVER=1.0p1 atf_check -s exit:0 \
|
||||
-e match:'WARNING.*1.0_p1' \
|
||||
TESTPKGVER=1.0p1 atf_check -s exit:1 \
|
||||
-e match:'ERROR.*version' \
|
||||
abuild sanitycheck
|
||||
}
|
||||
|
||||
|
@ -482,10 +529,18 @@ abuild_multiline_license_body() {
|
|||
cp -ra "$testrepo"/test-licenses .
|
||||
cd test-licenses
|
||||
abuild rootpkg
|
||||
atf_check -o match:'^license = MIT AND GPL-3.0-only OR GPL-3.0-or-later AND BSD-Clause-4$' \
|
||||
atf_check -o match:'^license = MIT AND \(GPL-3.0-only OR GPL-3.0-or-later AND BSD-Clause-4\)$' \
|
||||
cat pkg/.control.test-licenses/.PKGINFO
|
||||
}
|
||||
|
||||
abuild_license_spdx_body() {
|
||||
cp -ra "$testrepo"/test-licenses .
|
||||
cd test-licenses
|
||||
TESTPKGVER=1.0_p1 atf_check -s exit:0 \
|
||||
-e not-match:'WARNING' \
|
||||
abuild sanitycheck
|
||||
}
|
||||
|
||||
abuild_git_ceiling_body() {
|
||||
init_keys
|
||||
git init
|
||||
|
@ -587,6 +642,32 @@ abuild_package_size_nonzero_body() {
|
|||
cat pkg/.control.test-size/.PKGINFO
|
||||
}
|
||||
|
||||
abuild_keepdirs_body() {
|
||||
init_keys
|
||||
mkdir -p test-amove
|
||||
|
||||
cd test-amove
|
||||
cat > APKBUILD <<-EOF
|
||||
# Maintainer: Test User 123 <123@example.com>
|
||||
|
||||
# test package
|
||||
pkgname="test-keepdirs"
|
||||
pkgver="1.0"
|
||||
pkgrel=0
|
||||
pkgdesc='Dummy test package - keepdirs'
|
||||
url='https://gitlab.alpinelinux.org/alpine/aports'
|
||||
arch='noarch'
|
||||
license='MIT'
|
||||
options='keepdirs'
|
||||
|
||||
package() {
|
||||
mkdir -p "\$pkgdir"/usr/bin
|
||||
}
|
||||
EOF
|
||||
abuild rootpkg || atf_fail "abuild rootpkg failed"
|
||||
test -d pkg/test-keepdirs/usr/bin || atf_fail "$i failed"
|
||||
}
|
||||
|
||||
abuild_amove_body() {
|
||||
init_keys
|
||||
mkdir -p test-amove
|
||||
|
@ -608,7 +689,8 @@ abuild_amove_body() {
|
|||
\$pkgname-bin:_bin
|
||||
\$pkgname-sbin:_sbin
|
||||
\$pkgname-var:_var
|
||||
\$pkgname-usr:_usr"
|
||||
\$pkgname-usr:_usr
|
||||
\$pkgname-space:_space"
|
||||
|
||||
package() {
|
||||
mkdir -p "\$pkgdir"/etc \
|
||||
|
@ -620,6 +702,7 @@ abuild_amove_body() {
|
|||
"\$pkgdir"/etc/\$pkgname.conf \
|
||||
"\$pkgdir"/bin/hello \
|
||||
"\$pkgdir"/sbin/shello \
|
||||
"\$pkgdir"/sbin/space' ' \
|
||||
"\$pkgdir"/var/lib/\$pkgname/testfile \
|
||||
"\$pkgdir"/usr/share/a \
|
||||
"\$pkgdir"/usr/share/b
|
||||
|
@ -647,6 +730,10 @@ abuild_amove_body() {
|
|||
# glob *
|
||||
amove usr/share/*
|
||||
}
|
||||
_space() {
|
||||
# with space
|
||||
amove sbin/space' '
|
||||
}
|
||||
|
||||
EOF
|
||||
abuild rootpkg || atf_fail "abuild rootpkg failed"
|
||||
|
@ -658,8 +745,9 @@ abuild_amove_body() {
|
|||
test-amove-var/var/lib/test-amove/testfile \
|
||||
test-amove-usr/usr/share/a \
|
||||
test-amove-usr/usr/share/b \
|
||||
test-amove-space/sbin/space' ' \
|
||||
; do \
|
||||
test -f pkg/$i || atf_fail "$i failed"
|
||||
test -f pkg/"$i" || atf_fail "$i failed"
|
||||
done
|
||||
}
|
||||
|
||||
|
@ -830,7 +918,7 @@ abuild_cleanoldpkg_body() {
|
|||
mkdir -p "\$pkgdir"
|
||||
}
|
||||
EOF
|
||||
CARCH=$arch atf_check -e not-empty abuild
|
||||
CARCH=$arch atf_check -e not-empty abuild clean unpack rootpkg
|
||||
done
|
||||
done
|
||||
|
||||
|
@ -950,14 +1038,35 @@ abuild_setcap_binary_with_option_body() {
|
|||
|
||||
abuild_command_provides_body() {
|
||||
init_keys
|
||||
cp -ra "$testrepo"/bin-in-path .
|
||||
cd bin-in-path
|
||||
mkdir testprovides
|
||||
cd testprovides
|
||||
cat >APKBUILD<<-EOF
|
||||
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
|
||||
pkgname=testprovides
|
||||
pkgver=1.0
|
||||
pkgrel=0
|
||||
pkgdesc="Dummy test package that installs a file and directory in path"
|
||||
url="https://gitlab.alpinelinux.org/alpine/aports"
|
||||
arch="noarch"
|
||||
license="MIT"
|
||||
prepare() { mkdir -p "\$builddir"; }
|
||||
build() { true; }
|
||||
check() { true; }
|
||||
package() {
|
||||
mkdir -p "\$pkgdir/usr/bin"
|
||||
printf "%s\n" '#!/bin/sh' >"\$pkgdir/usr/bin/foo"
|
||||
chmod +x "\$pkgdir/usr/bin/foo"
|
||||
cp -a "\$pkgdir/usr/bin/foo" "\$pkgdir/usr/bin/foo@"
|
||||
mkdir -p "\$pkgdir/usr/bin/dir/"
|
||||
}
|
||||
EOF
|
||||
abuild rootpkg
|
||||
|
||||
atf_check \
|
||||
-o match:"provides = cmd:foo=1.0-r0" \
|
||||
-o not-match:"provides = cmd:foo@=1.0-r0" \
|
||||
-o not-match:"provides = cmd:dir=1.0-r0" \
|
||||
grep '^provides = ' pkg/.control.bin-in-path/.PKGINFO
|
||||
grep '^provides = ' pkg/.control.testprovides/.PKGINFO
|
||||
}
|
||||
|
||||
abuild_gocache_dir_body() {
|
||||
|
@ -984,6 +1093,7 @@ abuild_gocache_dir_body() {
|
|||
}
|
||||
EOF
|
||||
|
||||
unset GOCACHE
|
||||
MOVE_CACHES=1 \
|
||||
atf_check -s exit:0 \
|
||||
-o match:"dir:.*/tmp/go" \
|
||||
|
@ -1014,6 +1124,7 @@ abuild_cargo_home_dir_body() {
|
|||
}
|
||||
EOF
|
||||
|
||||
unset CARGO_HOME
|
||||
MOVE_CACHES=1 \
|
||||
atf_check -s exit:0 \
|
||||
-o match:"dir:.*/tmp/cargo" \
|
||||
|
@ -1061,3 +1172,74 @@ abuild_fish_comp_split_body() {
|
|||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
create_mock_apk() {
|
||||
mkdir -p bin
|
||||
cat > bin/apk <<-EOF
|
||||
#!/bin/sh
|
||||
if [ "\$1" = "--print-arch" ]; then
|
||||
echo 'aarch64'
|
||||
exit 0
|
||||
fi
|
||||
echo apk "\$@" >&2
|
||||
EOF
|
||||
chmod +x bin/apk
|
||||
ln -s apk bin/abuild-apk
|
||||
PATH="$PWD/bin:$PATH"
|
||||
}
|
||||
|
||||
abuild_deps_body() {
|
||||
create_mock_apk
|
||||
mkdir testdeps
|
||||
cd testdeps
|
||||
cat >APKBUILD <<-EOF
|
||||
# Maintainer: Joe User <juser@example.com>
|
||||
pkgname="testdeps"
|
||||
pkgver="1.0"
|
||||
pkgrel=0
|
||||
pkgdesc="Dummy test package"
|
||||
url="https://gitlab.alpinelinux.org/alpine/aports"
|
||||
arch="noarch"
|
||||
license="MIT"
|
||||
depends="foo"
|
||||
makedepends="bar"
|
||||
checkdepends="checkdep"
|
||||
makedepends_host="hostdep"
|
||||
makedepends_build="builddep"
|
||||
EOF
|
||||
|
||||
# native build. pull in both depends and makedepends
|
||||
# do not install in any --root
|
||||
atf_check \
|
||||
-e match:'Installing for build: foo bar checkdep$' \
|
||||
-e match:'apk add .*--virtual .makedepends-testdeps foo bar checkdep' \
|
||||
-e not-match:'apk add .*--root' \
|
||||
abuild deps
|
||||
|
||||
# dont install checkdep with ABUILD_BOOTSTRAP
|
||||
ABUILD_BOOTSTRAP=1 atf_check \
|
||||
-e not-match:"apk add.*checkdep" \
|
||||
abuild deps
|
||||
|
||||
# crosscompile:
|
||||
# install makedepends_build without --root
|
||||
# install makedepends_host with --root
|
||||
CTARGET='s390x' CHOST='ppc64le' CBUILDROOT="$PWD/root" atf_check \
|
||||
-e match:'Installing for build: builddep' \
|
||||
-e match:'Installing for host: hostdep' \
|
||||
-e match:'apk add .*--virtual .makedepends-testdeps builddep' \
|
||||
-e not-match:'apk add.*--root.*builddep' \
|
||||
-e match:'apk add .*--root.*hostdep' \
|
||||
-e match:'apk add .*--arch s390x.*hostdep' \
|
||||
-e not-match:'apk add.*checkdep' \
|
||||
abuild deps
|
||||
|
||||
# crosscompile, set only CHOST
|
||||
CHOST='armhf' atf_check \
|
||||
-e match:'apk add.*builddep' \
|
||||
-e not-match:'apk add.*--root.*builddep' \
|
||||
-e match:'apk add.*--root.*--arch armhf.*hostdep' \
|
||||
-e not-match:'apk add.*--arch armhf.*builddep' \
|
||||
abuild deps
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
#!/usr/bin/env atf-sh
|
||||
|
||||
. $(atf_get_srcdir)/test_env.sh
|
||||
init_tests \
|
||||
checkapk_help \
|
||||
checkapk_invalid_opt \
|
||||
checkapk_missing_abuild_conf \
|
||||
checkapk_missing_apkbuild
|
||||
|
||||
DATADIR=$(atf_get_srcdir)/testdata
|
||||
|
||||
export ABUILD_SHAREDIR=$(atf_get_srcdir)/..
|
||||
export ABUILD_CONF=/dev/null
|
||||
export ABUILD_USERCONF=/dev/null
|
||||
|
||||
checkapk_help_body() {
|
||||
atf_check -s exit:0 \
|
||||
-o match:"Usage:" \
|
||||
checkapk --help
|
||||
}
|
||||
|
||||
checkapk_invalid_opt_body() {
|
||||
atf_check -s not-exit:0 \
|
||||
-e match:"Usage:" \
|
||||
checkapk --invalid
|
||||
}
|
||||
|
||||
checkapk_missing_abuild_conf_body() {
|
||||
ABUILD_DEFCONF=/dev/null atf_check \
|
||||
-s not-exit:0 \
|
||||
-e match:"no abuild.conf found" \
|
||||
checkapk
|
||||
}
|
||||
|
||||
checkapk_missing_apkbuild_body() {
|
||||
atf_check \
|
||||
-s not-exit:0 \
|
||||
-e match:"must be run in the directory of a built package" \
|
||||
checkapk
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
|
||||
|
||||
# test package
|
||||
pkgname=bin-in-path
|
||||
pkgver=1.0
|
||||
pkgrel=0
|
||||
pkgdesc="Dummy test package that installs a file and directory in path"
|
||||
url="https://gitlab.alpinelinux.org/alpine/aports"
|
||||
arch="noarch"
|
||||
license="MIT"
|
||||
source=""
|
||||
|
||||
prepare() {
|
||||
mkdir -p "$builddir"
|
||||
}
|
||||
|
||||
build() {
|
||||
true
|
||||
}
|
||||
|
||||
check() {
|
||||
true
|
||||
}
|
||||
|
||||
package() {
|
||||
mkdir -p "$pkgdir/usr/bin"
|
||||
cat >"$pkgdir/usr/bin/foo" <<EOF
|
||||
#!/bin/sh
|
||||
EOF
|
||||
chmod +x "$pkgdir/usr/bin/foo"
|
||||
mkdir -p "$pkgdir/usr/bin/dir/"
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
|
||||
|
||||
# test package
|
||||
pkgname=${TESTNAME-test-pkgname}
|
||||
pkgver="${TESTPKGVER-1.0}"
|
||||
pkgrel=0
|
||||
pkgdesc="Dummy subpackage arch"
|
||||
url="https://gitlab.alpinelinux.org/alpine/aports"
|
||||
arch="noarch"
|
||||
license="MIT"
|
||||
subpackages="$pkgname-$TESTSUBARCH:_sub:$TESTSUBARCH"
|
||||
options="!archcheck"
|
||||
|
||||
check() {
|
||||
true
|
||||
}
|
||||
|
||||
package() {
|
||||
mkdir -p "$pkgdir"
|
||||
}
|
||||
|
||||
_sub() {
|
||||
mkdir -p "$subpkgdir"
|
||||
}
|
|
@ -8,10 +8,10 @@ pkgdesc='Dummy test package that has multi-line licenses'
|
|||
url='https://gitlab.alpinelinux.org/alpine/aports'
|
||||
arch='noarch'
|
||||
license='MIT AND
|
||||
GPL-3.0-only OR
|
||||
(GPL-3.0-only OR
|
||||
|
||||
GPL-3.0-or-later AND
|
||||
BSD-Clause-4
|
||||
BSD-Clause-4)
|
||||
'
|
||||
|
||||
prepare() {
|
||||
|
|
|
@ -8,6 +8,7 @@ pkgdesc="Dummy test package that fails to build"
|
|||
url="https://gitlab.alpinelinux.org/alpine/aports"
|
||||
arch="noarch"
|
||||
license="MIT"
|
||||
provides="${TESTPROVIDES-provided}"
|
||||
subpackages="${TESTSUBNAME-$pkgname-sub}:_sub"
|
||||
|
||||
prepare() {
|
||||
|
|
Loading…
Reference in New Issue