Drop our --region build, prepare-region.sh, region skel, the preselected China timezone, the explicit region in the configurator's JSON, Rime bundling and its pin.
413 lines
20 KiB
Bash
Executable File
413 lines
20 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
set -e
|
|
|
|
OMARCHY_ISO_REF="${OMARCHY_ISO_REF:-quattro}"
|
|
OMARCHY_MIRROR="${OMARCHY_MIRROR:-stable}"
|
|
|
|
# Edge, dev, and local-source ISOs install the dev packages explicitly. Those
|
|
# package recipes track the quattro branch. This avoids relying on pacman's
|
|
# provides=omarchy resolution and shows the real package names being tested in
|
|
# the offline mirror and target install. Every other ref, the default quattro
|
|
# build included, installs the published omarchy packages.
|
|
case "$OMARCHY_ISO_REF" in
|
|
edge|dev|local)
|
|
: "${OMARCHY_RUNTIME_PACKAGE:=omarchy-dev}"
|
|
: "${OMARCHY_SETTINGS_PACKAGE:=omarchy-settings-dev}"
|
|
;;
|
|
*)
|
|
: "${OMARCHY_RUNTIME_PACKAGE:=omarchy}"
|
|
: "${OMARCHY_SETTINGS_PACKAGE:=omarchy-settings}"
|
|
;;
|
|
esac
|
|
: "${OMARCHY_NVIM_PACKAGE:=omarchy-nvim}"
|
|
export OMARCHY_RUNTIME_PACKAGE OMARCHY_SETTINGS_PACKAGE OMARCHY_NVIM_PACKAGE
|
|
|
|
# Packages installed into the Arch container used to build the ISO.
|
|
pacman-key --init
|
|
pacman --noconfirm -Sy archlinux-keyring
|
|
# Full upgrade, not just -Sy: docker never re-pulls :latest once it's cached,
|
|
# so this container can be months behind the mirror it installs from. A plain
|
|
# -Sy install is then a partial upgrade — new packages linked against a glibc
|
|
# the container doesn't have yet.
|
|
pacman --noconfirm -Syu archiso git sudo base-devel jq grub imagemagick neovim nodejs npm tree-sitter-cli
|
|
|
|
# Pre-import the omarchy signing key (so pacman trusts our [omarchy] repo
|
|
# during the build without keyserver lookups).
|
|
pacman-key --add /builder/omarchy.gpg
|
|
pacman-key --lsign-key 40DFB630FF42BCFFB047046CF0134EE680CAC571
|
|
|
|
# omarchy-keyring is needed inside the offline mirror too.
|
|
pacman --config /configs/pacman-online-${OMARCHY_MIRROR}.conf --noconfirm -Sy omarchy-keyring
|
|
pacman-key --populate omarchy
|
|
|
|
# Put OPR first in the container too so makepkg resolves the same overrides
|
|
# as the online installer configuration.
|
|
if ! grep -q '^\[omarchy\]' /etc/pacman.conf; then
|
|
opr_section=$(awk '/^\[omarchy\]/,/^$/' /configs/pacman-online-${OMARCHY_MIRROR}.conf)
|
|
awk -v opr="$opr_section" '/^\[core\]/ { print opr; print "" } { print }' \
|
|
/etc/pacman.conf >/tmp/pacman-opr-first.conf
|
|
install -m 644 /tmp/pacman-opr-first.conf /etc/pacman.conf
|
|
rm -f /tmp/pacman-opr-first.conf
|
|
fi
|
|
|
|
# Build locations
|
|
build_cache_dir=/var/cache
|
|
offline_mirror_dir="$build_cache_dir/airootfs/var/cache/omarchy/mirror/offline"
|
|
mkdir -p "$build_cache_dir" "$offline_mirror_dir"
|
|
|
|
# Seed from the official Arch releng profile.
|
|
cp -r /archiso/configs/releng/* "$build_cache_dir/"
|
|
rm "$build_cache_dir/airootfs/etc/motd"
|
|
|
|
# We rely on the global CDN; drop reflector.
|
|
rm -rf "$build_cache_dir/airootfs/etc/systemd/system/multi-user.target.wants/reflector.service"
|
|
rm -rf "$build_cache_dir/airootfs/etc/systemd/system/reflector.service.d"
|
|
rm -rf "$build_cache_dir/airootfs/etc/xdg/reflector"
|
|
|
|
# Bring in our archiso profile additions.
|
|
cp -r /configs/* "$build_cache_dir/"
|
|
mkdir -p "$build_cache_dir/airootfs/usr/share/omarchy-iso"
|
|
echo "$OMARCHY_MIRROR" > "$build_cache_dir/airootfs/root/omarchy_mirror"
|
|
echo "$OMARCHY_ISO_REF" > "$build_cache_dir/airootfs/root/omarchy_iso_ref"
|
|
cat > "$build_cache_dir/airootfs/usr/share/omarchy-iso/package-targets" <<EOF
|
|
OMARCHY_RUNTIME_PACKAGE=$OMARCHY_RUNTIME_PACKAGE
|
|
OMARCHY_SETTINGS_PACKAGE=$OMARCHY_SETTINGS_PACKAGE
|
|
OMARCHY_NVIM_PACKAGE=$OMARCHY_NVIM_PACKAGE
|
|
EOF
|
|
|
|
if [[ ${OMARCHY_INSTALL_DEBUG:-} == "1" ]]; then
|
|
touch "$build_cache_dir/airootfs/usr/share/omarchy-iso/install-debug"
|
|
{
|
|
echo "debug=1"
|
|
echo "built_at=$(date -Is)"
|
|
echo "ref=$OMARCHY_ISO_REF"
|
|
echo "mirror=$OMARCHY_MIRROR"
|
|
echo "runtime_package=$OMARCHY_RUNTIME_PACKAGE"
|
|
echo "settings_package=$OMARCHY_SETTINGS_PACKAGE"
|
|
echo "nvim_package=$OMARCHY_NVIM_PACKAGE"
|
|
if [[ -d /omarchy-source ]]; then
|
|
echo "omarchy_source=/omarchy-source"
|
|
git -c safe.directory=/omarchy-source -C /omarchy-source rev-parse HEAD 2>/dev/null | sed 's/^/omarchy_commit=/' || true
|
|
git -c safe.directory=/omarchy-source -C /omarchy-source status --short 2>/dev/null | sed 's/^/omarchy_status=/' || true
|
|
fi
|
|
if [[ -d /omarchy-pkgs ]]; then
|
|
echo "omarchy_pkgs_source=/omarchy-pkgs"
|
|
git -c safe.directory=/omarchy-pkgs -C /omarchy-pkgs rev-parse HEAD 2>/dev/null | sed 's/^/omarchy_pkgs_commit=/' || true
|
|
git -c safe.directory=/omarchy-pkgs -C /omarchy-pkgs status --short 2>/dev/null | sed 's/^/omarchy_pkgs_status=/' || true
|
|
fi
|
|
} > "$build_cache_dir/airootfs/usr/share/omarchy-iso/build-info"
|
|
fi
|
|
|
|
# When --local-source is in effect, build omarchy* from the mounted source
|
|
# trees and drop them in the offline mirror. Otherwise pacman -Syw below
|
|
# downloads the published versions from the omarchy network mirror.
|
|
if [[ -d /omarchy-source && -d /omarchy-pkgs ]]; then
|
|
bash /builder/build-omarchy-packages.sh "$offline_mirror_dir"
|
|
LOCAL_OMARCHY_BUILD=1
|
|
# Published builds of these lack the local changes, so the target pins them.
|
|
printf '%s\n' "$OMARCHY_RUNTIME_PACKAGE" "$OMARCHY_SETTINGS_PACKAGE" \
|
|
> "$build_cache_dir/airootfs/usr/share/omarchy-iso/pinned-packages"
|
|
fi
|
|
|
|
# Node.js binary for offline mise install.
|
|
NODE_DIST_URL="https://nodejs.org/dist/latest"
|
|
NODE_SHASUMS=$(curl -fsSL "$NODE_DIST_URL/SHASUMS256.txt")
|
|
NODE_FILENAME=$(echo "$NODE_SHASUMS" | grep "linux-x64.tar.gz" | awk '{print $2}')
|
|
NODE_SHA=$(echo "$NODE_SHASUMS" | grep "linux-x64.tar.gz" | awk '{print $1}')
|
|
curl -fsSL "$NODE_DIST_URL/$NODE_FILENAME" -o "/tmp/$NODE_FILENAME"
|
|
echo "$NODE_SHA /tmp/$NODE_FILENAME" | sha256sum -c -
|
|
mkdir -p "$build_cache_dir/airootfs/opt/packages/"
|
|
cp "/tmp/$NODE_FILENAME" "$build_cache_dir/airootfs/opt/packages/"
|
|
|
|
# Packages installed into the live ISO environment itself (NOT the target system).
|
|
# The selected omarchy-settings package is needed here so its post_install hook
|
|
# drops Omarchy's plymouthd.conf into /etc/plymouth before mkarchiso builds the
|
|
# live initramfs.
|
|
# cage, foot and the two fonts give China installs a console that draws Chinese.
|
|
arch_packages=(linux-t2 git gum jq openssl plymouth ttfx tzupdate omarchy-keyring "$OMARCHY_SETTINGS_PACKAGE" lvm2 cryptsetup parted cage foot ttf-jetbrains-mono wqy-microhei)
|
|
printf '%s\n' "${arch_packages[@]}" >> "$build_cache_dir/packages.x86_64"
|
|
|
|
# The live ISO boots linux-t2 (see airootfs/etc/mkinitcpio.d/linux-t2.preset), so
|
|
# stock linux is a second kernel nobody boots: ~147MB of ISO, plus its own archiso
|
|
# initramfs, copied into both the ISO tree and the size-constrained FAT EFI image.
|
|
#
|
|
# It cannot just be deleted — releng's broadcom-wl hard-depends on it, and it is
|
|
# the only releng package that does, so pacman would drag the kernel straight back
|
|
# in. broadcom-wl is a prebuilt module for stock linux and cannot load on the
|
|
# kernel we boot, so it has done nothing since we started booting T2 anyway. The
|
|
# install is entirely offline and the live environment needs no Wi-Fi driver.
|
|
#
|
|
# Anchored so linux-t2 and linux-firmware are untouched.
|
|
sed -i -E '/^(linux|broadcom-wl)$/d' "$build_cache_dir/packages.x86_64"
|
|
|
|
# Build the offline mirror: everything pacstrap might want during the target
|
|
# install. With --local-source, the omarchy* packages we just built are
|
|
# already in the mirror and we filter them out below. Without it, pacman -Syw
|
|
# pulls the published omarchy* from the network mirror like any other package.
|
|
if [[ -d /omarchy-source ]]; then
|
|
regions_source=/omarchy-source/default/regions
|
|
base_pkg_lists=(/omarchy-source/install/omarchy-base.packages /omarchy-source/install/omarchy-other.packages)
|
|
setup_form=/omarchy-source/install/provisioning/setup-form.sh
|
|
else
|
|
# Pull the same package lists out of the freshly-downloaded Omarchy runtime
|
|
# package so we don't need a local checkout in the non-local-source path.
|
|
bootstrap_cache_dir=/tmp/omarchy-pkg-bootstrap
|
|
rm -rf "$bootstrap_cache_dir" /tmp/offlinedb-bootstrap /tmp/omarchy-pkglists
|
|
mkdir -p "$bootstrap_cache_dir" /tmp/offlinedb-bootstrap
|
|
pacman --config /configs/pacman-online-${OMARCHY_MIRROR}.conf --noconfirm -Syw "$OMARCHY_RUNTIME_PACKAGE" --cachedir "$bootstrap_cache_dir" --dbpath /tmp/offlinedb-bootstrap >/dev/null
|
|
omarchy_pkg=$(find "$bootstrap_cache_dir" -maxdepth 1 -type f -name "$OMARCHY_RUNTIME_PACKAGE-*.pkg.tar.zst" | sort | head -1)
|
|
if [[ -z $omarchy_pkg ]]; then
|
|
echo "ERROR: downloaded package for $OMARCHY_RUNTIME_PACKAGE not found in $bootstrap_cache_dir" >&2
|
|
exit 1
|
|
fi
|
|
mkdir -p /tmp/omarchy-pkglists
|
|
bsdtar -xf "$omarchy_pkg" -C /tmp/omarchy-pkglists usr/share/omarchy/install/omarchy-base.packages usr/share/omarchy/install/omarchy-other.packages
|
|
base_pkg_lists=(/tmp/omarchy-pkglists/usr/share/omarchy/install/omarchy-base.packages /tmp/omarchy-pkglists/usr/share/omarchy/install/omarchy-other.packages)
|
|
# Extracted on its own, tolerating a miss: bsdtar exits non-zero for a member
|
|
# it can't find, so asking for this alongside the package lists would abort the
|
|
# build here (set -e) with a bare "Not found in archive" instead of the
|
|
# actionable error below.
|
|
bsdtar -xf "$omarchy_pkg" -C /tmp/omarchy-pkglists usr/share/omarchy/install/provisioning/setup-form.sh 2>/dev/null || true
|
|
# Region profiles live under default/, which the settings package ships,
|
|
# not the runtime. Its own cache dir keeps the runtime lookup above from
|
|
# ever matching it.
|
|
settings_cache_dir="$bootstrap_cache_dir/settings"
|
|
mkdir -p "$settings_cache_dir"
|
|
pacman --config /configs/pacman-online-${OMARCHY_MIRROR}.conf --noconfirm -Syw "$OMARCHY_SETTINGS_PACKAGE" --cachedir "$settings_cache_dir" --dbpath /tmp/offlinedb-bootstrap >/dev/null
|
|
regions_source=$(find "$settings_cache_dir" -maxdepth 1 -type f -name "$OMARCHY_SETTINGS_PACKAGE-*.pkg.tar.zst" | sort | head -1)
|
|
if [[ -z $regions_source ]]; then
|
|
echo "ERROR: downloaded package for $OMARCHY_SETTINGS_PACKAGE not found in $settings_cache_dir" >&2
|
|
exit 1
|
|
fi
|
|
setup_form=/tmp/omarchy-pkglists/usr/share/omarchy/install/provisioning/setup-form.sh
|
|
fi
|
|
|
|
mkdir -p "$build_cache_dir/airootfs/usr/share/omarchy-iso"
|
|
cp "${base_pkg_lists[0]}" "$build_cache_dir/airootfs/usr/share/omarchy-iso/omarchy-base.packages"
|
|
cp "${base_pkg_lists[1]}" "$build_cache_dir/airootfs/usr/share/omarchy-iso/omarchy-other.packages"
|
|
|
|
# The configurator's setup form comes from the runtime this ISO bundles, so the
|
|
# installer and the first-boot setup that finishes a deferred install can never
|
|
# disagree. A runtime predating the split ships no such file, which would leave
|
|
# the configurator with no prompts at all.
|
|
if [[ ! -f $setup_form ]]; then
|
|
if [[ -d /omarchy-source ]]; then
|
|
echo "ERROR: the --local-source checkout ships no install/provisioning/setup-form.sh" >&2
|
|
remedy="Update the checkout to a revision carrying the shared setup form."
|
|
else
|
|
echo "ERROR: $OMARCHY_RUNTIME_PACKAGE does not ship install/provisioning/setup-form.sh" >&2
|
|
remedy="Publish a runtime carrying the shared setup form, or build with --local-source against a checkout that has it."
|
|
fi
|
|
echo " The configurator sources its prompts from that file, so this ISO" >&2
|
|
echo " would boot into an installer with no questions to ask." >&2
|
|
echo " $remedy" >&2
|
|
exit 1
|
|
fi
|
|
cp "$setup_form" "$build_cache_dir/airootfs/usr/share/omarchy-iso/setup-form.sh"
|
|
|
|
# Every region's packages ride in the offline mirror, and its community
|
|
# repositories join a writable copy of the online config to download them.
|
|
online_config=/tmp/omarchy-pacman-online.conf
|
|
cp "/configs/pacman-online-${OMARCHY_MIRROR}.conf" "$online_config"
|
|
bash /builder/prepare-regions.sh "$regions_source" \
|
|
"$build_cache_dir/airootfs/usr/share/omarchy-iso" "$online_config"
|
|
|
|
# Profiles ship in the settings package, but the finalizer that applies them
|
|
# ships in the runtime. A runtime without it would ignore the region marker,
|
|
# leaving regional targets with the keyring but none of the repositories.
|
|
if [[ -n ${omarchy_pkg:-} && -d $build_cache_dir/airootfs/usr/share/omarchy-iso/regions ]]; then
|
|
runtime_listing=$(bsdtar -tf "$omarchy_pkg")
|
|
if ! grep -qx 'usr/bin/omarchy-apply-pacman' <<<"$runtime_listing"; then
|
|
echo "ERROR: $OMARCHY_SETTINGS_PACKAGE ships region profiles, but $OMARCHY_RUNTIME_PACKAGE lacks omarchy-apply-pacman to apply them." >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
# Collect every package we want available in the offline mirror.
|
|
declare -a all_packages
|
|
mapfile -t all_packages < <(
|
|
{
|
|
cat "$build_cache_dir/packages.x86_64"
|
|
grep -hv '^#\|^$' "${base_pkg_lists[@]}"
|
|
grep -hv '^#\|^$' /builder/archinstall.packages
|
|
# Downloaded but not installed: the installer adds a region's packages
|
|
# only to targets in that region.
|
|
grep -hsv '^#\|^$' "$build_cache_dir"/airootfs/usr/share/omarchy-iso/regions/*/packages || true
|
|
# Always include the selected Omarchy packages so the target install can
|
|
# find the runtime and companion packages in the offline mirror.
|
|
printf '%s\n' "$OMARCHY_RUNTIME_PACKAGE" "$OMARCHY_SETTINGS_PACKAGE" "$OMARCHY_NVIM_PACKAGE"
|
|
} | sort -u
|
|
)
|
|
|
|
# Arch dropped the prebuilt broadcom-wl on 2026-09-02 and rebuilt broadcom-wl-dkms
|
|
# with replaces=(broadcom-wl). A replaces entry only helps upgrades of an already
|
|
# installed package; as an explicit pacman target the old name now fails with
|
|
# "target not found". Published Omarchy runtime packages that predate the rename
|
|
# still list it in omarchy-other.packages, so map it here until every channel
|
|
# ships a runtime that names broadcom-wl-dkms itself.
|
|
# arch-mact2 dropped apple-bcm-firmware on 2026-09-16 in favour of
|
|
# apple-bcm-firmware-fetcher, which does the same job (pull the T2 Wi-Fi and
|
|
# Bluetooth firmware off the macOS volume) but only conflicts with the old name
|
|
# rather than replacing it, so pacman cannot follow the rename on its own.
|
|
mapfile -t all_packages < <(
|
|
printf '%s\n' "${all_packages[@]}" |
|
|
sed -e 's/^broadcom-wl$/broadcom-wl-dkms/' \
|
|
-e 's/^apple-bcm-firmware$/apple-bcm-firmware-fetcher/' |
|
|
sort -u
|
|
)
|
|
|
|
# With --local-source we already built these omarchy* packages directly into
|
|
# the mirror; strip them from the pacman -Syw list so it doesn't try to fetch
|
|
# the published versions on top.
|
|
if [[ -n ${LOCAL_OMARCHY_BUILD:-} ]]; then
|
|
mapfile -t all_packages < <(
|
|
printf '%s\n' "${all_packages[@]}" |
|
|
grep -Fxv \
|
|
-e "$OMARCHY_RUNTIME_PACKAGE" \
|
|
-e "$OMARCHY_SETTINGS_PACKAGE" \
|
|
-e "$OMARCHY_NVIM_PACKAGE" || true
|
|
)
|
|
fi
|
|
|
|
mkdir -p /tmp/offlinedb
|
|
download_offline_packages() {
|
|
pacman --config "$online_config" --noconfirm -Syw \
|
|
"${all_packages[@]}" --cachedir "$offline_mirror_dir/" --dbpath /tmp/offlinedb --needed
|
|
}
|
|
|
|
# A repository may occasionally republish a package without changing its
|
|
# filename. Pacman detects that the persistent cached copy no longer matches
|
|
# the refreshed repository checksum and deletes it, but still fails the
|
|
# transaction. Retry once so the now-missing package is downloaded.
|
|
if ! download_offline_packages; then
|
|
echo "Offline package download failed; retrying after pacman cleaned invalid cached files..." >&2
|
|
download_offline_packages
|
|
fi
|
|
|
|
# Resolve the exact filenames chosen by the same synced package databases used
|
|
# for the download. Pruning by this transaction (rather than merely keeping the
|
|
# newest version of every cached package name) removes packages that have left
|
|
# the lists or dependency closure, such as an old Electron major version.
|
|
if ! resolved_package_files="$(
|
|
pacman --config "$online_config" --noconfirm \
|
|
--dbpath /tmp/offlinedb -S --print --print-format '%f' "${all_packages[@]}"
|
|
)"; then
|
|
echo "ERROR: could not resolve the package files required by the offline mirror" >&2
|
|
exit 1
|
|
fi
|
|
mapfile -t required_package_files <<< "$resolved_package_files"
|
|
|
|
# The online transaction intentionally excludes packages built from the local
|
|
# checkouts. Add those exact artifacts back to the keep-set after verifying
|
|
# that the local build left exactly one file for each selected package name.
|
|
if [[ -n ${LOCAL_OMARCHY_BUILD:-} ]]; then
|
|
for local_package_name in \
|
|
"$OMARCHY_RUNTIME_PACKAGE" "$OMARCHY_SETTINGS_PACKAGE" "$OMARCHY_NVIM_PACKAGE"; do
|
|
local_package_file=""
|
|
for candidate in "$offline_mirror_dir/$local_package_name-"*.pkg.tar.*; do
|
|
[[ -f $candidate && $candidate != *.sig ]] || continue
|
|
read -r candidate_name _ < <(pacman -Qp "$candidate" 2>/dev/null) || continue
|
|
[[ $candidate_name == "$local_package_name" ]] || continue
|
|
if [[ -n $local_package_file ]]; then
|
|
echo "ERROR: multiple local builds found for $local_package_name" >&2
|
|
exit 1
|
|
fi
|
|
local_package_file="${candidate##*/}"
|
|
done
|
|
if [[ -z $local_package_file ]]; then
|
|
echo "ERROR: local build not found for $local_package_name" >&2
|
|
exit 1
|
|
fi
|
|
required_package_files+=("$local_package_file")
|
|
done
|
|
fi
|
|
|
|
printf '%s\n' "${required_package_files[@]}" |
|
|
bash /builder/prune-offline-mirror.sh "$offline_mirror_dir"
|
|
|
|
# Rebuild the offline repo db from scratch so size/checksum/depends entries
|
|
# always reflect only the package files selected for this build.
|
|
rm -f "$offline_mirror_dir"/offline.db* "$offline_mirror_dir"/offline.files*
|
|
repo-add "$offline_mirror_dir/offline.db.tar.gz" "$offline_mirror_dir/"*.pkg.tar.zst
|
|
|
|
# mkarchiso expects the mirror at /var/cache/omarchy/mirror/offline inside the
|
|
# container (the airootfs path); symlink rather than duplicate.
|
|
mkdir -p /var/cache/omarchy/mirror
|
|
ln -sf "$offline_mirror_dir" /var/cache/omarchy/mirror/offline
|
|
|
|
# Denominator for the install dashboard's progress bar. Resolving the mirror's
|
|
# own package lists against the mirror we just indexed, with an empty local db,
|
|
# is the question pacstrap asks at install time — same resolver, same repo, same
|
|
# lists — so no hand-kept constant can drift.
|
|
#
|
|
# It over-counts by ~1 in 925: archinstall.packages lists both amd-ucode and
|
|
# intel-ucode because the mirror must contain either. phases.py records expected
|
|
# and actual in the timing JSON, so growing drift shows up in acceptance runs.
|
|
# The early-bootstrap set is already inside this closure, so restating it would
|
|
# only add a second list to drift.
|
|
resolve_expected_packages() {
|
|
local resolve_root=/tmp/omarchy-expected-packages
|
|
local resolved
|
|
local -a targets
|
|
|
|
rm -rf "$resolve_root"
|
|
mkdir -p "$resolve_root/var/lib/pacman"
|
|
|
|
mapfile -t targets < <(
|
|
{
|
|
grep -hv '^#\|^$' /builder/archinstall.packages
|
|
# Read the shipped copy, which is what _runtime_package_list reads at
|
|
# install time, not the build-time source it came from.
|
|
grep -hv '^#\|^$' \
|
|
"$build_cache_dir/airootfs/usr/share/omarchy-iso/omarchy-base.packages"
|
|
printf '%s\n' "$OMARCHY_RUNTIME_PACKAGE" "$OMARCHY_SETTINGS_PACKAGE" \
|
|
"$OMARCHY_NVIM_PACKAGE"
|
|
} | sort -u
|
|
)
|
|
|
|
pacman --config "$build_cache_dir/pacman-offline.conf" \
|
|
--root "$resolve_root" --dbpath "$resolve_root/var/lib/pacman" \
|
|
--noconfirm -Sy >/dev/null || return 1
|
|
|
|
# Capture before counting: no pipefail here, so a pacman failure inside a
|
|
# pipeline would become a plausible partial count, which never trips the
|
|
# dashboard's fallback.
|
|
resolved="$(pacman --config "$build_cache_dir/pacman-offline.conf" \
|
|
--root "$resolve_root" --dbpath "$resolve_root/var/lib/pacman" \
|
|
--noconfirm -S --print --print-format '%n' "${targets[@]}")" || return 1
|
|
|
|
printf '%s\n' "$resolved" | sort -u | grep -c .
|
|
}
|
|
|
|
# Worth failing the build over: -S --print only aborts when a target is missing
|
|
# from the offline repo, which would fail pacstrap the same way. A count that
|
|
# merely looks wrong is not — the dashboard falls back without the file.
|
|
if ! expected_packages="$(resolve_expected_packages)"; then
|
|
echo "ERROR: could not resolve the target package count from the offline mirror." >&2
|
|
echo " pacman -S --print aborts the whole transaction if any single target" >&2
|
|
echo " is missing, so this almost certainly means pacstrap would fail the" >&2
|
|
echo " same way at install time." >&2
|
|
exit 1
|
|
fi
|
|
if (( expected_packages < 600 || expected_packages > 2000 )); then
|
|
echo "WARNING: resolved target package count $expected_packages is outside the" >&2
|
|
echo " expected 600-2000 range; shipping no denominator so the install" >&2
|
|
echo " dashboard falls back to its time-based curve." >&2
|
|
else
|
|
printf '%s\n' "$expected_packages" \
|
|
>"$build_cache_dir/airootfs/usr/share/omarchy-iso/expected-packages"
|
|
echo "Target install resolves to $expected_packages packages."
|
|
fi
|
|
|
|
# Live ISO uses the same offline pacman.conf.
|
|
cp "$build_cache_dir/pacman-offline.conf" "$build_cache_dir/airootfs/etc/pacman.conf"
|
|
|
|
# Build the ISO.
|
|
mkarchiso -v -w "$build_cache_dir/work/" -o /out/ "$build_cache_dir/"
|
|
|
|
# Match host UID/GID on output.
|
|
if [[ -n $HOST_UID && -n $HOST_GID ]]; then
|
|
chown -R "$HOST_UID:$HOST_GID" /out/
|
|
fi
|