This commit is contained in:
Ryan Hughes committed 2026-05-08 01:04:52 -04:00
1 parent c1be0f4ecc
commit 2ffe4f811c
16 files changed
+1650 -496

No files matched your search

+180
View File
@@ -0,0 +1,180 @@
#!/bin/bash
set -euo pipefail
BUILD_ROOT=$(realpath "${BASH_SOURCE[0]%/*}/..")
source "$BUILD_ROOT/helpers/message-helpers.sh"
source "$BUILD_ROOT/helpers/paths.sh"
PACKAGE=""
SOURCE="aur"
SYNC="true"
RELEASE_RING=""
AUR_PACKAGE=""
FORCE=false
SCAFFOLD=false
usage() {
cat <<EOF
Usage: $0 <package> [OPTIONS]
Create pkgbuilds/<package> with Omarchy metadata. AUR packages are synced
immediately after metadata is written.
Options:
--source <aur|local> Package source (default: aur)
--local Shortcut for --source local
--aur <name> AUR package name when different from local directory
--no-sync For AUR packages, mark sync disabled after initial setup
--fast Put package in the fast release ring
--release-ring <ring> Release ring (currently: fast)
--scaffold For local packages, create a starter PKGBUILD
--force Overwrite existing .omarchy/package.json
-h, --help Show this help message
Examples:
$0 yay
$0 spotify --fast
$0 signal-desktop --no-sync
$0 omarchy-zsh --local --scaffold
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--source)
SOURCE="$2"
shift 2
;;
--local)
SOURCE="local"
shift
;;
--aur)
AUR_PACKAGE="$2"
shift 2
;;
--no-sync)
SYNC="false"
shift
;;
--fast)
RELEASE_RING="fast"
shift
;;
--release-ring)
RELEASE_RING="$2"
shift 2
;;
--scaffold)
SCAFFOLD=true
shift
;;
--force)
FORCE=true
shift
;;
-h|--help)
usage
exit 0
;;
--*)
print_error "Unknown option: $1"
exit 1
;;
*)
if [[ -n "$PACKAGE" ]]; then
print_error "Only one package can be added at a time"
exit 1
fi
PACKAGE="$1"
shift
;;
esac
done
if [[ -z "$PACKAGE" ]]; then
print_error "Package name required"
usage
exit 1
fi
case "$SOURCE" in
aur|local) ;;
*) print_error "Invalid source: $SOURCE (must be aur or local)"; exit 1 ;;
esac
case "$RELEASE_RING" in
""|fast) ;;
*) print_error "Invalid release ring: $RELEASE_RING (currently only 'fast' is supported)"; exit 1 ;;
esac
PACKAGE_DIR="$PKGBUILDS_DIR/$PACKAGE"
OMARCHY_DIR="$PACKAGE_DIR/.omarchy"
METADATA_FILE="$OMARCHY_DIR/package.json"
if [[ -f "$METADATA_FILE" && "$FORCE" != true ]]; then
print_error "Package metadata already exists: $METADATA_FILE"
print_info "Use --force to overwrite it"
exit 1
fi
print_header "Add Package"
print_info "Package: $PACKAGE"
print_info "Source: $SOURCE"
[[ -n "$RELEASE_RING" ]] && print_info "Release ring: $RELEASE_RING"
mkdir -p "$OMARCHY_DIR"
jq_args=(--arg source "$SOURCE")
jq_filter='{source: $source}'
if [[ "$SOURCE" == "aur" && -n "$AUR_PACKAGE" && "$AUR_PACKAGE" != "$PACKAGE" ]]; then
jq_args+=(--arg aur "$AUR_PACKAGE")
jq_filter="$jq_filter + {aur: $aur}"
fi
if [[ "$SOURCE" == "aur" && "$SYNC" == "false" ]]; then
jq_filter="$jq_filter + {sync: false}"
fi
if [[ -n "$RELEASE_RING" ]]; then
jq_args+=(--arg release_ring "$RELEASE_RING")
jq_filter="$jq_filter + {release_ring: $release_ring}"
fi
jq -n "${jq_args[@]}" "$jq_filter" > "$METADATA_FILE"
print_success "Wrote $METADATA_FILE"
if [[ "$SOURCE" == "aur" ]]; then
if [[ "$SYNC" == "false" ]]; then
# Temporarily sync once, then restore sync=false so future automated syncs skip it.
tmpfile=$(mktemp)
jq 'del(.sync)' "$METADATA_FILE" > "$tmpfile"
mv "$tmpfile" "$METADATA_FILE"
"$BUILD_ROOT/bin/sync-aur" "$PACKAGE"
jq '. + {sync: false}' "$METADATA_FILE" > "$tmpfile"
mv "$tmpfile" "$METADATA_FILE"
print_info "AUR sync disabled for future runs"
else
"$BUILD_ROOT/bin/sync-aur" "$PACKAGE"
fi
else
if [[ "$SCAFFOLD" == true && ! -f "$PACKAGE_DIR/PKGBUILD" ]]; then
cat > "$PACKAGE_DIR/PKGBUILD" <<EOF
pkgname=$PACKAGE
pkgver=0.1.0
pkgrel=1
pkgdesc=""
arch=('any')
url="https://omarchy.org"
license=('MIT')
package() {
:
}
EOF
print_success "Scaffolded PKGBUILD"
fi
fi
print_success "Package setup complete: $PACKAGE_DIR"
+36 -13
View File
@@ -9,13 +9,9 @@ source "$BUILD_ROOT/helpers/message-helpers.sh"
source "$BUILD_ROOT/helpers/docker-helpers.sh"
source "$BUILD_ROOT/helpers/paths.sh"
# Create directories if they don't exist
mkdir -p "$BUILD_OUTPUT_DIR" "$REPO_DIR" "$SRC_DIR"
print_header "Omarchy Package Builder"
print_header "Omarchy AUR Package Builder"
# Check Docker is available
check_docker
DRY_RUN=false
# Parse command line arguments
while [[ $# -gt 0 ]]; do
@@ -43,6 +39,10 @@ while [[ $# -gt 0 ]]; do
done
PACKAGES="${PACKAGES# }"
;;
--dry-run)
DRY_RUN=true
shift
;;
-h | --help)
echo "Usage: $0 [OPTIONS]"
echo ""
@@ -50,14 +50,15 @@ while [[ $# -gt 0 ]]; do
echo " --arch <arch> Target architecture (x86_64 or aarch64, default: x86_64)"
echo " --mirror <mirror> Mirror to use (edge or stable, default: edge)"
echo " --package <names> Build only the specified package(s) (space-separated)"
echo " --dry-run Show what would build without running makepkg"
echo " -h, --help Show this help message"
echo ""
echo "This script builds packages from pkgbuilds/ directories based on mirror:"
echo " --mirror edge: builds from pkgbuilds/edge/ + pkgbuilds/shared/"
echo " --mirror stable: builds from pkgbuilds/shared/ only (edge pkgs promoted via 'repo migrate')"
echo "This script builds packages from pkgbuilds/ based on .omarchy/package.json:"
echo " --mirror edge: builds all packages"
echo " --mirror stable: builds packages with release_ring=fast only"
echo ""
echo "Or build specific packages with --package:"
echo " Package names should match directories in the relevant pkgbuilds/ tier"
echo " Package names should match directories in pkgbuilds/"
echo ""
echo "Examples:"
echo " $0 --arch aarch64"
@@ -80,6 +81,27 @@ print_info "Mirror: $MIRROR"
print_info "Build workspace: $BUILD_OUTPUT_DIR"
print_info "Final output: $REPO_DIR"
if [[ "$DRY_RUN" == true ]]; then
print_warning "DRY RUN MODE - build plan only; no Docker or makepkg will run"
ARCH="$ARCH" \
MIRROR="$MIRROR" \
PACKAGES="$PACKAGES" \
DRY_RUN=true \
PKGBUILDS_DIR="$PKGBUILDS_DIR" \
BUILD_OUTPUT_DIR="$BUILD_OUTPUT_DIR" \
FINAL_OUTPUT_DIR="$REPO_DIR" \
HELPERS_DIR="$BUILD_ROOT/helpers" \
SRC_DIR="$SRC_DIR" \
"$BUILD_ROOT/build/build.sh"
exit $?
fi
# Create directories if they don't exist
mkdir -p "$BUILD_OUTPUT_DIR" "$REPO_DIR" "$SRC_DIR"
# Check Docker is available
check_docker
# Setup QEMU for aarch64 builds on x86_64 hosts
if [[ "$(uname -m)" == "x86_64" && "$ARCH" == "aarch64" ]]; then
# Check if QEMU is already working
@@ -104,7 +126,7 @@ fi
# Build/update the Docker image
build_docker_image "$BUILD_DIR" "$ARCH" "$MIRROR"
print_info "Running AUR package build..."
print_info "Running package build..."
# Create output directories if they don't exist
mkdir -p "$BUILD_OUTPUT_DIR"
@@ -123,6 +145,7 @@ DOCKER_ARGS=(
-v "$BUILD_ROOT/build-output:/build-output"
-v "$BUILD_ROOT/pkgs.omarchy.org:/pkgs.omarchy.org"
-v "$BUILD_DIR:/build:ro"
-v "$BUILD_ROOT/helpers:/helpers:ro"
-v "$BUILD_ROOT/pkgbuilds:/pkgbuilds:ro"
)
@@ -137,8 +160,8 @@ BUILD_RESULT=$?
# Summary
echo ""
if [[ $BUILD_RESULT -eq 0 ]]; then
print_success "AUR build completed successfully!"
print_success "Build completed successfully!"
else
print_warning "Some AUR packages failed (see details above)"
print_warning "Some packages failed (see details above)"
exit $BUILD_RESULT
fi
+41 -73
View File
@@ -7,30 +7,29 @@ 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"
STATE_DIR="${OMARCHY_STATE_DIR:-/root/.state}"
ARCH="${ARCH:-x86_64}"
# Ensure state directory exists
mkdir -p "$STATE_DIR"
print_header "Package Version Check"
# Get version from repo database
get_repo_version() {
local pkg="$1"
local mirror="$2"
local repo_db="$BUILD_ROOT/pkgs.omarchy.org/$mirror/$ARCH/omarchy.db.tar.zst"
if [[ -f "$repo_db" ]]; then
local desc_file=$(tar -tf "$repo_db" 2>/dev/null | grep "^${pkg}-[0-9r].*/desc$" | head -1)
local desc_file
desc_file=$(tar -tf "$repo_db" 2>/dev/null | grep "^${pkg}-[0-9r].*/desc$" | head -1)
if [[ -n "$desc_file" ]]; then
tar -xOf "$repo_db" "$desc_file" 2>/dev/null | awk '/%VERSION%/{getline; print; exit}'
fi
fi
}
# Get version from PKGBUILD
get_pkgbuild_version() {
local pkgdir="$1"
if [[ -f "$pkgdir/PKGBUILD" ]]; then
@@ -38,88 +37,57 @@ get_pkgbuild_version() {
fi
}
# Check if package needs building for a mirror
check_package() {
local pkg="$1"
local pkgdir="$2"
local mirror="$3"
local pkgbuild_version=$(get_pkgbuild_version "$pkgdir")
local repo_version=$(get_repo_version "$pkg" "$mirror")
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 # Can't read version, skip
return 1
fi
if [[ "$pkgbuild_version" != "$repo_version" ]]; then
return 0 # Needs building
return 0
fi
return 1 # Up to date
return 1
}
edge_needs_build=false
stable_needs_build=false
edge_packages=()
stable_packages=()
check_mirror() {
local mirror="$1"
local state_file="$STATE_DIR/.sync-needed-$mirror"
local needs_build=false
local packages=()
print_info "Checking edge packages..."
print_info "Checking $mirror packages..."
# Check edge/ packages -> only affects edge
for pkgdir in "$BUILD_ROOT/pkgbuilds/edge"/*/; do
[[ ! -d "$pkgdir" ]] && continue
pkg=$(basename "$pkgdir")
[[ ! -f "$pkgdir/PKGBUILD" ]] && continue
if check_package "$pkg" "$pkgdir" "edge"; then
edge_needs_build=true
edge_packages+=("$pkg")
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_mirror "$mirror")
echo ""
if [[ "$needs_build" == true ]]; then
touch "$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
done
print_info "Checking shared packages..."
echo ""
}
# Check shared/ packages -> affects BOTH edge and stable
for pkgdir in "$BUILD_ROOT/pkgbuilds/shared"/*/; do
[[ ! -d "$pkgdir" ]] && continue
pkg=$(basename "$pkgdir")
[[ ! -f "$pkgdir/PKGBUILD" ]] && continue
# Check against edge
if check_package "$pkg" "$pkgdir" "edge"; then
edge_needs_build=true
edge_packages+=("$pkg")
fi
# Check against stable
if check_package "$pkg" "$pkgdir" "stable"; then
stable_needs_build=true
stable_packages+=("$pkg")
fi
done
check_mirror edge
check_mirror stable
echo ""
# Drop state files as needed
if [[ "$edge_needs_build" == true ]]; then
touch "$STATE_DIR/.sync-needed-edge"
print_success "Edge needs building (${#edge_packages[@]} packages)"
print_info "Packages: ${edge_packages[*]}"
print_info "State file created: $STATE_DIR/.sync-needed-edge"
else
print_info "Edge is up to date"
fi
echo ""
if [[ "$stable_needs_build" == true ]]; then
touch "$STATE_DIR/.sync-needed-stable"
print_success "Stable needs building (${#stable_packages[@]} packages)"
print_info "Packages: ${stable_packages[*]}"
print_info "State file created: $STATE_DIR/.sync-needed-stable"
else
print_info "Stable is up to date"
fi
echo ""
print_success "Version check complete!"
+196 -19
View File
@@ -1,15 +1,66 @@
#!/bin/bash
set -euo pipefail
# Get the directory of this script
SCRIPT_DIR=$(realpath "${BASH_SOURCE[0]%/*}")
BUILD_ROOT=$(realpath "$SCRIPT_DIR/..")
source "$BUILD_ROOT/helpers/message-helpers.sh"
source "$BUILD_ROOT/helpers/paths.sh"
source "$BUILD_ROOT/helpers/package-metadata.sh"
OUTPUT_JSON=false
LIST_REPO=false
SOURCE_FILTER=""
SYNC_FILTER=""
RING_FILTER=""
usage() {
cat <<EOF
Usage: $0 [OPTIONS]
List package source metadata from pkgbuilds/<package>/.omarchy/package.json.
Options:
--json Output JSON for agents/scripts
--source <aur|local> Filter by source
--sync <true|false> Filter by AUR sync state
--release-ring <ring> Filter by release ring, e.g. fast
--repo List packages from the published repo database instead
--arch <arch> Target architecture for --repo (default: x86_64)
--mirror <mirror> Mirror for --repo (edge or stable, default: edge)
-h, --help Show this help message
Examples:
$0
$0 --release-ring fast
$0 --source aur --sync false
$0 --json
$0 --repo --mirror stable
EOF
}
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--json)
OUTPUT_JSON=true
shift
;;
--repo)
LIST_REPO=true
shift
;;
--source)
SOURCE_FILTER="$2"
shift 2
;;
--sync)
SYNC_FILTER="$2"
shift 2
;;
--release-ring)
RING_FILTER="$2"
shift 2
;;
--arch)
ARCH="$2"
update_arch_paths
@@ -21,12 +72,7 @@ while [[ $# -gt 0 ]]; do
shift 2
;;
-h | --help)
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " --arch <arch> Target architecture (x86_64 or aarch64, default: x86_64)"
echo " --mirror <mirror> Mirror to use (edge or stable, default: edge)"
echo " -h, --help Show this help message"
usage
exit 0
;;
*)
@@ -36,18 +82,149 @@ while [[ $# -gt 0 ]]; do
esac
done
DB_FILE="$REPO_DIR/omarchy.db.tar.zst"
list_repo_packages() {
local db_file="$REPO_DIR/omarchy.db.tar.zst"
if [[ ! -f "$DB_FILE" ]]; then
echo "Repository database not found: $DB_FILE"
exit 1
if [[ ! -f "$db_file" ]]; then
echo "Repository database not found: $db_file" >&2
exit 1
fi
tar -xOf "$db_file" --wildcards "*/desc" 2>/dev/null |
awk '/%NAME%/{getline; name=$0}
/%VERSION%/{getline; print name "-" $0}' |
sort
}
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') || true
fi
}
patch_count() {
local pkgdir="$1"
local patches_dir="$pkgdir/.omarchy/patches"
[[ -d "$patches_dir" ]] || { echo 0; return; }
find "$patches_dir" -maxdepth 1 -type f -name '*.patch' | wc -l
}
post_sync_hook_enabled() {
local pkgdir="$1"
[[ -f "$pkgdir/.omarchy/post-sync.sh" ]] && echo true || echo false
}
package_matches_filters() {
local source="$1"
local sync="$2"
local ring="$3"
[[ -z "$SOURCE_FILTER" || "$source" == "$SOURCE_FILTER" ]] || return 1
[[ -z "$RING_FILTER" || "$ring" == "$RING_FILTER" ]] || return 1
if [[ -n "$SYNC_FILTER" ]]; then
[[ "$source" == "aur" ]] || return 1
[[ "$sync" == "$SYNC_FILTER" ]] || return 1
fi
return 0
}
emit_package_json() {
local name="$1" source="$2" aur="$3" sync="$4" ring="$5" pkgrel="$6" upstream_commit="$7" patches="$8" hook="$9" version="${10}" path="${11}"
jq -n \
--arg name "$name" \
--arg source "$source" \
--arg aur "$aur" \
--arg sync "$sync" \
--arg release_ring "$ring" \
--argjson pkgrel "$pkgrel" \
--arg upstream_commit "$upstream_commit" \
--argjson patches "$patches" \
--arg hook "$hook" \
--arg version "$version" \
--arg path "$path" \
'{name: $name, source: $source, aur: $aur, sync: (if $sync == "" then null else $sync == "true" end), release_ring: $release_ring, pkgrel: $pkgrel, upstream_commit: $upstream_commit, patches: $patches, post_sync_hook: ($hook == "true"), version: $version, path: $path}'
}
if [[ "$LIST_REPO" == true ]]; then
list_repo_packages
exit 0
fi
echo "Packages in $MIRROR mirror ($ARCH):"
echo ""
rows_file=$(mktemp)
json_file=$(mktemp)
trap 'rm -f "$rows_file" "$json_file"' EXIT
# Extract package names and versions from database
tar -xOf "$DB_FILE" --wildcards "*/desc" 2>/dev/null |
awk '/%NAME%/{getline; name=$0}
/%VERSION%/{getline; print name "-" $0}' |
sort
first_json=true
printf '[\n' > "$json_file"
while IFS= read -r pkgdir; do
name=$(basename "$pkgdir")
metadata=$(metadata_file_for_dir "$pkgdir")
source=$(jq -r '.source // ""' "$metadata")
ring=$(jq -r '.release_ring // ""' "$metadata")
aur=$(jq -r --arg name "$name" '.aur // $name' "$metadata")
aur_display="$aur"
[[ "$aur_display" == "$name" ]] && aur_display=""
if [[ "$source" == "aur" ]]; then
sync=$(jq -r 'if has("sync") then .sync else true end' "$metadata")
else
sync=""
fi
package_matches_filters "$source" "$sync" "$ring" || continue
pkgrel=$(jq -c '.pkgrel // {}' "$metadata")
pkgrel_display=$(jq -r '.pkgrel // {} | to_entries | map("\(.key)=\(.value)") | join(",")' "$metadata")
upstream_commit=$(jq -r '.upstream_commit // ""' "$metadata")
upstream_display="${upstream_commit:0:7}"
patches=$(patch_count "$pkgdir" | tr -d ' ')
hook=$(post_sync_hook_enabled "$pkgdir")
hook_display="$([[ "$hook" == true ]] && echo yes || echo no)"
version=$(get_pkgbuild_version "$pkgdir")
relpath=${pkgdir#"$BUILD_ROOT/"}
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
"$name" \
"$source" \
"$aur_display" \
"$([[ -n "$sync" ]] && [[ "$sync" == true ]] && echo yes || ([[ "$sync" == false ]] && echo no || echo -))" \
"$ring" \
"$pkgrel_display" \
"$upstream_display" \
"$patches" \
"$hook_display" \
"$version" \
"$relpath" >> "$rows_file"
if [[ "$first_json" == false ]]; then
printf ',\n' >> "$json_file"
fi
emit_package_json "$name" "$source" "$aur" "$sync" "$ring" "$pkgrel" "$upstream_commit" "$patches" "$hook" "$version" "$relpath" >> "$json_file"
first_json=false
done < <(package_dirs)
printf '\n]\n' >> "$json_file"
if [[ "$OUTPUT_JSON" == true ]]; then
jq . "$json_file"
exit 0
fi
if command -v gum >/dev/null 2>&1; then
gum table --print --separator $'\t' \
--columns Package,Source,AUR,Sync,Release_Ring,Pkgrel,Upstream,Patches,Post_Sync,Version,Path \
< "$rows_file"
else
{
printf 'Package\tSource\tAUR\tSync\tRelease_Ring\tPkgrel\tUpstream\tPatches\tPost_Sync\tVersion\tPath\n'
cat "$rows_file"
} | column -t -s $'\t'
fi
+3 -3
View File
@@ -1,5 +1,5 @@
#!/bin/bash
# Migrate package files from edge repo to stable repo without overwriting
# Promote tested edge package artifacts into stable without overwriting
set -e
@@ -41,7 +41,7 @@ while [[ $# -gt 0 ]]; do
echo " -h, --help Show this help message"
echo ""
echo "What it does:"
echo " 1) Rsync package files from edge -> stable (without overwriting existing files)"
echo " 1) Rsync tested package artifacts from edge -> stable (without overwriting existing files)"
echo " 2) Run stable cleanup (keep 2 versions)"
echo " 3) Update stable repository database"
echo " 4) Sync stable repository to remote (prompts for confirmation)"
@@ -57,7 +57,7 @@ done
SOURCE_DIR="$BUILD_ROOT/pkgs.omarchy.org/edge/$ARCH"
TARGET_DIR="$BUILD_ROOT/pkgs.omarchy.org/stable/$ARCH"
print_header "Migrate Edge to Stable"
print_header "Promote Edge Artifacts to Stable"
print_info "Architecture: $ARCH"
print_info "Source: $SOURCE_DIR"
print_info "Target: $TARGET_DIR"
+288
View File
@@ -0,0 +1,288 @@
#!/bin/bash
set -euo pipefail
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"
PACKAGE=""
DEST_DIR=""
COMMIT_OVERRIDE=""
usage() {
cat <<EOF
Usage: $0 <package> [OPTIONS]
Create a scratch workspace for inspecting an AUR-backed package.
The workspace contains:
upstream/ Raw AUR package at .omarchy/package.json upstream_commit, or HEAD
patched/ Raw AUR package with Omarchy .omarchy patches/hooks/pkgrel applied
current/ Current checked-in package directory
Options:
--dir <path> Workspace directory (default: mktemp under /tmp)
--commit <sha> Use a specific AUR commit instead of upstream_commit
-h, --help Show this help message
Examples:
$0 v4l2-relayd
$0 v4l2-relayd --dir /tmp/v4l2-relayd-worktree
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--dir)
DEST_DIR="$2"
shift 2
;;
--commit)
COMMIT_OVERRIDE="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
--*)
print_error "Unknown option: $1"
exit 1
;;
*)
if [[ -n "$PACKAGE" ]]; then
print_error "Only one package can be inspected at a time"
exit 1
fi
PACKAGE="$1"
shift
;;
esac
done
if [[ -z "$PACKAGE" ]]; then
print_error "Package name required"
usage
exit 1
fi
PACKAGE_DIR="$PKGBUILDS_DIR/$PACKAGE"
METADATA="$PACKAGE_DIR/.omarchy/package.json"
if [[ ! -f "$METADATA" ]]; then
print_error "Missing package metadata: $METADATA"
exit 1
fi
if [[ "$(jq -r '.source // ""' "$METADATA")" != "aur" ]]; then
print_error "package-worktree only supports AUR-backed packages"
exit 1
fi
AUR_PACKAGE=$(jq -r --arg package "$PACKAGE" '.aur // $package' "$METADATA")
UPSTREAM_COMMIT=${COMMIT_OVERRIDE:-$(jq -r '.upstream_commit // ""' "$METADATA")}
if [[ -z "$DEST_DIR" ]]; then
DEST_DIR=$(mktemp -d "${TMPDIR:-/tmp}/omarchy-${PACKAGE}.XXXXXX")
else
mkdir -p "$DEST_DIR"
DEST_DIR=$(realpath "$DEST_DIR")
fi
UPSTREAM_DIR="$DEST_DIR/upstream"
PATCHED_DIR="$DEST_DIR/patched"
CURRENT_DIR="$DEST_DIR/current"
get_pkgbuild_field() {
local package_dir="$1"
local field="$2"
local value=""
if [[ -f "$package_dir/PKGBUILD" ]]; then
value=$(grep -m1 "^${field}=" "$package_dir/PKGBUILD" | cut -d= -f2- | tr -d "\"'") || true
if [[ -n "$value" ]]; then
echo "$value"
return
fi
fi
if [[ -f "$package_dir/.SRCINFO" ]]; then
awk -F' = ' -v field="$field" '$1 ~ "^[[:space:]]*" field "$" { print $2; exit }' "$package_dir/.SRCINFO"
fi
}
set_pkgrel() {
local package_dir="$1"
local pkgrel="$2"
sed -i "s/^pkgrel=.*/pkgrel=$pkgrel/" "$package_dir/PKGBUILD"
}
copy_aur_contents() {
local aur_dir="$1"
local target_dir="$2"
mkdir -p "$target_dir"
shopt -s dotglob nullglob
local item base
for item in "$aur_dir"/*; do
base=$(basename "$item")
[[ "$base" == ".git" ]] && continue
cp -a "$item" "$target_dir/"
done
shopt -u dotglob nullglob
}
remove_aur_only_files() {
local package_dir="$1"
rm -f "$package_dir/.SRCINFO" "$package_dir/.gitignore"
}
apply_omarchy_patches() {
local package_dir="$1"
local patches_dir="$package_dir/.omarchy/patches"
local applied=false
[[ -d "$patches_dir" ]] || return 1
shopt -s nullglob
local patch_files=("$patches_dir"/*.patch)
shopt -u nullglob
[[ ${#patch_files[@]} -gt 0 ]] || return 1
local patch_file
for patch_file in "${patch_files[@]}"; do
print_info " Applying $(basename "$patch_file")"
if ! (cd "$package_dir" && patch -p1 --forward --batch --no-backup-if-mismatch < "$patch_file"); then
print_error "Failed to apply patch: $patch_file"
return 2
fi
applied=true
done
[[ "$applied" == true ]]
}
run_post_sync_hook() {
local package_dir="$1"
local aur_pkgrel="$2"
local hook="$package_dir/.omarchy/post-sync.sh"
[[ -f "$hook" ]] || return 1
print_info " Running post-sync.sh"
if ! (
cd "$package_dir"
PACKAGE_NAME="$PACKAGE" \
AUR_PACKAGE_NAME="$AUR_PACKAGE" \
AUR_PKGREL="$aur_pkgrel" \
bash ".omarchy/post-sync.sh"
); then
print_error "post-sync.sh failed"
return 2
fi
}
apply_pkgrel_metadata() {
local package_dir="$1"
local aur_pkgrel="$2"
local previous_pkgver="$3"
local metadata="$package_dir/.omarchy/package.json"
jq -e 'has("pkgrel")' "$metadata" >/dev/null || return 1
local current_pkgver suffix offset base
current_pkgver=$(get_pkgbuild_field "$package_dir" pkgver)
if [[ -n "$previous_pkgver" && "$current_pkgver" != "$previous_pkgver" ]]; then
print_info " Skipping stale pkgrel metadata (pkgver changed: $previous_pkgver -> $current_pkgver)"
return 1
fi
suffix=$(jq -r '.pkgrel.suffix // 1' "$metadata")
offset=$(jq -r '.pkgrel.offset // 0' "$metadata")
base=$((aur_pkgrel + offset))
print_info " Applying pkgrel metadata: $base.$suffix"
set_pkgrel "$package_dir" "$base.$suffix"
}
apply_auto_pkgrel_suffix() {
local package_dir="$1"
local aur_pkgrel="$2"
print_info " Applying automatic pkgrel suffix: $aur_pkgrel.1"
set_pkgrel "$package_dir" "$aur_pkgrel.1"
}
print_header "Package Worktree: $PACKAGE"
print_info "Workspace: $DEST_DIR"
print_info "AUR package: $AUR_PACKAGE"
if [[ -n "$UPSTREAM_COMMIT" ]]; then
print_info "Upstream commit: $UPSTREAM_COMMIT"
else
print_warning "No upstream_commit recorded; using AUR HEAD"
fi
rm -rf "$UPSTREAM_DIR" "$PATCHED_DIR" "$CURRENT_DIR"
git clone "https://aur.archlinux.org/${AUR_PACKAGE}.git" "$UPSTREAM_DIR" >/dev/null 2>&1
if [[ -n "$UPSTREAM_COMMIT" ]]; then
git -C "$UPSTREAM_DIR" checkout --detach "$UPSTREAM_COMMIT" >/dev/null 2>&1
fi
rm -rf "$UPSTREAM_DIR/.git"
copy_aur_contents "$UPSTREAM_DIR" "$PATCHED_DIR"
rm -rf "$PATCHED_DIR/.omarchy"
cp -a "$PACKAGE_DIR/.omarchy" "$PATCHED_DIR/.omarchy"
cp -a "$PACKAGE_DIR" "$CURRENT_DIR"
AUR_PKGREL=$(get_pkgbuild_field "$UPSTREAM_DIR" pkgrel)
PREVIOUS_PKGVER=$(get_pkgbuild_field "$PACKAGE_DIR" pkgver || true)
CUSTOMIZED=false
PKGREL_APPLIED=false
print_info "Creating patched/ from upstream/ + .omarchy customizations"
if apply_omarchy_patches "$PATCHED_DIR"; then
CUSTOMIZED=true
else
patch_status=$?
if [[ $patch_status -eq 2 ]]; then
exit 1
fi
fi
if run_post_sync_hook "$PATCHED_DIR" "$AUR_PKGREL"; then
CUSTOMIZED=true
else
hook_status=$?
if [[ $hook_status -eq 2 ]]; then
exit 1
fi
fi
if apply_pkgrel_metadata "$PATCHED_DIR" "$AUR_PKGREL" "$PREVIOUS_PKGVER"; then
PKGREL_APPLIED=true
fi
if [[ "$CUSTOMIZED" == true && "$PKGREL_APPLIED" == false ]]; then
apply_auto_pkgrel_suffix "$PATCHED_DIR" "$AUR_PKGREL"
fi
remove_aur_only_files "$PATCHED_DIR"
remove_aur_only_files "$CURRENT_DIR"
cat <<EOF
Created package workspace:
$DEST_DIR/upstream raw AUR package
$DEST_DIR/patched AUR + Omarchy customizations
$DEST_DIR/current checked-in package
Useful diffs:
diff -ruN "$DEST_DIR/upstream" "$DEST_DIR/patched"
diff -ruN "$DEST_DIR/patched" "$DEST_DIR/current"
EOF
+19 -2
View File
@@ -10,6 +10,7 @@ source "$BUILD_ROOT/helpers/basecamp-notifier.sh"
SYNC_REMOTE=""
SKIP_PROD_CHECK=false
DRY_RUN=false
print_header "Complete Release Workflow"
@@ -51,6 +52,11 @@ while [[ $# -gt 0 ]]; do
SKIP_PROD_CHECK=true
shift
;;
--dry-run)
DRY_RUN=true
BUILD_ARGS+=("--dry-run")
shift
;;
-h | --help)
echo "Usage: $0 [OPTIONS]"
echo ""
@@ -59,7 +65,8 @@ while [[ $# -gt 0 ]]; do
echo " --mirror <mirror> Mirror to use (edge or stable, default: edge)"
echo " --package <name> Build only the specified package"
echo " --sync-remote <path> Rclone remote for sync (default: pkgs.omarchy.org:omarchy-pkgs)"
echo " --skip-prod-check Skip production environment check during sync"
echo " --skip-prod-check Skip production environment check during sync
--dry-run Show build plan only; do not sign/promote/clean/update/sync"
echo " -h, --help Show this help message"
echo ""
echo "This script runs the complete workflow:"
@@ -80,13 +87,23 @@ print_info "Build workspace: $BUILD_OUTPUT_DIR"
# Step 1: Build
echo ""
print_info "Step 1/6: Building packages..."
if [[ "$DRY_RUN" == true ]]; then
print_info "Step 1/6: Planning build..."
else
print_info "Step 1/6: Building packages..."
fi
"$BUILD_ROOT/bin/build" "${BUILD_ARGS[@]}" || {
print_error "Build failed"
notify_error "Release failed: Build step failed" "Mirror: $MIRROR | Arch: $ARCH"
exit 1
}
if [[ "$DRY_RUN" == true ]]; then
echo ""
print_success "Release dry run complete (build plan only)."
exit 0
fi
# Step 2: Sign
echo ""
print_info "Step 2/6: Signing packages..."
+2 -2
View File
@@ -47,13 +47,13 @@ show_usage() {
echo ""
echo "Commands:"
echo " release Run complete workflow: build → sign → promote → clean → update → sync"
echo " build Build AUR packages (unsigned)"
echo " build Build packages (unsigned)"
echo " sign Sign all packages in build-output"
echo " promote Promote build to production (build-output → pkgs.omarchy.org)"
echo " update Update repository database"
echo " clean Clean old package versions"
echo " migrate Migrate edge packages into stable (no overwrite), then clean + update"
echo " list List packages in repository"
echo " list List source package metadata (use --repo for published repo)"
echo " remove Remove a specific package"
echo " sync Sync repository to remote"
echo ""
+365 -133
View File
@@ -1,46 +1,50 @@
#!/bin/bash
set -euo pipefail
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"
TEMP_DIR=$(mktemp -d)
trap 'rm -rf "$TEMP_DIR"' EXIT
trap "rm -rf $TEMP_DIR" EXIT
# Default tier
TIER=""
SPECIFIC_PACKAGES=()
# Parse arguments
usage() {
cat <<EOF
Usage: $0 [PACKAGE...]
Sync AUR-backed packages into pkgbuilds/<package>/.
Package selection is driven by pkgbuilds/<package>/.omarchy/package.json:
{ "source": "aur" } # synced from matching AUR package name
{ "source": "aur", "aur": "yaru" } # synced from different AUR package name
{ "source": "aur", "sync": false } # AUR-origin, but not auto-synced
Arguments:
PACKAGE One or more package names to sync (optional)
Examples:
$0 # Sync all AUR packages with sync enabled
$0 yay cursor-bin # Sync specific packages
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--tier)
TIER="$2"
if [[ "$TIER" != "edge" && "$TIER" != "shared" ]]; then
print_error "Invalid tier: $TIER (must be 'edge' or 'shared')"
exit 1
fi
shift 2
;;
-h|--help)
echo "Usage: $0 --tier <edge|shared> [PACKAGE...]"
echo ""
echo "Sync AUR packages to pkgbuilds/<tier>/ directory"
echo ""
echo "Options:"
echo " --tier <tier> Target tier: edge or shared (required)"
echo ""
echo "Arguments:"
echo " PACKAGE One or more package names to sync (optional)"
echo ""
echo "Examples:"
echo " $0 --tier edge # Sync all packages from edge.packages"
echo " $0 --tier shared # Sync all packages from shared.packages"
echo " $0 --tier edge yay # Sync only the yay package to edge/"
echo " $0 --tier shared cursor-bin # Sync only cursor-bin to shared/"
usage
exit 0
;;
--tier)
print_error "--tier is no longer supported; package metadata controls sync behavior"
exit 1
;;
--*)
print_error "Unknown option: $1"
exit 1
;;
*)
SPECIFIC_PACKAGES+=("$1")
shift
@@ -48,127 +52,355 @@ while [[ $# -gt 0 ]]; do
esac
done
# Require tier
if [[ -z "$TIER" ]]; then
print_error "Missing required --tier argument"
echo "Usage: $0 --tier <edge|shared> [PACKAGE...]"
exit 1
fi
# Set paths based on tier
PACKAGES_FILE="$BUILD_ROOT/build/packages/${TIER}.packages"
TARGET_DIR="$PKGBUILDS_DIR/$TIER"
print_header "AUR Package Sync (tier: $TIER)"
mkdir -p "$TARGET_DIR"
if [[ ! -f "$PACKAGES_FILE" ]]; then
print_error "Package list not found: $PACKAGES_FILE"
exit 1
fi
print_header "AUR Package Sync"
mkdir -p "$PKGBUILDS_DIR"
SYNCED=0
SKIPPED=0
FAILED=0
SYNCED_PACKAGES=()
SPECIFIC_MODE=false
# Function to sync a package from AUR
sync_package() {
local package="$1"
print_info "Syncing $package from AUR..."
cd "$TEMP_DIR"
rm -rf "$package"
if git clone "https://aur.archlinux.org/${package}.git" 2>/dev/null; then
# Create target directory if it doesn't exist
mkdir -p "$TARGET_DIR/$package"
# Copy files (not .git directory)
cp -r "$package"/* "$TARGET_DIR/$package/" 2>/dev/null || true
cp -r "$package"/.* "$TARGET_DIR/$package/" 2>/dev/null || true
# Remove .git from destination
rm -rf "$TARGET_DIR/$package/.git"
SYNCED_PACKAGES+=("$package")
((SYNCED++))
else
print_warning "Failed to clone $package (may not exist in AUR)"
((FAILED++))
get_pkgbuild_field() {
local package_dir="$1"
local field="$2"
local value=""
if [[ -f "$package_dir/PKGBUILD" ]]; then
value=$(grep -m1 "^${field}=" "$package_dir/PKGBUILD" | cut -d= -f2- | tr -d "\"'") || true
if [[ -n "$value" ]]; then
echo "$value"
return
fi
fi
if [[ -f "$package_dir/.SRCINFO" ]]; then
awk -F' = ' -v field="$field" '$1 ~ "^[[:space:]]*" field "$" { print $2; exit }' "$package_dir/.SRCINFO"
fi
}
# If specific packages provided, sync only those
set_pkgrel() {
local package_dir="$1"
local pkgrel="$2"
local pkgbuild="$package_dir/PKGBUILD"
if [[ -f "$pkgbuild" ]]; then
sed -i "s/^pkgrel=.*/pkgrel=$pkgrel/" "$pkgbuild"
fi
}
display_package_name() {
local package_dir="$1"
local name
name=$(basename "$package_dir")
echo "${name%.work}"
}
remove_aur_only_files() {
local package_dir="$1"
rm -f "$package_dir/.SRCINFO" "$package_dir/.gitignore"
}
copy_aur_contents() {
local aur_dir="$1"
local target_dir="$2"
mkdir -p "$target_dir"
shopt -s dotglob nullglob
local item base
for item in "$aur_dir"/*; do
base=$(basename "$item")
[[ "$base" == ".git" ]] && continue
cp -a "$item" "$target_dir/"
done
shopt -u dotglob nullglob
}
commit_synced_worktree() {
local work_dir="$1"
local target_dir="$2"
local parent base staged_dir backup_root backup_dir
parent=$(dirname "$target_dir")
base=$(basename "$target_dir")
staged_dir=$(mktemp -d "$parent/.${base}.staged.XXXXXX")
backup_root=$(mktemp -d "$parent/.${base}.backup.XXXXXX")
backup_dir="$backup_root/$base"
# Copy to the package filesystem before swapping. This keeps the original
# package directory intact if copying from /tmp fails or is interrupted.
if ! cp -a "$work_dir/." "$staged_dir/"; then
print_error "Failed to stage synced package for $base"
rm -rf "$staged_dir" "$backup_root"
return 1
fi
if [[ -e "$target_dir" ]]; then
if ! mv "$target_dir" "$backup_dir"; then
print_error "Failed to back up existing package directory: $target_dir"
rm -rf "$staged_dir" "$backup_root"
return 1
fi
fi
if ! mv "$staged_dir" "$target_dir"; then
print_error "Failed to install synced package directory: $target_dir"
if [[ -e "$backup_dir" ]]; then
mv "$backup_dir" "$target_dir" || true
fi
rm -rf "$staged_dir" "$backup_root"
return 1
fi
rm -rf "$backup_root" "$work_dir"
}
set_upstream_commit() {
local package_dir="$1"
local commit="$2"
local metadata="$package_dir/.omarchy/package.json"
local tmpfile
tmpfile=$(mktemp)
jq --arg commit "$commit" '.upstream_commit = $commit' "$metadata" > "$tmpfile"
mv "$tmpfile" "$metadata"
}
apply_omarchy_patches() {
local package_dir="$1"
local patches_dir="$package_dir/.omarchy/patches"
local applied=false
[[ -d "$patches_dir" ]] || return 1
shopt -s nullglob
local patch_files=("$patches_dir"/*.patch)
local patch_dir_files=("$patches_dir"/*)
shopt -u nullglob
if [[ ${#patch_files[@]} -eq 0 ]]; then
if [[ ${#patch_dir_files[@]} -gt 0 ]]; then
print_warning "No .patch files found in $patches_dir"
fi
return 1
fi
print_info "Applying Omarchy patches for $(display_package_name "$package_dir")..."
local patch_file
for patch_file in "${patch_files[@]}"; do
print_info " $(basename "$patch_file")"
if ! (cd "$package_dir" && patch -p1 --forward --batch --no-backup-if-mismatch < "$patch_file"); then
print_error "Failed to apply patch: $patch_file"
return 2
fi
applied=true
done
[[ "$applied" == true ]]
}
run_omarchy_post_sync_hook() {
local package_dir="$1"
local package="$2"
local aur_package="$3"
local aur_pkgrel="$4"
local hook="$package_dir/.omarchy/post-sync.sh"
[[ -f "$hook" ]] || return 1
print_info "Running Omarchy post-sync hook for $(display_package_name "$package_dir")..."
if ! (
cd "$package_dir"
PACKAGE_NAME="$package" \
AUR_PACKAGE_NAME="$aur_package" \
AUR_PKGREL="$aur_pkgrel" \
bash ".omarchy/post-sync.sh"
); then
print_error "Failed to run post-sync hook: $hook"
return 2
fi
return 0
}
apply_pkgrel_suffix_if_customized() {
local package_dir="$1"
local aur_pkgrel="$2"
[[ -n "$aur_pkgrel" ]] || return 0
print_info "Applying Omarchy pkgrel suffix for $(display_package_name "$package_dir"): pkgrel=$aur_pkgrel.1"
set_pkgrel "$package_dir" "$aur_pkgrel.1"
}
apply_pkgrel_override() {
local package_dir="$1"
local aur_pkgrel="$2"
local previous_pkgver="$3"
local metadata="$package_dir/.omarchy/package.json"
local pkgbuild="$package_dir/PKGBUILD"
[[ -f "$metadata" ]] || return 1
jq -e 'has("pkgrel")' "$metadata" >/dev/null || return 1
local current_pkgver suffix offset base rel tmpfile
current_pkgver=$(grep -m1 '^pkgver=' "$pkgbuild" | cut -d= -f2)
if [[ -n "$previous_pkgver" && "$current_pkgver" != "$previous_pkgver" ]]; then
print_info "Removing stale pkgrel metadata for $(display_package_name "$package_dir") (pkgver changed: $previous_pkgver -> $current_pkgver)"
tmpfile=$(mktemp)
jq 'del(.pkgrel)' "$metadata" > "$tmpfile"
mv "$tmpfile" "$metadata"
return 1
fi
suffix=$(jq -r '.pkgrel.suffix // 1' "$metadata")
offset=$(jq -r '.pkgrel.offset // 0' "$metadata")
if [[ ! "$offset" =~ ^[0-9]+$ || ! "$aur_pkgrel" =~ ^[0-9]+$ ]]; then
print_error "pkgrel offset requires numeric AUR pkgrel for $(display_package_name "$package_dir")"
return 2
fi
base=$((aur_pkgrel + offset))
rel="$base.$suffix"
print_info "Applying pkgrel suffix for $(display_package_name "$package_dir"): AUR pkgrel=$aur_pkgrel, offset=$offset, suffix=$suffix -> pkgrel=$rel"
set_pkgrel "$package_dir" "$rel"
return 0
}
sync_package() {
local package="$1"
local package_dir="$PKGBUILDS_DIR/$package"
local metadata="$package_dir/.omarchy/package.json"
if [[ ! -f "$metadata" ]]; then
if [[ "$SPECIFIC_MODE" == true ]]; then
print_error "Package $package is missing .omarchy/package.json"
((++FAILED))
else
print_warning "Skipping $package: missing .omarchy/package.json"
((++SKIPPED))
fi
return 0
fi
if [[ "$(jq -r '.source // ""' "$metadata")" != "aur" ]]; then
print_info "Skipping $package: source is not AUR"
((++SKIPPED))
return 0
fi
if [[ "$(jq -r 'if has("sync") then .sync else true end' "$metadata")" == "false" ]]; then
print_info "Skipping $package: AUR sync disabled"
((++SKIPPED))
return 0
fi
local aur_package
aur_package=$(jq -r --arg package "$package" '.aur // $package' "$metadata")
if [[ "$aur_package" == "$package" ]]; then
print_info "Syncing $package from AUR..."
else
print_info "Syncing $package from AUR package $aur_package..."
fi
cd "$TEMP_DIR"
rm -rf "$aur_package"
if ! git clone "https://aur.archlinux.org/${aur_package}.git" "$aur_package" >/dev/null 2>&1; then
print_warning "Failed to clone $aur_package (may not exist in AUR)"
((++FAILED))
return 0
fi
local aur_dir="$TEMP_DIR/$aur_package"
local work_dir="$TEMP_DIR/${package}.work"
local aur_pkgrel previous_pkgver upstream_commit
aur_pkgrel=$(get_pkgbuild_field "$aur_dir" pkgrel)
previous_pkgver=$(get_pkgbuild_field "$package_dir" pkgver || true)
upstream_commit=$(git -C "$aur_dir" rev-parse HEAD)
rm -rf "$work_dir"
copy_aur_contents "$aur_dir" "$work_dir"
rm -rf "$work_dir/.omarchy"
cp -a "$package_dir/.omarchy" "$work_dir/.omarchy"
local customized=false
if apply_omarchy_patches "$work_dir"; then
customized=true
else
local patch_status=$?
if [[ $patch_status -eq 2 ]]; then
((++FAILED))
return 0
fi
fi
if run_omarchy_post_sync_hook "$work_dir" "$package" "$aur_package" "$aur_pkgrel"; then
customized=true
else
local hook_status=$?
if [[ $hook_status -eq 2 ]]; then
((++FAILED))
return 0
fi
fi
local pkgrel_overridden=false
set +e
apply_pkgrel_override "$work_dir" "$aur_pkgrel" "$previous_pkgver"
local pkgrel_status=$?
set -e
case "$pkgrel_status" in
0) pkgrel_overridden=true ;;
1) ;;
*) ((++FAILED)); return 0 ;;
esac
if [[ "$customized" == true && "$pkgrel_overridden" == false ]]; then
apply_pkgrel_suffix_if_customized "$work_dir" "$aur_pkgrel"
fi
remove_aur_only_files "$work_dir"
set_upstream_commit "$work_dir" "$upstream_commit"
if ! commit_synced_worktree "$work_dir" "$package_dir"; then
((++FAILED))
return 0
fi
SYNCED_PACKAGES+=("$package")
((++SYNCED))
}
if [[ ${#SPECIFIC_PACKAGES[@]} -gt 0 ]]; then
SPECIFIC_MODE=true
for package in "${SPECIFIC_PACKAGES[@]}"; do
sync_package "$package"
done
else
# Sync all packages from list
while IFS= read -r line || [ -n "$line" ]; do
[[ "$line" =~ ^#.*$ ]] && continue
[[ -z "$line" ]] && continue
package=$(echo "$line" | awk '{print $1}')
# Skip GitHub repos (contain /)
if [[ "$package" == *"/"* ]]; then
continue
fi
while IFS= read -r package; do
sync_package "$package"
done < <(grep -v "^#" "$PACKAGES_FILE" | grep -v "^$")
done < <(packages_for_aur_sync)
fi
# Apply patches only to packages that were actually synced
for package in "${SYNCED_PACKAGES[@]}"; do
if [[ -d "$TARGET_DIR/$package/patches" ]]; then
print_info "Applying patches for $package..."
(cd "$TARGET_DIR/$package" && shopt -s nullglob && for patch in patches/*.patch; do
if ! patch -p1 --no-backup-if-mismatch < "$patch"; then
print_error "Failed to apply patch: $patch"
exit 1
fi
done)
fi
done
# Apply pkgrel overrides (version-pinned pkgrel bumps that self-clean)
for package in "${SYNCED_PACKAGES[@]}"; do
override_file="$TARGET_DIR/$package/pkgrel.override"
[[ -f "$override_file" ]] || continue
pkgbuild="$TARGET_DIR/$package/PKGBUILD"
srcinfo="$TARGET_DIR/$package/.SRCINFO"
gitignore="$TARGET_DIR/$package/.gitignore"
current_pkgver=$(grep -m1 '^pkgver=' "$pkgbuild" | cut -d= -f2)
matched=false
while IFS='=' read -r ver rel; do
[[ "$ver" =~ ^#.*$ || -z "$ver" ]] && continue
if [[ "$current_pkgver" == "$ver" ]]; then
print_info "Applying pkgrel override for $package: pkgver=$ver -> pkgrel=$rel"
sed -i "s/^pkgrel=.*/pkgrel=$rel/" "$pkgbuild"
sed -i "s/pkgrel = .*/pkgrel = $rel/" "$srcinfo"
# Ensure .gitignore tracks the override file (AUR may have overwritten it)
if [[ -f "$gitignore" ]] && ! grep -q '^!pkgrel.override$' "$gitignore"; then
echo '!pkgrel.override' >> "$gitignore"
fi
matched=true
break
fi
done < "$override_file"
if [[ "$matched" == false ]]; then
print_info "Removing stale pkgrel.override for $package (no match for pkgver=$current_pkgver)"
rm "$override_file"
fi
done
echo ""
print_success "Sync complete! (tier: $TIER)"
echo " Target: $TARGET_DIR"
if [[ $FAILED -gt 0 ]]; then
print_error "Sync completed with failures"
else
print_success "Sync complete!"
fi
echo " Target: $PKGBUILDS_DIR"
echo " Synced: $SYNCED"
echo " Skipped: $SKIPPED"
echo " Failed: $FAILED"
if [[ $FAILED -gt 0 ]]; then
exit 1
fi