#!/bin/bash # Check PKGBUILD versions against published repo versions # Creates state files for edge and/or stable if any packages need building set -e BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/..") source "$BUILD_ROOT/helpers/message-helpers.sh" source "$BUILD_ROOT/helpers/paths.sh" source "$BUILD_ROOT/helpers/package-metadata.sh" source "$BUILD_ROOT/helpers/lock-helpers.sh" STATE_DIR="${OMARCHY_STATE_DIR:-/root/.state}" ARCH="${ARCH:-x86_64}" PULL=false [[ "${1:-}" == "--pull" ]] && PULL=true mkdir -p "$STATE_DIR" # Runs on a tight schedule, so it must never disturb a build in progress: # comparing versions reads the PKGBUILDs a running build is reading, and # --pull would swap them underneath it. Take the lock non-blocking and skip # the tick when a release owns it — the queue is unchanged, so the next tick # picks up exactly where this one left off. if ! try_release_lock; then exit 0 fi print_header "Package Version Check" # The scheduled run pulls; a manual run leaves the operator's tree alone. if [[ "$PULL" == true ]]; then print_info "Updating repository..." git -C "$BUILD_ROOT" pull --ff-only || print_warning "git pull failed — checking the current tree" fi get_repo_version() { local pkg="$1" local mirror="$2" local repo_db="$REPO_ROOT/$mirror/$ARCH/omarchy.db.tar.zst" [[ -f "$repo_db" ]] || return 0 tar -xOf "$repo_db" --wildcards '*/desc' 2>/dev/null | awk -v pkg="$pkg" ' function reset() { name=""; base=""; version="" } function emit() { if (!found && version != "" && (name == pkg || base == pkg)) { print version found=1 } reset() } $0 == "%FILENAME%" { emit(); next } $0 == "%NAME%" { if (name != "" && version != "") emit(); getline; name=$0; next } $0 == "%BASE%" { getline; base=$0; next } $0 == "%VERSION%" { getline; version=$0; next } END { emit() } ' } get_pkgbuild_version() { local pkgdir="$1" if [[ -f "$pkgdir/PKGBUILD" ]]; then (cd "$pkgdir" && bash -c 'source PKGBUILD 2>/dev/null; if [[ -n "$epoch" ]]; then echo "${epoch}:${pkgver}-${pkgrel}"; else echo "${pkgver}-${pkgrel}"; fi') fi } check_vcs_unchanged() { local pkgdir="$1" local repo_version="$2" local pkgbuild="$pkgdir/PKGBUILD" [[ -f "$pkgbuild" ]] || return 1 grep -qE '^pkgver[[:space:]]*\(\)' "$pkgbuild" || return 1 [[ -n "$repo_version" ]] || return 1 # If epoch or pkgrel changed in PKGBUILD, release even if upstream is unchanged. local pkgbuild_epoch pkgbuild_pkgrel pkgbuild_epoch=$(cd "$pkgdir" && bash -c 'source PKGBUILD 2>/dev/null; echo "${epoch:-}"') pkgbuild_pkgrel=$(cd "$pkgdir" && bash -c 'source PKGBUILD 2>/dev/null; echo "${pkgrel}"') local repo_pkgrel="${repo_version##*-}" local repo_no_pkgrel="${repo_version%-*}" local repo_epoch="" if [[ "$repo_no_pkgrel" == *:* ]]; then repo_epoch="${repo_no_pkgrel%%:*}" fi [[ "$pkgbuild_epoch" != "$repo_epoch" ]] && return 1 [[ "$pkgbuild_pkgrel" != "$repo_pkgrel" ]] && return 1 local repo_hash upstream_hash repo_hash=$(package_extract_vcs_hash_from_version "$repo_version") [[ -n "$repo_hash" ]] || return 1 upstream_hash=$(package_git_upstream_hash "$pkgdir") [[ -n "$upstream_hash" ]] || return 1 [[ "$repo_hash" == "$upstream_hash" ]] } check_package() { local pkg="$1" local pkgdir="$2" local mirror="$3" local pkgbuild_version repo_version pkgbuild_version=$(get_pkgbuild_version "$pkgdir") repo_version=$(get_repo_version "$pkg" "$mirror") if [[ -z "$pkgbuild_version" ]]; then return 1 fi if grep -qE '^pkgver[[:space:]]*\(\)' "$pkgdir/PKGBUILD"; then if [[ -n "$repo_version" && -n "$(package_extract_vcs_hash_from_version "$repo_version")" ]]; then if check_vcs_unchanged "$pkgdir" "$repo_version"; then return 1 else return 0 fi elif [[ "$pkgbuild_version" == "$repo_version" ]]; then return 1 else return 0 fi fi if [[ "$pkgbuild_version" == "$repo_version" ]]; then return 1 fi return 0 } check_mirror() { local mirror="$1" local state_file="$STATE_DIR/.sync-needed-$mirror" local needs_build=false local packages=() print_info "Checking $mirror packages..." while IFS= read -r pkg; do local pkgdir="$PKGBUILDS_DIR/$pkg" if check_package "$pkg" "$pkgdir" "$mirror"; then needs_build=true packages+=("$pkg") fi done < <(packages_for_unscoped_build "$mirror") echo "" if [[ "$needs_build" == true ]]; then # Record WHAT is queued, not just THAT something is: the release run reads # this to name the packages in its start report, which is the difference # between "a build is running" and "your package is in this build". printf '%s\n' "${packages[@]}" >"$state_file" print_success "${mirror^} needs building (${#packages[@]} packages)" print_info "Packages: ${packages[*]}" print_info "State file created: $state_file" else print_info "${mirror^} is up to date" fi echo "" } check_mirror edge check_mirror stable print_success "Version check complete!"