Read PKGBUILD variables with CARCH set and refuse to queue a package whose version cannot be read
makepkg always exports CARCH, so PKGBUILDs may branch on it at file scope. Every place the tooling sourced a PKGBUILD did so without CARCH, taking the wrong branch or aborting partway, and check-versions turned the resulting empty pkgver/pkgrel into the version '-', which never matches a published version and queues an endless rebuild. package_pkgbuild_var reads one variable the way makepkg would see it, for the architecture being checked, and reports whether the source succeeded. check-versions, sync-rebuilds and omarchy-pkgs use it. check-versions now warns and skips a package whose pkgver or pkgrel is empty instead of comparing a partial version. A self-test covers a PKGBUILD that branches on CARCH before assigning its version.
This commit is contained in:
4 files changed
+70
-10
No files matched your search
+23
-8
@@ -79,10 +79,26 @@ get_repo_version() {
|
|||||||
'
|
'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# The PKGBUILD's full version (epoch:pkgver-pkgrel) for the architecture being
|
||||||
|
# checked. Prints nothing when pkgver or pkgrel cannot be read: a partial
|
||||||
|
# version like "-" would compare unequal to everything published and queue a
|
||||||
|
# rebuild on every tick, so an unreadable PKGBUILD must not queue at all.
|
||||||
get_pkgbuild_version() {
|
get_pkgbuild_version() {
|
||||||
local pkgdir="$1"
|
local pkgdir="$1"
|
||||||
if [[ -f "$pkgdir/PKGBUILD" ]]; then
|
local epoch pkgver pkgrel
|
||||||
(cd "$pkgdir" && bash -c 'source PKGBUILD 2>/dev/null; if [[ -n "$epoch" ]]; then echo "${epoch}:${pkgver}-${pkgrel}"; else echo "${pkgver}-${pkgrel}"; fi')
|
|
||||||
|
[[ -f "$pkgdir/PKGBUILD" ]] || return 1
|
||||||
|
|
||||||
|
epoch=$(package_pkgbuild_var "$pkgdir" epoch "$ARCH")
|
||||||
|
pkgver=$(package_pkgbuild_var "$pkgdir" pkgver "$ARCH")
|
||||||
|
pkgrel=$(package_pkgbuild_var "$pkgdir" pkgrel "$ARCH")
|
||||||
|
|
||||||
|
[[ -n "$pkgver" && -n "$pkgrel" ]] || return 1
|
||||||
|
|
||||||
|
if [[ -n "$epoch" ]]; then
|
||||||
|
echo "${epoch}:${pkgver}-${pkgrel}"
|
||||||
|
else
|
||||||
|
echo "${pkgver}-${pkgrel}"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,8 +113,8 @@ check_vcs_unchanged() {
|
|||||||
|
|
||||||
# If epoch or pkgrel changed in PKGBUILD, release even if upstream is unchanged.
|
# If epoch or pkgrel changed in PKGBUILD, release even if upstream is unchanged.
|
||||||
local pkgbuild_epoch pkgbuild_pkgrel
|
local pkgbuild_epoch pkgbuild_pkgrel
|
||||||
pkgbuild_epoch=$(cd "$pkgdir" && bash -c 'source PKGBUILD 2>/dev/null; echo "${epoch:-}"')
|
pkgbuild_epoch=$(package_pkgbuild_var "$pkgdir" epoch "$ARCH")
|
||||||
pkgbuild_pkgrel=$(cd "$pkgdir" && bash -c 'source PKGBUILD 2>/dev/null; echo "${pkgrel}"')
|
pkgbuild_pkgrel=$(package_pkgbuild_var "$pkgdir" pkgrel "$ARCH")
|
||||||
|
|
||||||
local repo_pkgrel="${repo_version##*-}"
|
local repo_pkgrel="${repo_version##*-}"
|
||||||
local repo_no_pkgrel="${repo_version%-*}"
|
local repo_no_pkgrel="${repo_version%-*}"
|
||||||
@@ -126,12 +142,11 @@ check_package() {
|
|||||||
local mirror="$3"
|
local mirror="$3"
|
||||||
|
|
||||||
local pkgbuild_version repo_version
|
local pkgbuild_version repo_version
|
||||||
pkgbuild_version=$(get_pkgbuild_version "$pkgdir")
|
if ! pkgbuild_version=$(get_pkgbuild_version "$pkgdir") || [[ -z "$pkgbuild_version" ]]; then
|
||||||
repo_version=$(get_repo_version "$pkg" "$mirror")
|
print_warning "$pkg: could not read pkgver/pkgrel from its PKGBUILD for $ARCH — not queueing"
|
||||||
|
|
||||||
if [[ -z "$pkgbuild_version" ]]; then
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
repo_version=$(get_repo_version "$pkg" "$mirror")
|
||||||
|
|
||||||
if grep -qE '^pkgver[[:space:]]*\(\)' "$pkgdir/PKGBUILD"; then
|
if grep -qE '^pkgver[[:space:]]*\(\)' "$pkgdir/PKGBUILD"; then
|
||||||
if [[ -n "$repo_version" && -n "$(package_extract_vcs_hash_from_version "$repo_version")" ]]; then
|
if [[ -n "$repo_version" && -n "$(package_extract_vcs_hash_from_version "$repo_version")" ]]; then
|
||||||
|
|||||||
+2
-1
@@ -21,6 +21,7 @@ BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/..")
|
|||||||
source "$BUILD_ROOT/helpers/message-helpers.sh"
|
source "$BUILD_ROOT/helpers/message-helpers.sh"
|
||||||
source "$BUILD_ROOT/helpers/paths.sh"
|
source "$BUILD_ROOT/helpers/paths.sh"
|
||||||
source "$BUILD_ROOT/helpers/host-helpers.sh"
|
source "$BUILD_ROOT/helpers/host-helpers.sh"
|
||||||
|
source "$BUILD_ROOT/helpers/package-metadata.sh"
|
||||||
|
|
||||||
UPSTREAM_URL="${OMARCHY_UPSTREAM_URL:-https://github.com/basecamp/omarchy.git}"
|
UPSTREAM_URL="${OMARCHY_UPSTREAM_URL:-https://github.com/basecamp/omarchy.git}"
|
||||||
EDGE_DB_URL="${OMARCHY_EDGE_DB_URL:-https://pkgs.omarchy.org/edge/$(reference_arch)/omarchy.db.tar.zst}"
|
EDGE_DB_URL="${OMARCHY_EDGE_DB_URL:-https://pkgs.omarchy.org/edge/$(reference_arch)/omarchy.db.tar.zst}"
|
||||||
@@ -92,7 +93,7 @@ version_is_rc() { version_is_prerelease "$1"; }
|
|||||||
|
|
||||||
pkgbuild_var() {
|
pkgbuild_var() {
|
||||||
local pkg="$1" var="$2"
|
local pkg="$1" var="$2"
|
||||||
(cd "$BUILD_ROOT/pkgbuilds/$pkg" && bash -c "source PKGBUILD 2>/dev/null; echo \"\${$var}\"")
|
package_pkgbuild_var "$BUILD_ROOT/pkgbuilds/$pkg" "$var"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Prints the published version of $pkg from the edge DB. Distinguishes
|
# Prints the published version of $pkg from the edge DB. Distinguishes
|
||||||
|
|||||||
+21
-1
@@ -237,7 +237,7 @@ pkgbuild_field() {
|
|||||||
local package_dir="$1"
|
local package_dir="$1"
|
||||||
local field="$2"
|
local field="$2"
|
||||||
|
|
||||||
(cd "$package_dir" && env -u OMARCHY_SRC bash -c "source PKGBUILD 2>/dev/null; echo \"\${$field:-}\"")
|
package_pkgbuild_var "$package_dir" "$field"
|
||||||
}
|
}
|
||||||
|
|
||||||
# 2 -> 3, and 1.1 -> 1.2. Anything else is a pkgrel this command has no business
|
# 2 -> 3, and 1.1 -> 1.2. Anything else is a pkgrel this command has no business
|
||||||
@@ -781,6 +781,26 @@ cmd_self_test() {
|
|||||||
unset SELFTEST_ARCHES
|
unset SELFTEST_ARCHES
|
||||||
check "pkgrel untouched" 1 "$(pkgrel_of "$root/pkgbuilds/t-x86")"
|
check "pkgrel untouched" 1 "$(pkgrel_of "$root/pkgbuilds/t-x86")"
|
||||||
|
|
||||||
|
echo "A PKGBUILD that branches on CARCH at file scope still reads its version:"
|
||||||
|
root=$(selftest_root carch-branch)
|
||||||
|
mkdir -p "$root/pkgbuilds/t-carch/.omarchy"
|
||||||
|
cat > "$root/pkgbuilds/t-carch/PKGBUILD" <<'PKG'
|
||||||
|
pkgname=t-carch
|
||||||
|
case "$CARCH" in
|
||||||
|
x86_64) _suffix=x64 ;;
|
||||||
|
aarch64) _suffix=arm64 ;;
|
||||||
|
*) return 1 ;;
|
||||||
|
esac
|
||||||
|
pkgver=1.0
|
||||||
|
pkgrel=3
|
||||||
|
arch=(x86_64 aarch64)
|
||||||
|
PKG
|
||||||
|
echo '{"source":"local"}' > "$root/pkgbuilds/t-carch/.omarchy/package.json"
|
||||||
|
check "pkgver read for x86_64" "1.0" "$(package_pkgbuild_var "$root/pkgbuilds/t-carch" pkgver x86_64)"
|
||||||
|
check "pkgrel read for x86_64" "3" "$(package_pkgbuild_var "$root/pkgbuilds/t-carch" pkgrel x86_64)"
|
||||||
|
check "arch-specific value follows CARCH" "arm64" "$(package_pkgbuild_var "$root/pkgbuilds/t-carch" _suffix aarch64)"
|
||||||
|
check "unsupported arch reports failure" 1 "$(package_pkgbuild_var "$root/pkgbuilds/t-carch" pkgver armv7h >/dev/null; echo $?)"
|
||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
if [[ "$failures" -eq 0 ]]; then
|
if [[ "$failures" -eq 0 ]]; then
|
||||||
print_success "Self-test passed"
|
print_success "Self-test passed"
|
||||||
|
|||||||
@@ -144,6 +144,30 @@ package_has_pkgbuild() {
|
|||||||
[[ -f "$pkgdir/PKGBUILD" ]]
|
[[ -f "$pkgdir/PKGBUILD" ]]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Read one variable from a PKGBUILD the way makepkg would see it.
|
||||||
|
#
|
||||||
|
# makepkg always exports CARCH, so PKGBUILDs may branch on it at file scope
|
||||||
|
# (per-architecture sources, tarball suffixes, even `return` for an
|
||||||
|
# unsupported architecture). Sourcing without CARCH takes the wrong branch or
|
||||||
|
# aborts partway, which leaves pkgver and pkgrel empty — and an empty version
|
||||||
|
# never equals the published one, so the package is queued for a rebuild that
|
||||||
|
# promotion then refuses. Every read of a PKGBUILD goes through here.
|
||||||
|
#
|
||||||
|
# Prints the value; exit status is that of `source PKGBUILD` itself, so a
|
||||||
|
# caller can tell "variable empty" from "PKGBUILD could not be read".
|
||||||
|
package_pkgbuild_var() {
|
||||||
|
local pkgdir="$1"
|
||||||
|
local var="$2"
|
||||||
|
local arch="${3:-${ARCH:-x86_64}}"
|
||||||
|
|
||||||
|
(cd "$pkgdir" && env -u OMARCHY_SRC CARCH="$arch" bash -c '
|
||||||
|
source PKGBUILD >/dev/null 2>&1
|
||||||
|
rc=$?
|
||||||
|
printf "%s\n" "${!1:-}"
|
||||||
|
exit "$rc"
|
||||||
|
' _ "$var")
|
||||||
|
}
|
||||||
|
|
||||||
# The architectures declared by a PKGBUILD. Set CARCH while reading it so a
|
# The architectures declared by a PKGBUILD. Set CARCH while reading it so a
|
||||||
# conditional arch=() assignment is evaluated for the architecture we are
|
# conditional arch=() assignment is evaluated for the architecture we are
|
||||||
# actually checking, even when the repository host is a different one.
|
# actually checking, even when the repository host is a different one.
|
||||||
|
|||||||
Reference in new issue
Block a user