Example: Managing Repository Contents

These examples demonstrate advanced workflows for managing the packages within your local repository, such as cleaning unused packages or rebuilding packages against new dependencies.

Keeping a Repository Clean with sync-list

As you use aur-sync, packages can accumulate in your local repository. To prevent it from growing with unused packages and their dependencies, you can maintain a specific list of desired packages.

The sync-list script ensures that your local repository only contains packages from a given list and their dependencies. Any other packages are removed.

Key Steps:

  1. Create a Temporary Repository: It makes a copy of the existing local repository database.
  2. Calculate Dependency Tree: It determines the full dependency tree for the packages in your target list.
  3. Remove Unneeded Packages: It uses repo-remove to purge any packages from the temporary database that are not in the dependency tree.
  4. Sync New Packages: It runs aur-sync using a temporary pacman.conf that points to the clean, temporary repository.
  5. Update Real Repository: Finally, it uses rsync --delete to synchronize the state of the temporary repository back to your actual local repository, removing any packages that are no longer needed.

sync-list Script

#!/bin/bash
set -e
argv0=sync-list

# Targets are taken from a file or the command-line, to avoid
# redirecting stdin to aur-view or aur-build.
if [[ -s $1 ]]; then
    list=$(realpath -- "$1")
else
    printf >&2 '%s: %s: file is empty or does not exist\n' "$argv0" "$1"
    exit 1
fi

# Create a scratch space. /var/tmp ensures sufficient space for built
# packages (not on tmpfs by default)
var_tmp=$(mktemp -d --tmpdir="${TMPDIR:-/var/tmp/}")
tmp=$(mktemp -d)
trap 'rm -rf "$tmp" "$var_tmp"' EXIT # comment this if inspecting the contents

# 1. Avoid concurrent use
( flock -n 200 || exit 1
  cd "$tmp"

  # Retrieve repository location
  { IFS=: read -r _ db_name
    IFS=: read -r _ db_root
    IFS=: read -r _ db_path
  } < <(aur repo --status "$@")
  wait "$!"

  # 2. Retrieve targets and their dependencies from the local repository.
  aur repo-parse -p "$db_path" --table | tee db_table | \
      cut -f1,2 | grep -Fwf "$list" | tsort >db_deps

  # 3. Remove entries that are not in the dependency tree.
  cut -f1 db_table | grep -Fxvf db_deps | sort -u >db_removals

  files_path=$(realpath "$db_root/$db_name".files)

  # Create copy of local repository database
  cp -Pv "$db_path" "$db_root/$db_name".db "$var_tmp"
  cp -Pv "$files_path" "$db_root/$db_name".files "$var_tmp"

  # 4. Remove entries that are not in the dependency tree.
  cd "$var_tmp"
  xargs -a "$tmp"/db_removals -r repo-remove "${db_path##*/}"

  # 5. Add symlinks to built packages.
  aur repo-parse -p "$db_path" --attr FileName | \
      xargs env -C "$db_root" realpath -z | xargs -0r ln -t "$var_tmp" -s --

  # 6. Point the repository root in pacman.conf to the temporary directory.
  { printf '[options]\n'
    pacconf --raw --options

    while IFS= read -r; do
        # section header
        printf '[%s]\n' "$REPLY"

        if [[ $REPLY == "$db_name" ]]; then
            pacconf --raw --repo="$REPLY" --verbose Usage SigLevel
            printf '%s\n' "Server = file://$var_tmp"
        else
            pacconf --raw --repo="$REPLY" --verbose Usage SigLevel Server
        fi
    done < <(pacconf --repo-list)
  } >"$tmp"/pacman.conf

  # 7. Run aur-sync(1) with the new pacman configuration.
  # Adjust options to preference.
  aur sync -d "$db_name" --pacman-conf="$tmp"/pacman.conf -Rrn $(<"$list")

  # 8. Synchronize the new repository state to the original location.
  # Remove --dry-run if the output is as desired.
  set -x
  rsync -avh "$var_tmp"/ "$db_root"/ --delete \
        --copy-links --exclude={"$db_name".db,"$db_name".files} --dry-run

  # 9. Save list with new dependency tree
  cp -v "$list" "$list".old
  aur repo-parse -p "$db_path" --list | cut -f1 >"$list"

) 200> /tmp/lockfile

Rebuilding Packages with sync-rebuild

Package rebuilds are necessary when a dependency updates in a way that breaks compatibility, requiring dependents to be rebuilt against the new version. The sync-rebuild script automates this process.

Key Steps:

  1. Fetch Sources: Ensures all sources for the target packages are available locally.
  2. Compare Versions: Compares the version in the PKGBUILD with the version in the local repository.
  3. Increment pkgrel: If the versions match, it increments the pkgrel in the PKGBUILD by 0.1. This ensures pacman sees the rebuilt package as an upgrade.
  4. Build Package: Builds the package with the modified PKGBUILD. If the build fails, it restores the original file.

sync-rebuild Script

This example is a Python script demonstrating a more complex workflow.

#!/usr/bin/env python3
""" Rebuild AUR packages against newer dependencies
"""
import json
import fileinput
import sys
# ... (script continues)
(For brevity, the full Python script is omitted here. It can be found in the examples directory of the repository.)

Finding Packages to Rebuild

You can use aur repo to find packages that depend on a specific library that has been updated.

# Find all packages in the 'custom' repo that depend on python
aur repo -d custom --search '^python.*' --search-by depends --list

Rebuild Order

For AUR packages, the rebuild order can be determined using aur depends:

# Get the correct build order for targets
aur depends --reverse <targets...> | tsort