Example: Advanced Build Techniques
These examples showcase more advanced features and workflows, such as running builds as root or using custom viewers for file inspection.
Building as Root with sync-asroot
Normally, aur-build
runs as a regular user and uses sudo
(or a similar tool) to elevate privileges for specific tasks like installing dependencies or updating the local repository.
The sync-asroot
script demonstrates an alternative approach: running the entire build process as root
and dropping privileges for tasks that should be unprivileged, like running makepkg
or gpg
.
This is achieved by setting environment variables that replace the default commands with versions that use runuser
:
AUR_MAKEPKG="runuser -u <user> -- makepkg"
AUR_GPG="runuser -u <user> -- gpg"
AUR_REPO_ADD="runuser -u <user> -- repo-add"
Warning: Building with
makechrootpkg
as root gives the build process unfettered access to the host system, regardless of how the build user is configured. Exercise caution with this method.
sync-asroot
Script
#!/bin/bash
# run as: `sudo sync-asroot ...`
[[ -v AUR_DEBUG ]] && set -o xtrace
SUDO_HOME=$(eval echo "~$SUDO_USER")
XDG_CACHE_HOME=${XDG_CACHE_HOME:-$SUDO_HOME/.cache}
AURDEST=${AURDEST:-$XDG_CACHE_HOME/aurutils/sync}
argv0=sync-asroot
# default options
build_args=(-LR --chroot) sync_args=() keep_going=1
# colors (for build summary)
source /usr/share/makepkg/util/message.sh
if [[ ! -v NO_COLOR ]] && [[ ! -v AUR_DEBUG ]]; then
[[ -t 2 ]] && colorize
fi
# option parsing
unset build_user
while getopts :U:d:k:fSuN OPT; do
case $OPT in
d) build_args+=(-d "$OPTARG"); sync_args+=(-d "$OPTARG") ;;
f) build_args+=(-f "$OPTARG") ;;
S) build_args+=(-S) ;;
U) build_user=$OPTARG ;;
k) keep_going=$OPTARG ;;
u) sync_args+=(-u) ;;
N) sync_args+=(--no-ver) ;;
esac
done
shift $(( OPTIND-1 ))
# 1. define unprivileged commands ------------------------------------------------->
build_user=${build_user:-${SUDO_USER:-$USER}}
build_args+=(-U "$build_user")
build_env=(AUR_MAKEPKG="runuser -u $build_user -- makepkg"
AUR_GPG="runuser -u $build_user -- gpg"
AUR_REPO_ADD="runuser -u $build_user -- repo-add"
AUR_BUILD_PKGLIST="runuser -u $build_user -- aur build--pkglist")
# 2. retrieve sources ------------------------------------------------------------->
ninja_dir=$(runuser -u "$build_user" -- mktemp -d) || exit
trap 'rm -rf "$ninja_dir"' EXIT
runuser -u "$build_user" -- \
env AURDEST="$AURDEST" aur sync "${sync_args[@]}" "$@" --columns --save "$ninja_dir"/graph || exit 1
# 3. build queue ------------------------------------------------------------------>
if [[ -s $ninja_dir/graph ]]; then
runuser -u "$build_user" -- aur sync--ninja "$AURDEST" <"$ninja_dir"/graph >"$ninja_dir"/build.ninja -- \
env AUR_ASROOT=1 "${build_env[@]}" aur build "${build_args[@]}"
env NINJA_STATUS='[%s/%t] ' ninja -C "$ninja_dir" -k "$keep_going"
# ... (build summary continues)
fi
Custom File Viewing with view-delta
aur-view
uses a file manager defined by the AUR_PAGER
environment variable to inspect build files. The view-delta
script is an example of a custom pager that provides a different inspection experience.
Instead of an interactive file manager, view-delta
assumes you won't be editing the files. It uses modern command-line tools for a read-only review:
- Displays Diffs: It uses
delta
(ordiff-so-fancy
) to show colorful, side-by-side diffs for any changed files. - Displays Other Files: It uses
bat
for syntax-highlighted output of any new or unchanged files. - Confirmation Prompt: It displays a prompt at the end, allowing you to continue (by pressing Enter) or abort the build (by pressing Ctrl+D).
Usage
Set AUR_PAGER
to the path of the view-delta
script:
AUR_PAGER=/path/to/view-delta aur sync <package>
view-delta
Script
#!/bin/bash
[[ -v AUR_DEBUG ]] && set -o xtrace
set -o errexit
shopt -s extglob
# Helper function to take complements of pkgbase arrays
filter_packages() { grep -Fxvf <(printf '%s\n' "$@") -; }
# Directory with diffs and PKGBUILD subdirs
cd "${1:-/dev/null}"
diffs=(@(*.diff|*.log))
pkgbases=(*/)
pkgbases=("${pkgbases[@]%/}")
# Show diffs in 2 panes
if [[ -f ${diffs[0]} ]]; then
cat "${diffs[@]}" | delta --diff-so-fancy --paging=always --line-numbers --navigate
# Remove diffs from remaining targets (new or unchanged dirs)
mapfile -t pkgbases < <(
printf '%s\n' "${pkgbases[@]}" | filter_packages "${diffs[@]%%.*}")
fi >&2
# Show remaining targets in a concatenated fashion
if (( ${#pkgbases[@]} )); then
# Only print files in the git repository
find -L "${pkgbases[@]}" -prune -exec sh -c 'git -C {} ls-files -z | env -C {} xargs -0r realpath -z' \; |
grep -Ezv '.SRCINFO|.gitignore' | xargs -0r bat --paging=always
fi >&2
# Show an exit prompt
read -rp $'Press Return to continue or Ctrl+d to abort\n'