cua-driver-bin: point the binary's self-updater at pacman

cua-driver update --apply pipes the vendor installer into bash, which
installs a second copy under ~/.cua-driver and links it into ~/.local/bin,
stepping around pacman and the repository's release gate. Upstream offers
no switch for that path, and a /usr/bin wrapper would not cover it either:
the MCP configurations the binary generates record the resolved executable.

prepare() rewrites the installer URL inside the binary, in place and at
equal length, to file:///usr/lib/cua-driver/pm.sh, a stand-in that declines
and names pacman. The build asserts the URL appears exactly twice before
the rewrite and not at all after it, so an upstream change to the updater
stops the build instead of shipping a live self-updater.

Verified in a clean archlinux:base container: pacman -Qkk is clean, the
CLI and cursor-theme helper still run, and on the nightly channel
update --apply prints the notice, exits 1, and creates nothing under
~/.cua-driver/packages or ~/.local/bin.
This commit is contained in:
Spencer Bull committed 2026-09-04 17:23:55 -05:00
1 parent d9127d7124
commit 8ac12ec7d6
2 files changed
+74 -10

No files matched your search

+62 -10
View File
@@ -7,6 +7,15 @@
# /proc/self/exe -- so the whole tree lands under /usr/lib/cua-driver with a
# /usr/bin symlink. .omarchy/upstream.sh rewrites the version and checksums
# below from the release feed.
#
# The binary carries its own updater: `cua-driver update --apply` pipes the
# vendor installer into bash, which would install a second copy under
# ~/.cua-driver and link it into ~/.local/bin, stepping around pacman and
# this repository's release gate. Upstream offers no switch for that path,
# and a /usr/bin wrapper would not cover it either, since the MCP
# configurations the binary generates record the resolved executable. So
# prepare() rewrites the installer URL inside the binary to point at pm.sh,
# a stand-in that declines and names pacman instead.
pkgname=cua-driver-bin
pkgver=0.23.2
@@ -29,23 +38,63 @@ depends=(
)
provides=("cua-driver=${pkgver}")
conflicts=('cua-driver')
# Prebuilt Rust binaries ship byte-exact: their build ids are what upstream
# symbolication matches.
# Prebuilt Rust binaries ship byte-exact apart from the installer rewrite
# below: their build ids are what upstream symbolication matches.
options=('!strip' '!debug')
source=('LICENSE')
source=('LICENSE' 'pm.sh')
source_x86_64=("https://github.com/trycua/cua/releases/download/cua-driver-rs-v${pkgver}/cua-driver-rs-${pkgver}-linux-x86_64.tar.gz")
source_aarch64=("https://github.com/trycua/cua/releases/download/cua-driver-rs-v${pkgver}/cua-driver-rs-${pkgver}-linux-arm64.tar.gz")
sha256sums=('c0779290c1d4783169aa3dbfb55feb505e563ef8a004bbf55298ceffcfbda8d9')
sha256sums=('c0779290c1d4783169aa3dbfb55feb505e563ef8a004bbf55298ceffcfbda8d9'
'c76e251c3ed424200eac52bec35ba534336307fabd83a175ab0b47e2084ab0d8')
sha256sums_x86_64=('478e010d2b0426de9d8a07eb839802daa92137b33cb8affb93b991e91d76ce7e')
sha256sums_aarch64=('3ad2d6c7ca7356a08e534baa2f4ca84ad02cebb2d27caef66cb268b6df71210d')
case "${CARCH}" in
x86_64) _platform="linux-x86_64" ;;
aarch64) _platform="linux-arm64" ;;
esac
_vendor_tree="cua-driver-rs-${pkgver}-${_platform}"
# Rust strings carry their length out of band, so the replacement has to be
# exactly as long as the original: 32 bytes, which is what fixes the
# stand-in's short name and location.
_vendor_installer='https://cua.ai/driver/install.sh'
_pacman_installer='file:///usr/lib/cua-driver/pm.sh'
prepare() {
cd "${srcdir}/${_vendor_tree}"
if (( ${#_vendor_installer} != ${#_pacman_installer} )); then
echo "installer URLs must be the same length to rewrite in place" >&2
return 1
fi
# The URL appears twice: once in the updater and once in the printed
# reinstall one-liner. Any other count means upstream moved the updater
# and this rewrite needs another look, so the build stops rather than
# shipping a live self-updater.
local found
found=$(grep -obUaF "${_vendor_installer}" cua-driver | wc -l)
if (( found != 2 )); then
echo "expected the vendor installer URL twice in cua-driver, found ${found}" >&2
return 1
fi
local size_before size_after
size_before=$(stat -c %s cua-driver)
sed -i "s|${_vendor_installer//./\\.}|${_pacman_installer}|g" cua-driver
size_after=$(stat -c %s cua-driver)
if (( size_before != size_after )) \
|| grep -qUaF "${_vendor_installer}" cua-driver \
|| (( $(grep -obUaF "${_pacman_installer}" cua-driver | wc -l) != 2 )); then
echo "installer URL rewrite did not land cleanly in cua-driver" >&2
return 1
fi
}
package() {
local platform
case "${CARCH}" in
x86_64) platform="linux-x86_64" ;;
aarch64) platform="linux-arm64" ;;
esac
cd "${srcdir}/cua-driver-rs-${pkgver}-${platform}"
cd "${srcdir}/${_vendor_tree}"
# The vendor tree stays together: cua-driver execs cua-cursor-theme as a
# sibling of the resolved binary, and the SDK library, node runtime, ABI
@@ -54,6 +103,9 @@ package() {
cp -a . "${pkgdir}/usr/lib/cua-driver/"
chmod -R a+rX "${pkgdir}/usr/lib/cua-driver"
# The path prepare() wrote into the binary.
install -Dm755 "${srcdir}/pm.sh" "${pkgdir}/usr/lib/cua-driver/pm.sh"
install -d "${pkgdir}/usr/bin"
ln -s ../lib/cua-driver/cua-driver "${pkgdir}/usr/bin/cua-driver"
+12
View File
@@ -0,0 +1,12 @@
#!/bin/bash
# Stands in for the vendor installer. cua-driver-bin points the binary's
# `update --apply` here instead of https://cua.ai/driver/install.sh, which
# would otherwise install a second copy under ~/.cua-driver and link it into
# ~/.local/bin, stepping around pacman and the repository's release gate. The
# exit status is what `cua-driver update --apply` reports.
{
echo "cua-driver is installed by pacman (cua-driver-bin), so the vendor installer is disabled."
echo "Upgrade it with pacman instead:"
echo " sudo pacman -Syu cua-driver-bin"
} >&2
exit 1