Files
omarchy-pkgs/pkgbuilds/omarchy-settings-dev/PKGBUILD
T
40ea1555f2 Ship the complete passwordless-sudo lifecycle in settings-dev (#645)
* Move the dev sudo grant lifecycle into omarchy-settings-dev

The hardened omarchy-sudo-passwordless publishes a grant only when its revocation hook is installed and no package transaction has left /run/omarchy-sudo-passwordless-package-removing behind. The hook sets that marker before every settings upgrade, and the settings scriptlets are what clear it, so shipping the hook alone let the first grant work and then refused every grant after the next update until a reboot.

omarchy-settings-dev now ships the command, omarchy-security-functions, the boot cleanup rule and the hook together, with the scriptlets from #257 that revoke before the package changes and clear the marker once no grant remains. omarchy-dev stops shipping the two helpers and requires the settings release that does: without it omarchy-update has no library to source.

Co-authored-by: Afonso Oliveira <afonso.oliveira707@gmail.com>

* Check that settings-dev registers the scriptlet the lifecycle test exercises

The lifecycle test reads the .install file directly, so it kept passing with the recipe's install= line gone, which is the one change that would strand the hook's marker again.

Co-Authored-By: Codex XHigh <noreply@openai.com>

* Keep omarchy-dev's settings dependency unversioned

The dev pair builds each package on its own against the published edge repository, in the PR build and in publish alike, so omarchy-dev cannot require a settings-dev release that only this change produces: the floor failed both omarchy-dev builds on this PR, and an exact pkgver match would fail the same way on every upstream pin bump. Nothing needs it. The upstream watch moves both pins together, publish stops the run before anything is published when one package fails, and a new settings-dev over an old runtime is refused on the files they would both own.

* Refuse settings-dev releases that predate the grant helper move

With the dependency unversioned, a new omarchy-dev could still install over a settings-dev that is held back or not yet published, removing omarchy-security-functions from both, and omarchy-update cannot start without it. A versioned conflict refuses that pairing at install time without constraining the per-package builds, which resolve only depends.

Co-Authored-By: Codex XHigh <noreply@openai.com>

* Require the security library as a capability instead of a version floor

The conflict named the last settings-dev release without the helpers, a version that moves with every upstream pin bump and settings-only pkgrel while this change waits to merge, and a rebase that kept a stale floor still passed the tests while the published release slipped past it. omarchy-settings-dev now provides omarchy-security-functions and omarchy-dev's package() requires it. makepkg checks only the top-level depends before building, so the per-package builds still resolve against the published repository, while pacman refuses a runtime without a settings release that ships the library, and pulls that release in when only the runtime is asked for.

Co-Authored-By: Codex XHigh <noreply@openai.com>

---------

Co-authored-by: Spencer Bull <spencer@omarchy.org>
Co-authored-by: Afonso Oliveira <afonso.oliveira707@gmail.com>
Co-authored-by: Codex XHigh <noreply@openai.com>
2026-10-11 09:56:47 -05:00

504 lines
26 KiB
Bash

# Maintainer: Ryan Hughes <ryan@omarchy.org>
pkgname='omarchy-settings-dev'
pkgver=4.0.0.r6897.g4df5459
pkgrel=2
# Pinned by the upstream watch in .omarchy/package.json (bin/sync-upstream):
# every quattro tip becomes a commit pin here, so the package is versioned,
# checksummed and built exactly like a release, just more often. The r-number
# is the branch's total commit count, not the distance from the last tag: the
# published history used the total, and pacman must never see it go down.
_commit=4df545905d70b92d7c2dc62b339ff529d0075551
pkgdesc='Omarchy user defaults, /etc/skel content, fonts, plymouth theme, and support helpers (quattro branch tip)'
# Arch-specific because the shipped /etc tree is not the same on every
# architecture for older sources: their zram and oomd drop-ins belong to the
# x86_64 memory stack and are left out of the aarch64 package (see package()).
# The Limine and mkinitcpio drop-ins ship on both: UEFI aarch64 installs (DGX
# Spark, Snapdragon X) boot with Limine and an encrypted root exactly like
# x86_64. A source with default/settings-runtime-profile decides at runtime
# which platform-specific files apply, and its aarch64 package ships the same
# files as x86_64. makepkg only honours the arch-suffixed arrays below on
# arch-specific packages.
arch=('x86_64' 'aarch64')
url='https://github.com/basecamp/omarchy'
license=('MIT')
provides=('omarchy-settings' 'omarchy-security-functions')
conflicts=('omarchy-settings')
# `/etc/default/limine` is intentionally NOT owned by this package. The ISO
# orchestrator generates it at install time from the resolved target boot
# cmdline. We ship a template under /usr/share/omarchy/default/limine/ for the
# orchestrator to read.
#
# limine + limine-mkinitcpio-hook + limine-snapper-sync + snapper are NOT in
# depends because this package gets installed into the live ISO env (for
# plymouth / /etc/skel seeding) where there is no ESP and the mkinitcpio hook
# would fail trying to deploy Limine. The target omarchy package pulls in the
# full bootloader/snapshot stack; omarchy-iso only installs the early Limine
# pieces needed before the runtime package lands.
depends=(
'bash'
'curl'
'gum'
'sudo'
'hicolor-icon-theme'
'plymouth'
)
makedepends=(
'git'
'imagemagick'
)
# backup=() is pacman's hook for protecting user edits to package-owned files
# on upgrade. Only the paths the package actually installs into /etc qualify.
# The etc-overrides set (faillock.conf, nsswitch.conf, cups-browsed.conf,
# cups-files.conf, plymouthd.conf, /etc/skel/.bashrc) ships at
# /usr/share/omarchy/etc-overrides/
# and is cp -f'd by post_install — those paths are unowned by pacman and the
# scriptlet WILL clobber user edits on each upgrade (documented limitation).
backup=(
'etc/fastfetch/config.jsonc'
'etc/docker/daemon.json'
'etc/gnupg/dirmngr.conf'
'etc/sysctl.d/99-omarchy-sysctl.conf'
'etc/sysctl.d/90-omarchy-file-watchers.conf'
'etc/systemd/logind.conf.d/10-ignore-power-button.conf'
'etc/systemd/logind.conf.d/20-inhibit-delay.conf'
'etc/systemd/resolved.conf.d/10-disable-multicast.conf'
'etc/systemd/resolved.conf.d/20-docker-dns.conf'
'etc/systemd/system.conf.d/10-faster-shutdown.conf'
'etc/systemd/system/user@.service.d/10-faster-shutdown.conf'
'etc/systemd/system/docker.service.d/no-block-boot.conf'
'etc/systemd/system/plocate-updatedb.service.d/ac-only.conf'
'etc/systemd/system.conf.d/20-omarchy-nofile.conf'
'etc/systemd/user.conf.d/20-omarchy-nofile.conf'
'etc/sddm.conf.d/10-theme.conf'
'etc/sddm.conf.d/10-wayland.conf'
'etc/udev/rules.d/60-omarchy-io-scheduler.rules'
'etc/udev/rules.d/99-omarchy-power-profile.rules'
'etc/udev/rules.d/99-omarchy-wifi-powersave.rules'
)
# Boot configuration is backed up on both architectures.
backup+=(
'etc/mkinitcpio.conf.d/omarchy_hooks.conf'
'etc/limine-entry-tool.d/omarchy-defaults.conf'
'etc/limine-entry-tool.d/omarchy-uki.conf'
)
# backup has no arch-suffixed form, so the x86_64-only drop-ins join it here.
# Each of these paths is removed from an older source's aarch64 package in
# package(), which adds them back for a runtime-profile source.
_x86_64_backup=(
'etc/mkinitcpio.conf.d/thunderbolt_module.conf'
'etc/modprobe.d/omarchy-usb-autosuspend.conf'
'etc/systemd/oomd.conf.d/10-omarchy.conf'
'etc/systemd/zram-generator.conf'
)
if [[ $CARCH == x86_64 ]]; then
backup+=("${_x86_64_backup[@]}")
fi
optdepends=(
'omarchy-dev: Full Omarchy desktop (quattro branch tip)'
'inxi: System information for omarchy-debug'
'fastfetch: System information for omarchy-upload-log'
)
optdepends_x86_64=(
'limine: Bootloader the shipped /etc/mkinitcpio.conf.d/ and /etc/limine-entry-tool.d/ drop-ins are for'
'limine-mkinitcpio-hook: Picks up the shipped /etc/mkinitcpio.conf.d/omarchy_hooks.conf'
'limine-snapper-sync: Boot-entry sync for snapper snapshots'
'zram-generator: Reads the shipped /etc/systemd/zram-generator.conf to create the compressed swap device'
'snapper: Used with the shipped /etc/snapper/config-templates/omarchy template'
)
install='omarchy-settings-dev.install'
# Live config files the package can't own outright (the path is owned by an
# upstream Arch package): ship them at /usr/share/omarchy/etc-overrides/ and
# cp -f into place from post_install. See omarchy-settings-dev.install.
_etc_override_paths=(
'etc/security/faillock.conf'
'etc/nsswitch.conf'
'etc/cups/cups-browsed.conf'
'etc/cups/cups-files.conf'
'etc/plymouth/plymouthd.conf'
)
# Source: the pinned quattro commit. Set OMARCHY_SRC=/path/to/checkout to
# build from a local source tree instead (mirrors omarchy-zsh/omarchy-fish DX);
# the arrays are emptied below so nothing is downloaded in that case.
source=("omarchy::git+https://github.com/basecamp/omarchy.git#commit=${_commit}")
sha256sums=('31bfb9dd158ead5bd6e740bb82df7f89532a587fdd84b1711ed3a5688c2cab48')
if [[ -n "${OMARCHY_SRC:-}" ]]; then
source=()
sha256sums=()
fi
prepare() {
if [[ -n "${OMARCHY_SRC:-}" ]]; then
rm -rf "$srcdir/omarchy"
mkdir -p "$srcdir/omarchy"
cp -a "${OMARCHY_SRC}/." "$srcdir/omarchy/"
fi
}
# Print the HOOKS that result from sourcing mkinitcpio drop-ins onto a line.
_omarchy_settings_hooks_after() {
local start=$1
shift
(
# Keep the build host's own tools, such as a platform detector, out of it.
PATH=/nonexistent
read -ra HOOKS <<<"$start"
MODULES=() FILES=()
for conf in "$@"; do
# shellcheck disable=SC1090
source "$conf" || exit 1
done
echo "${HOOKS[*]}"
)
}
package() {
cd "$srcdir/omarchy"
# A source that decides at runtime which platform-specific files apply (see
# default/settings-runtime-profile in it) ships its whole tree on aarch64,
# with the same backup and optdepends as x86_64. Older sources still leave
# the x86_64 memory stack out there.
local legacy_aarch64=0
if [[ $CARCH == aarch64 ]]; then
if [[ -f default/settings-runtime-profile ]]; then
backup+=("${_x86_64_backup[@]}")
optdepends+=("${optdepends_x86_64[@]}")
else
legacy_aarch64=1
fi
fi
# /etc/skel/.config from config/** — system-wide default user config.
# Package-owned defaults that live elsewhere in the system belong under
# default/** or etc/** instead.
install -d "$pkgdir/etc/skel/.config"
cp -a config/. "$pkgdir/etc/skel/.config/"
# Fastfetch reads /etc/fastfetch/config.jsonc when no user config exists.
install -Dm644 etc/fastfetch/config.jsonc "$pkgdir/etc/fastfetch/config.jsonc"
# ALSO ship config/** under /usr/share/omarchy/config/. Used as the
# source-of-truth by omarchy-refresh-config, omarchy-reinstall-configs,
# and other commands that copy individual files into a running user's
# ~/.config. /etc/skel only seeds new users; this tree is what existing
# users re-sync against.
install -d "$pkgdir/usr/share/omarchy/config"
cp -a config/. "$pkgdir/usr/share/omarchy/config/"
# Package-owned defaults with real system/XDG locations. User config remains
# higher priority: ~/.config/uwsm/default, ~/.config/uwsm/env.d,
# ~/.config/environment.d, ~/.config/fontconfig, ~/.config/xdg-terminals.list,
# ~/.config/mimeapps.list, and ~/.config/systemd/user can all override these.
install -Dm644 default/uwsm/env.d/10-omarchy "$pkgdir/usr/share/uwsm/env.d/10-omarchy"
install -Dm644 default/environment.d/10-omarchy-fcitx.conf "$pkgdir/usr/lib/environment.d/10-omarchy-fcitx.conf"
install -Dm644 default/fontconfig/conf.avail/50-omarchy.conf "$pkgdir/usr/share/fontconfig/conf.avail/50-omarchy.conf"
install -d "$pkgdir/etc/fonts/conf.d"
ln -sfn /usr/share/fontconfig/conf.avail/50-omarchy.conf "$pkgdir/etc/fonts/conf.d/50-omarchy.conf"
install -Dm644 default/xdg-terminal-exec/hyprland-xdg-terminals.list "$pkgdir/usr/share/xdg-terminal-exec/hyprland-xdg-terminals.list"
install -Dm644 default/applications/mimeapps.list "$pkgdir/usr/share/applications/mimeapps.list"
install -Dm644 default/systemd/user/bt-agent.service "$pkgdir/usr/lib/systemd/user/bt-agent.service"
install -Dm644 default/systemd/user/omarchy-sleep-lock.service "$pkgdir/usr/lib/systemd/user/omarchy-sleep-lock.service"
install -Dm644 default/systemd/user/omarchy-recover-internal-monitor.service "$pkgdir/usr/lib/systemd/user/omarchy-recover-internal-monitor.service"
install -Dm644 default/systemd/user/omarchy-migrate-notify.service "$pkgdir/usr/lib/systemd/user/omarchy-migrate-notify.service"
# Compatibility alias for the old unit name. Existing users have an absolute
# graphical-session.target.wants symlink to this path from when they were set
# up, and the migration that repoints it only runs for users who actually run
# an update -- which is the opposite of who this notifier is for. Without the
# alias their symlink dangles and they are never told about pending
# migrations. Droppable once installs have run migration 1785095882.
ln -sfn omarchy-migrate-notify.service "$pkgdir/usr/lib/systemd/user/omarchy-update-user-notify.service"
install -Dm644 default/systemd/user/omarchy-tailscale-receive.service "$pkgdir/usr/lib/systemd/user/omarchy-tailscale-receive.service"
install -Dm644 default/systemd/user/omarchy-fcitx5.service "$pkgdir/usr/lib/systemd/user/omarchy-fcitx5.service"
install -Dm644 default/systemd/user/omarchy-crash-watch.service "$pkgdir/usr/lib/systemd/user/omarchy-crash-watch.service"
# First-run enables this unit, so it ships wherever the source has it.
if [[ -f default/systemd/user/omarchy-brightness-keyboard-auto.service ]]; then
install -Dm644 default/systemd/user/omarchy-brightness-keyboard-auto.service "$pkgdir/usr/lib/systemd/user/omarchy-brightness-keyboard-auto.service"
fi
# First-run, a migration and their own setup commands enable the USB and
# Thunderbolt approval watchers. Left in /usr/share/omarchy/default alone,
# systemd cannot find them: the Thunderbolt migration fails, which holds back
# every migration after it, and first-run enables none of its units.
if [[ -f default/systemd/user/omarchy-usb-authorization.service ]]; then
install -Dm644 default/systemd/user/omarchy-usb-authorization.service "$pkgdir/usr/lib/systemd/user/omarchy-usb-authorization.service"
fi
if [[ -f default/systemd/user/omarchy-thunderbolt-authorization.service ]]; then
install -Dm644 default/systemd/user/omarchy-thunderbolt-authorization.service "$pkgdir/usr/lib/systemd/user/omarchy-thunderbolt-authorization.service"
fi
# Marks app.slice (and only app.slice) as a systemd-oomd kill candidate, so
# memory pressure costs one app scope instead of the compositor session.
# Thresholds live in etc/systemd/oomd.conf.d/10-omarchy.conf. Both this and
# the zram vendor drop-in belong to the x86_64 memory stack: an older
# source's aarch64 install neither enables systemd-oomd nor configures zram.
if (( ! legacy_aarch64 )); then
install -Dm644 default/systemd/user/app.slice.d/10-oomd.conf "$pkgdir/usr/lib/systemd/user/app.slice.d/10-oomd.conf"
install -Dm644 default/systemd/zram-generator.conf.d/90-omarchy.conf "$pkgdir/usr/lib/systemd/zram-generator.conf.d/90-omarchy.conf"
fi
install -Dm644 default/systemd/system/plocate-updatedb.service.d/10-omarchy.conf "$pkgdir/usr/lib/systemd/system/plocate-updatedb.service.d/10-omarchy.conf"
# Same for applications/** — used by omarchy-refresh-applications,
# omarchy-install-gaming-*, etc. to copy .desktop files into ~/.local/share.
install -d "$pkgdir/usr/share/omarchy/applications"
cp -a applications/. "$pkgdir/usr/share/omarchy/applications/"
# Icons are package-owned below in /usr/share/icons/hicolor, not this
# historical app-local folder.
rm -rf "$pkgdir/usr/share/omarchy/applications/icons"
# /etc tree (drop-ins the package fully owns + the etc-override files we
# stage separately below).
install -d "$pkgdir/etc"
cp -a etc/. "$pkgdir/etc/"
# omacom/omarchy#13362 moves the HOOKS baseline into its own drop-in.
[[ ! -f $pkgdir/etc/mkinitcpio.conf.d/00-omarchy-hooks.conf ]] ||
backup+=('etc/mkinitcpio.conf.d/00-omarchy-hooks.conf')
if [[ $CARCH == aarch64 ]]; then
# Keep omarchy_hooks.conf and the Limine entry-tool config: without them a
# kernel update on an encrypted aarch64 install rebuilds an initramfs with
# no encrypt hook and the machine cannot unlock its root. An older source's
# Thunderbolt module request is x86-specific; ARM kernels lack the module
# and mkinitcpio treats a missing explicit module as an error. A
# runtime-profile source adds it only where the kernel has the module.
(( ! legacy_aarch64 )) || rm -f "$pkgdir/etc/mkinitcpio.conf.d/thunderbolt_module.conf"
# Apple Silicon Macs install this package too. Their initramfs needs the
# asahi hook, which omarchy-mac-boot's 90-94 fragments (Aurora) or
# mkinitcpio.conf (legacy GRUB Macs) set, and an unconditional HOOKS= here
# would replace it. An older source that sets HOOKS outright (v4.0.4) gets
# its line wrapped so it applies only when the hooks loaded so far lack
# asahi; one that already decides per platform (omacom/omarchy#13362), and
# every runtime-profile source, ships as it is. The wrapper reads
# configuration, not the running machine, so it also holds when the image
# is built in a chroot.
local hooks_conf hooks_confs=()
for hooks_conf in "$pkgdir"/etc/mkinitcpio.conf.d/{00-omarchy-hooks,omarchy_hooks}.conf; do
[[ -f $hooks_conf ]] || continue
hooks_confs+=("$hooks_conf")
(( legacy_aarch64 )) || continue
sed -i 's/^\(HOOKS=([^#]*)\)[[:space:]]*$/if [[ " ${HOOKS[*]:-} " != *" asahi "* ]]; then\n \1\nfi/' "$hooks_conf"
if grep -q '^HOOKS=' "$hooks_conf"; then
echo "${hooks_conf#"$pkgdir"/}: cannot guard this HOOKS= line for Apple Silicon" >&2
return 1
fi
done
# Whatever the layout, a Mac's asahi line must come through the shipped
# files, and a stock line must not: that is where Omarchy's hooks come from.
local mac_line='base udev block asahi encrypt filesystems fsck' stock_line='base udev block filesystems fsck'
local mac_hooks stock_hooks
if ! mac_hooks=$(_omarchy_settings_hooks_after "$mac_line" "${hooks_confs[@]}") ||
! stock_hooks=$(_omarchy_settings_hooks_after "$stock_line" "${hooks_confs[@]}") ||
[[ $mac_hooks != "$mac_line" || $stock_hooks == "$stock_line" ]]; then
echo "etc/mkinitcpio.conf.d: the aarch64 hooks must keep a Mac's asahi line and set everyone else's" >&2
return 1
fi
fi
if (( legacy_aarch64 )); then
# Memory stack: no zram device or zswap on an older source's aarch64
# install, and systemd-oomd is not enabled there, so the vm.* reclaim
# tuning written for zram would be wrong for it. Keep only the network
# tuning.
rm -rf "$pkgdir/etc/systemd/oomd.conf.d"
rm -f "$pkgdir/etc/systemd/zram-generator.conf" "$pkgdir/etc/tmpfiles.d/omarchy-zswap.conf"
cat >"$pkgdir/etc/sysctl.d/99-omarchy-sysctl.conf" <<'EOF'
# Solve common flakiness with SSH (MTU discovery on flaky links).
net.ipv4.tcp_mtu_probing=1
EOF
# USB autosuspend is left at the kernel default on Apple Silicon.
rm -f "$pkgdir/etc/modprobe.d/omarchy-usb-autosuspend.conf"
rmdir "$pkgdir/etc/modprobe.d" "$pkgdir/etc/tmpfiles.d" 2>/dev/null || true
fi
# sudoers.d files must be mode 0440 or sudo will refuse them, and the
# directory must be 0750 to match the Arch sudo package's filesystem
# convention (otherwise pacman warns about dir-mode drift on every install).
if [[ -d "$pkgdir/etc/sudoers.d" ]]; then
chmod 0750 "$pkgdir/etc/sudoers.d"
chmod 0440 "$pkgdir/etc/sudoers.d"/*
fi
# Stage upstream-owned files at /usr/share/omarchy/etc-overrides/ instead of
# owning their live /etc paths directly (which would conflict with pam,
# filesystem, cups-browsed, plymouth, bash). post_install copies them in.
install -d "$pkgdir/usr/share/omarchy/etc-overrides"
install -Dm644 default/bashrc \
"$pkgdir/usr/share/omarchy/etc-overrides/dot.bashrc"
cat >"$pkgdir/usr/share/omarchy/etc-overrides/os-release" <<EOF
NAME="Omarchy"
PRETTY_NAME="Omarchy"
ID=omarchy
ID_LIKE=arch
BUILD_ID="$pkgver"
VERSION_ID="$pkgver"
ANSI_COLOR="38;2;158;206;106"
HOME_URL="https://omarchy.org/"
DOCUMENTATION_URL="https://learn.omacom.io/2/the-omarchy-manual"
SUPPORT_URL="https://discord.gg/tXFUdasqhY"
BUG_REPORT_URL="https://github.com/basecamp/omarchy/issues"
LOGO=omarchy
EOF
for path in "${_etc_override_paths[@]}"; do
case "$path" in
'etc/security/faillock.conf')
mv "$pkgdir/$path" "$pkgdir/usr/share/omarchy/etc-overrides/security-faillock.conf" ;;
'etc/nsswitch.conf')
mv "$pkgdir/$path" "$pkgdir/usr/share/omarchy/etc-overrides/nsswitch.conf" ;;
'etc/cups/cups-browsed.conf')
mv "$pkgdir/$path" "$pkgdir/usr/share/omarchy/etc-overrides/cups-cups-browsed.conf" ;;
'etc/cups/cups-files.conf')
[[ ! -f $pkgdir/$path ]] || mv "$pkgdir/$path" "$pkgdir/usr/share/omarchy/etc-overrides/cups-cups-files.conf" ;;
'etc/plymouth/plymouthd.conf')
mv "$pkgdir/$path" "$pkgdir/usr/share/omarchy/etc-overrides/plymouth-plymouthd.conf" ;;
esac
done
# The directories under /etc we just emptied are upstream-owned; remove our
# empty placeholders so pacman doesn't complain.
rmdir "$pkgdir/etc/security" 2>/dev/null || true
rmdir "$pkgdir/etc/cups" 2>/dev/null || true
rmdir "$pkgdir/etc/plymouth" 2>/dev/null || true
# /etc/skel/.local/share/applications from applications/**.
install -d "$pkgdir/etc/skel/.local/share/applications"
if compgen -G 'applications/*.desktop' >/dev/null; then
cp applications/*.desktop "$pkgdir/etc/skel/.local/share/applications/"
fi
if [[ -d applications/hidden ]] && compgen -G 'applications/hidden/*.desktop' >/dev/null; then
cp applications/hidden/*.desktop "$pkgdir/etc/skel/.local/share/applications/"
fi
# Package-owned application icons in standard freedesktop hicolor paths.
# Desktop files and generated webapp/TUI launchers reference these by icon
# name, so user setup no longer needs to copy static Omarchy icons into
# ~/.local/share.
if [[ -d applications/icons ]] && compgen -G 'applications/icons/*' >/dev/null; then
install -d "$pkgdir/usr/share/icons/hicolor/256x256/apps"
install -d "$pkgdir/usr/share/icons/hicolor/48x48/apps"
for icon in applications/icons/*; do
[[ -f $icon ]] || continue
icon_name=$(basename "$icon")
icon_id=$(printf '%s\n' "${icon_name%.*}" \
| tr '[:upper:]' '[:lower:]' \
| sed 's/[^[:alnum:]]\+/-/g; s/^-//; s/-$//')
case "$icon_name" in
*.svg)
install -Dm644 "$icon" "$pkgdir/usr/share/icons/hicolor/scalable/apps/$icon_id.svg"
;;
*)
magick "$icon" -thumbnail 256x256 -background transparent -gravity center -extent 256x256 \
"PNG32:$pkgdir/usr/share/icons/hicolor/256x256/apps/$icon_id.png"
magick "$icon" -thumbnail 48x48 -background transparent -gravity center -extent 48x48 \
"PNG32:$pkgdir/usr/share/icons/hicolor/48x48/apps/$icon_id.png"
;;
esac
done
fi
# default/** ships to /usr/share/omarchy/default/. The Snapper template is
# additionally installed to /etc/snapper/config-templates/ for the standard
# Snapper template location; Omarchy target setup copies the default into the
# live root config.
install -d "$pkgdir/usr/share/omarchy/default"
cp -a default/. "$pkgdir/usr/share/omarchy/default/"
# Snapper config template used by the install-time `snapper create-config`.
install -Dm644 default/snapper/root \
"$pkgdir/etc/snapper/config-templates/omarchy"
# SDDM theme/session assets. These are static package-owned files; the
# installer only writes autologin.conf because that embeds the install user.
install -d -m 0755 "$pkgdir/usr/share/sddm/themes"
cp -a default/sddm/omarchy "$pkgdir/usr/share/sddm/themes/"
find "$pkgdir/usr/share/sddm/themes/omarchy" -type d -exec chmod 0755 {} +
find "$pkgdir/usr/share/sddm/themes/omarchy" -type f -exec chmod 0644 {} +
install -Dm644 default/sddm/hyprland.lua "$pkgdir/usr/share/sddm/hyprland.lua"
install -Dm644 default/wayland-sessions/omarchy.desktop \
"$pkgdir/usr/local/share/wayland-sessions/omarchy.desktop"
# Plymouth theme. Files at 0644, dirs at 0755 (the upstream plymouth
# package's convention for /usr/share/plymouth/themes/*). cp -a inherits
# the source dir's mode, which is whatever the build host has — chmod
# explicitly so installs are consistent regardless of build environment.
install -d -m 0755 "$pkgdir/usr/share/plymouth/themes/omarchy"
cp -a default/plymouth/. "$pkgdir/usr/share/plymouth/themes/omarchy/"
find "$pkgdir/usr/share/plymouth/themes/omarchy" -type d -exec chmod 0755 {} +
find "$pkgdir/usr/share/plymouth/themes/omarchy" -type f -exec chmod 0644 {} +
# System font.
install -Dm644 default/fonts/omarchy/omarchy.ttf "$pkgdir/usr/share/fonts/omarchy/omarchy.ttf"
# systemd system-sleep hook (lazy-unmounts gvfsd-fuse mounts before
# suspend/hibernate). The script also ships under /usr/share/omarchy/default
# via the default/** copy above; we additionally install it to the live
# systemd path so the hook fires.
install -Dm755 default/systemd/system-sleep/unmount-fuse \
"$pkgdir/usr/lib/systemd/system-sleep/unmount-fuse"
# Pacman platform guard: refuses packages tagged for another hardware
# platform. It ships here, not in omarchy, so it is resident before the
# runtime and any hardware package install; the hook, the script it runs and
# the script's own copy of the platform detector travel together (omarchy
# keeps /usr/bin/omarchy-hw-platform). aarch64 only: no platform package is
# built for x86_64, so an x86 machine has nothing to guard, and its HOOKS
# baseline needs no detector. Conditional until the pinned source carries
# them.
if [[ $CARCH == aarch64 && -f default/libalpm/hooks/00-omarchy-platform-guard.hook ]]; then
install -Dm644 default/libalpm/hooks/00-omarchy-platform-guard.hook \
"$pkgdir/usr/share/libalpm/hooks/00-omarchy-platform-guard.hook"
install -Dm755 default/libalpm/scripts/omarchy-platform-guard \
"$pkgdir/usr/share/libalpm/scripts/omarchy-platform-guard"
install -Dm755 bin/omarchy-hw-platform \
"$pkgdir/usr/share/libalpm/scripts/omarchy-hw-platform"
fi
# Temporary passwordless sudo: the grant command, its library, the boot
# cleanup rule from etc/ and the hook that revokes grants before this
# package changes all live here, so the hook never outlives its Exec target
# and removing the runtime alone keeps expiry working.
for helper in omarchy-sudo-passwordless omarchy-security-functions; do
install -Dm755 "bin/$helper" "$pkgdir/usr/bin/$helper"
install -d "$pkgdir/usr/share/omarchy/bin"
ln -s "/usr/bin/$helper" "$pkgdir/usr/share/omarchy/bin/$helper"
done
install -Dm644 default/libalpm/hooks/05-omarchy-passwordless-revoke.hook \
"$pkgdir/usr/share/libalpm/hooks/05-omarchy-passwordless-revoke.hook"
# Branding assets (logos, icons).
install -Dm644 logo.txt "$pkgdir/usr/share/omarchy/logo.txt"
install -Dm644 logo.svg "$pkgdir/usr/share/omarchy/logo.svg"
install -Dm644 icon.txt "$pkgdir/usr/share/omarchy/icon.txt"
install -Dm644 icon.png "$pkgdir/usr/share/omarchy/icon.png"
# Standard icon-theme locations so os-release's LOGO=omarchy resolves in
# desktop/system-info tools that use the freedesktop icon lookup rules.
install -Dm644 icon.png "$pkgdir/usr/share/pixmaps/omarchy.png"
install -Dm644 icon.png "$pkgdir/usr/share/icons/hicolor/256x256/apps/omarchy.png"
# Seed the user-editable branding files into /etc/skel so fresh users
# have working defaults for `omarchy screensaver` and the About screen
# from the moment they're created. omarchy-reinstall-configs refreshes
# these from the /usr/share/omarchy/ sources for existing users.
install -Dm644 logo.txt "$pkgdir/etc/skel/.config/omarchy/branding/screensaver.txt"
install -Dm644 icon.txt "$pkgdir/etc/skel/.config/omarchy/branding/about.txt"
# Other static per-user defaults seeded via /etc/skel for new users.
# omarchy-finalize-user no longer copies these into $HOME; existing users
# resync via omarchy-reinstall-configs.
install -Dm644 default/hypr/toggles/flags.lua \
"$pkgdir/etc/skel/.local/state/omarchy/toggles/hypr/flags.lua"
install -Dm644 default/nautilus-python/extensions/localsend.py \
"$pkgdir/etc/skel/.local/share/nautilus-python/extensions/localsend.py"
install -Dm644 default/nautilus-python/extensions/transcode.py \
"$pkgdir/etc/skel/.local/share/nautilus-python/extensions/transcode.py"
# Tensaku asks for an annotation size on first run unless its persisted
# state already names one; seeding it keeps the first screenshot quiet.
install -Dm644 default/tensaku/state.toml \
"$pkgdir/etc/skel/.local/state/tensaku/state.toml"
# Support binaries needed before the full omarchy package is installed
# (used by ISO/recovery flows).
install -Dm755 bin/omarchy-upload-log "$pkgdir/usr/bin/omarchy-upload-log"
install -Dm755 bin/omarchy-debug "$pkgdir/usr/bin/omarchy-debug"
install -Dm755 bin/omarchy-debug-idle "$pkgdir/usr/bin/omarchy-debug-idle"
}