Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions pkgbuilds/cua-hyprland-plugin/DOWNSTREAM-PROVENANCE.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"files": {
"CMakeLists.txt": "be5a67cf11bdd3195082e8b4225b1cd9c9bfe7fd66572a6aa5774c654b72f7f1",
"LICENSE.md": "c0779290c1d4783169aa3dbfb55feb505e563ef8a004bbf55298ceffcfbda8d9",
"SOURCE-PROVENANCE.json": "292ac8fa09bec96cbd499d5d57cc8ea9b1c00fe6347162fb6960c45f972bdb9d",
"SOURCE-PROVENANCE.json": "9a7eba9fd642d6697213729311da620fad292cd3f693c8b49b8a07163ef22a1d",
"cmake/DetectHyprlandAPI.cmake": "216133ec0eb141c3696bf3770a23e63e46521c9e91a0245a7cb75c20a75ba2c5",
"cmake/VerifyRuntime.cmake": "5869f79a418e7aa6178d2b9166c36cd01c3093c2579b647624968244db57b761",
"include/cua_hyprland/protocol.hpp": "7051463b3c61a2dc93c388e66b6136b7bb524f8694350f249f9d2b5c55826493",
Expand Down Expand Up @@ -55,6 +55,6 @@
},
"patch_sha256": "87d3f560cfbd195748321a7e7ad2cb921c77cc022877de7890d3a711940f6e3c",
"schema": 1,
"upstream_manifest_sha256": "292ac8fa09bec96cbd499d5d57cc8ea9b1c00fe6347162fb6960c45f972bdb9d",
"upstream_revision": "58aba84b5b83d77e7e2b0f006547699eb594e50d"
"upstream_manifest_sha256": "9a7eba9fd642d6697213729311da620fad292cd3f693c8b49b8a07163ef22a1d",
"upstream_revision": "c82d32e3e1adbc6578a148962002ddf6e3e8a15a"
}
189 changes: 37 additions & 152 deletions pkgbuilds/cua-hyprland-plugin/PKGBUILD
Original file line number Diff line number Diff line change
@@ -1,173 +1,59 @@
# Verified upstream kit plus a separately pinned Omarchy patch.
# Cua's published profile kit, scoped to its ABI packages, plus a separately pinned Omarchy patch.
# Normal reruns need a fresh build directory; makepkg -e reuses verified extracted trees.
# Profile kit: original source bytes and separately committed packaging tooling.
# shellcheck shell=bash disable=SC2034,SC2154
pkgname=cua-hyprland-plugin
pkgver=0.32.0
# Profile validation starts package releases at 2, above upstream's generic -1 build of the same Driver.
pkgver=0.33.2
# Above the kit's own 0.33.2-2 qualification build, which carries neither the patch nor this profile.
pkgrel=3
pkgdesc='Cua input candidate for reviewed profile omarchy-hyprland-0562r4-remaps'
pkgdesc='Cua input candidate for reviewed profile omarchy-edge-20261004-abi'
arch=('x86_64')
url='https://github.com/trycua/cua'
license=('MIT')
depends=('hyprland=0.56.2-4' 'aquamarine=0.15.1-1' 'glibc=2.44+r50+g1848099f063e-1' 'hyprcursor=0.1.13-7' 'hyprgraphics=0.5.1-4' 'hyprlang=0.6.8-5' 'hyprutils=0.14.2-1' 'libgcc=16.2.1+r23+gd564253eb6c8-1' 'libstdc++=16.2.1+r23+gd564253eb6c8-1' 'libxkbcommon=1.13.2-1' 'wayland=1.26.0-1' 'python>=3.11' 'binutils')
makedepends=('cmake>=3.30' 'ninja' 'pkgconf' 'gcc' 'patch')
options=('!strip' '!debug' '!lto')
_stem='cua-hyprland-plugin-0.32.0-58aba84b5b83d77e7e2b0f006547699eb594e50d'
_archive_sha256='25bc3b2d353ba6bb6ecd17e4b67b11b0d6b731a5ae01025197442c97e50acf7a'
_kit_sha256='3c2141dcb2583d918ef2cdb6ff3805dec62119a439a29c811a93cc980d621423'
_profile_sha256='b20d98979137fb5216768d95215f80d372d9bfd2269b541d7bcf664a12f80b97'
_stem='cua-hyprland-plugin-0.33.2-c82d32e3e1adbc6578a148962002ddf6e3e8a15a'
_archive_sha256='79596a9a5e7300546ad4ab0646430edcf3e0c0456a541458de2a52b8c44a8fad'
_kit_sha256='a97fc47ec49600dfd79ba459c05a410b744e0a462b3a0cf59864a7d6fce9601d'
_profile_sha256='fe1b3f51a84962a188e9784116bf5f072ef692715adee71e996a6b95c5482976'
_verifier_sha256='480f649cbd35a0ddc7f49dc0a3a44785402c9e0ec9653b0f8ea4965d52d7f900'
_cxx="${CUA_RELEASE_CXX:-/usr/bin/g++}"
_download_name='cua-hyprland-plugin-0.26.1-cc54254464c0c9aebfd6547fe7e4a0ceaf0456d7-profile-omarchy-stable-20260910-kit-1.1.0-5dacea79a6a5927e59fca7b51e6c04e94fa45133ac1b8fb7f4e1f442d113eb9a-67f89ceb47edd973aa748820eadd02ddbfb3d3e4.tar.gz'
_download_sha256='a89bfa7f6490f598719dfabdd2a5badc137e27b0764fd25e6a05e1f969433520'
source=('https://github.com/trycua/cua/releases/download/cua-hyprland-kit-v1.1.0-omarchy-stable-20260910/cua-hyprland-plugin-0.26.1-cc54254464c0c9aebfd6547fe7e4a0ceaf0456d7-profile-omarchy-stable-20260910-kit-1.1.0-5dacea79a6a5927e59fca7b51e6c04e94fa45133ac1b8fb7f4e1f442d113eb9a-67f89ceb47edd973aa748820eadd02ddbfb3d3e4.tar.gz'
"https://github.com/trycua/cua/releases/download/cua-driver-rs-v${pkgver}/${_stem}.tar.gz"
'PROFILE.json')
noextract=("$_download_name" "${_stem}.tar.gz")
sha256sums=('a89bfa7f6490f598719dfabdd2a5badc137e27b0764fd25e6a05e1f969433520'
'25bc3b2d353ba6bb6ecd17e4b67b11b0d6b731a5ae01025197442c97e50acf7a'
'b20d98979137fb5216768d95215f80d372d9bfd2269b541d7bcf664a12f80b97')
_download_name='cua-hyprland-plugin-0.33.2-c82d32e3e1adbc6578a148962002ddf6e3e8a15a-profile-omarchy-edge-20261004-kit-1.3.0-0ada2c227d0817b0228e9d8127e2363a785c13175a9b74fbebaedc9825d3a4fd-c82d32e3e1adbc6578a148962002ddf6e3e8a15a.tar.gz'
_download_sha256='ac560bba4bc656004564fd9cc09daea1206402148825ca7d7ac27ccdd56345b1'
source=("https://github.com/trycua/cua/releases/download/cua-hyprland-kit-v1.3.0-omarchy-edge-20261004/${_download_name}")
noextract=("$_download_name")
sha256sums=("$_download_sha256")

# Downstream inputs are also checked explicitly when makepkg integrity is skipped.
declare -gA _downstream_sha256=(
# Local inputs are also checked explicitly when makepkg integrity is skipped.
declare -gA _local_sha256=(
['PROFILE.json']='fe1b3f51a84962a188e9784116bf5f072ef692715adee71e996a6b95c5482976'
['kit.py']='f9d0fbcff1ffe62883b927bd3d5522822c8d1682330f57991485ad247326aac2'
['kit_test.py']='ab90cc54ee0c1b54129d52c165427de12292c5f14c7b0f21e9bb0a6438307fbd'
['downstream.patch']='87d3f560cfbd195748321a7e7ad2cb921c77cc022877de7890d3a711940f6e3c'
['DOWNSTREAM-PROVENANCE.json']='814e136f4684886107b5ccfa7ffc773a1ad0cea7dcddebd977c6f35c6e87ce00'
['DOWNSTREAM-PROVENANCE.json']='e743455ab81598f8db278d17d556414d6cc1457a2533b2918236ee360564b974'
['downstream.py']='7c9725805ad038737bd4d346c85f27991ce9ddfff436a32ebf515cad1bf98ca1'
['downstream_test.py']='7b9a992979b22a5e061fdf011ac6be59a3f1ae6e0d7c0a8ff631f74e71984c5a'
)
source+=('downstream.patch' 'DOWNSTREAM-PROVENANCE.json' 'downstream.py' 'downstream_test.py')
sha256sums+=('87d3f560cfbd195748321a7e7ad2cb921c77cc022877de7890d3a711940f6e3c' '814e136f4684886107b5ccfa7ffc773a1ad0cea7dcddebd977c6f35c6e87ce00' '7c9725805ad038737bd4d346c85f27991ce9ddfff436a32ebf515cad1bf98ca1' '7b9a992979b22a5e061fdf011ac6be59a3f1ae6e0d7c0a8ff631f74e71984c5a')
source+=('PROFILE.json' 'kit.py' 'kit_test.py' 'downstream.patch' 'DOWNSTREAM-PROVENANCE.json' 'downstream.py' 'downstream_test.py')
sha256sums+=('fe1b3f51a84962a188e9784116bf5f072ef692715adee71e996a6b95c5482976' 'f9d0fbcff1ffe62883b927bd3d5522822c8d1682330f57991485ad247326aac2' 'ab90cc54ee0c1b54129d52c165427de12292c5f14c7b0f21e9bb0a6438307fbd' '87d3f560cfbd195748321a7e7ad2cb921c77cc022877de7890d3a711940f6e3c' 'e743455ab81598f8db278d17d556414d6cc1457a2533b2918236ee360564b974' '7c9725805ad038737bd4d346c85f27991ce9ddfff436a32ebf515cad1bf98ca1' '7b9a992979b22a5e061fdf011ac6be59a3f1ae6e0d7c0a8ff631f74e71984c5a')

_verify_download() {
python3 -I - "$SRCDEST/$_download_name" "$_download_sha256" "$srcdir" "$1" "$SRCDEST/PROFILE.json" \
"$SRCDEST/${_stem}.tar.gz" <<'CUA_DOWNLOAD_PY'
import hashlib
import io
import json
from pathlib import Path, PurePosixPath
import sys
import tarfile

expected = {'KIT-PROVENANCE.json': '7beb736adfd334eed52e84070177634269e3a09f8bb25971b38606933ff4c997', 'PKGBUILD': 'b945a6a6eda13d0e382770edd5419485e3196041956663eb38f5183b05d30db3', 'PROFILE-PKGBUILD.in': 'c350d1b2375946cb0166893d67a1fc01344ee5e3215bbe801b4d54bb361d6bce', 'PROFILE-USAGE.md': 'c14d8e8103fccab59e558758f4249f86bce700a8723cd4ba1b97b1102e02bbd2', 'PROFILE.json': '5dacea79a6a5927e59fca7b51e6c04e94fa45133ac1b8fb7f4e1f442d113eb9a', 'SHA256SUMS': '34a2126bcfab983f171382aafac3ef218475b652f4583c58f4a04088044cb935', 'SOURCE-PROVENANCE.json': '54f514664c84e1358a435f29cd6befd5661b0b133d76997191c000b10f021a75', 'cua-hyprland-plugin-0.26.1-cc54254464c0c9aebfd6547fe7e4a0ceaf0456d7.tar.gz': '47bca9e018f32f4fcfe683f91c7475c60368f3b65d318cc35c1f2de88a4ee9ab', 'lifecycle.py': 'b18dceb8b8e05b93586ddd3a2f1d90d70ae1c36088e54fc05c89e08585290990', 'profile_bundle.py': 'ac883883814787da477c037f017939ee92c9fb5f46f373af7de1331b24f1f6da', 'profile_verify.py': '480f649cbd35a0ddc7f49dc0a3a44785402c9e0ec9653b0f8ea4965d52d7f900'}
kit_stem = 'cua-hyprland-plugin-0.26.1-cc54254464c0c9aebfd6547fe7e4a0ceaf0456d7'
stem = 'cua-hyprland-plugin-0.32.0-58aba84b5b83d77e7e2b0f006547699eb594e50d'

def require(condition, message):
if not condition:
raise SystemExit(message)

def digest(data):
return hashlib.sha256(data).hexdigest()
_inputs() {
local name
printf '%s %s\n' "$_download_sha256" "$SRCDEST/$_download_name" | sha256sum -c - || return 1
for name in "${!_local_sha256[@]}"; do
printf '%s %s\n' "${_local_sha256[$name]}" "$SRCDEST/$name" | sha256sum -c - || return 1
done
}

archive, checksum, srcdir, mode, profile_path, source_path = sys.argv[1:]
archive, srcdir = Path(archive), Path(srcdir)
require(mode in {'check', 'extract'}, 'invalid kit verification mode')
require(archive.is_file() and not archive.is_symlink(), 'outer archive must be a regular file')
data = archive.read_bytes()
require(digest(data) == checksum, 'outer archive checksum mismatch')
payload = {}
with tarfile.open(fileobj=io.BytesIO(data), mode='r:gz') as contents:
for member in contents:
require(member.isfile() and not member.issparse() and not member.pax_headers,
'nonregular outer kit member')
require(member.name in expected and member.name not in payload, 'outer kit inventory mismatch')
content = contents.extractfile(member).read()
require(digest(content) == expected[member.name], 'outer kit member checksum mismatch')
payload[member.name] = content
require(payload.keys() == expected.keys(), 'outer kit inventory mismatch')
# Rebase the kit onto the Driver 0.32.0 source release, whose manifest has the fields
# this verifier checks, and derive the reviewed Omarchy edge profile for it.
# Tooling, compiler and runtime hashes stay upstream's. The compositor and its
# headers are re-measured from Arch's 0.56.2-4 rebuild of the same Hyprland release.
source_file = Path(source_path)
require(source_file.is_file() and not source_file.is_symlink(), 'source archive must be a regular file')
source_data = source_file.read_bytes()
require(digest(source_data) == '25bc3b2d353ba6bb6ecd17e4b67b11b0d6b731a5ae01025197442c97e50acf7a',
'source archive checksum mismatch')
with tarfile.open(fileobj=io.BytesIO(source_data), mode='r:gz') as contents:
manifest_data = contents.extractfile(stem + '/SOURCE-PROVENANCE.json').read()
manifest = json.loads(manifest_data)
del payload[kit_stem + '.tar.gz']
payload[stem + '.tar.gz'] = source_data
payload['SOURCE-PROVENANCE.json'] = manifest_data
identity = {'revision': manifest['source_revision'], 'driver_version': manifest['driver_version'],
'archive_sha256': digest(source_data), 'manifest_sha256': digest(manifest_data)}
profile_data = Path(profile_path).read_bytes()
require(digest(profile_data) == 'b20d98979137fb5216768d95215f80d372d9bfd2269b541d7bcf664a12f80b97',
'local profile checksum mismatch')
profile = json.loads(payload['PROFILE.json'])
profile.update(profile_id='omarchy-hyprland-0562r4-remaps', package_release=3, source=identity)
profile['hyprland'].update(package_version='0.56.2-4',
sha256='55da553be71222566ee73b973d2f56dbb9939044d8f22f81aa54b66c83f2f6d1',
headers_sha256='1fdefe6ac027a159d04a5dfee4928ec7ebd15544a9a25b5f66d2f5a46fcf364a')
profile['runtime']['packages'].update(aquamarine='0.15.1-1', glibc='2.44+r50+g1848099f063e-1')
require(json.loads(profile_data) == profile,
'local profile changes more than the reviewed source, package versions and re-measured compositor')
payload['PROFILE.json'] = profile_data
provenance = json.loads(payload['KIT-PROVENANCE.json'])
provenance.update(profile_sha256=digest(profile_data), source=identity)
payload['KIT-PROVENANCE.json'] = (json.dumps(provenance, sort_keys=True, indent=2) + '\n').encode()
# Render the recipe the way the kit's own profile_verify.render_recipe does.
recipe = payload['PROFILE-PKGBUILD.in'].decode()
for key, value in {'DRIVER_VERSION': identity['driver_version'], 'PKGREL': str(profile['package_release']),
'PROFILE_ID': profile['profile_id'], 'STEM': stem,
'HYPRLAND_PACKAGE': profile['hyprland']['package_version'],
'RUNTIME_DEPENDS': ' '.join(f"'{name}={version}'" for name, version
in sorted(profile['runtime']['packages'].items())),
'ARCHIVE_SHA256': identity['archive_sha256'], 'PROFILE_SHA256': digest(profile_data),
'KIT_SHA256': digest(payload['KIT-PROVENANCE.json']),
'VERIFIER_SHA256': provenance['tooling_files']['profile_verify.py']}.items():
recipe = recipe.replace(f'@{key}@', value)
payload['PKGBUILD'] = recipe.encode()
payload['SHA256SUMS'] = ''.join(f'{digest(body)} {name}\n' for name, body in sorted(payload.items())
if name != 'SHA256SUMS').encode()
del expected[kit_stem + '.tar.gz']
expected.update({stem + '.tar.gz': '25bc3b2d353ba6bb6ecd17e4b67b11b0d6b731a5ae01025197442c97e50acf7a',
'SOURCE-PROVENANCE.json': '292ac8fa09bec96cbd499d5d57cc8ea9b1c00fe6347162fb6960c45f972bdb9d',
'PROFILE.json': 'b20d98979137fb5216768d95215f80d372d9bfd2269b541d7bcf664a12f80b97',
'KIT-PROVENANCE.json': '3c2141dcb2583d918ef2cdb6ff3805dec62119a439a29c811a93cc980d621423',
'PKGBUILD': '610d426d6f88238fc6fae56afc1d54ba7866800d14e97777d9b47ddc9b347cc0',
'SHA256SUMS': '093dc8708a9b440977662d7f00bccace24b0b9253e6bf0d1decad2655b886881'})
require(payload.keys() == expected.keys(), 'derived kit inventory mismatch')
for name, content in payload.items():
require(digest(content) == expected[name], 'derived kit checksum mismatch: ' + name)
require(srcdir.is_dir() and not srcdir.is_symlink(), 'srcdir must be a real directory')
kit, source = srcdir / 'cua-profile-kit', srcdir / stem
if mode == 'extract':
require(not kit.exists() and not kit.is_symlink() and not source.exists() and not source.is_symlink(),
'prepare requires fresh kit and source destinations; use a clean srcdir')
source_payload = {}
with tarfile.open(fileobj=io.BytesIO(payload[stem + '.tar.gz']), mode='r:gz') as contents:
for member in contents:
require(member.isfile() and not member.issparse() and not member.pax_headers and
member.name.startswith(stem + '/'), 'invalid source member')
name = member.name[len(stem) + 1:]
path = PurePosixPath(name)
require(name and path.as_posix() == name and not path.is_absolute() and
'..' not in path.parts and '\\' not in name and name not in source_payload,
'unsafe or duplicate source path')
source_payload[name] = contents.extractfile(member).read()
kit.mkdir()
source.mkdir()
for name, content in payload.items():
(kit / name).write_bytes(content)
for name, content in source_payload.items():
destination = source / name
destination.parent.mkdir(parents=True, exist_ok=True)
destination.write_bytes(content)
require(kit.is_dir() and not kit.is_symlink(), 'kit must be a real directory')
require({path.name for path in kit.iterdir()} == expected.keys(), 'extracted kit inventory mismatch')
for name, checksum in expected.items():
path = kit / name
require(path.is_file() and not path.is_symlink() and digest(path.read_bytes()) == checksum,
'extracted kit checksum mismatch: ' + name)
CUA_DOWNLOAD_PY
_kit() {
_inputs || return 1
python3 -I -B "$SRCDEST/kit.py" "$1" --archive "$SRCDEST/$_download_name" --archive-sha256 "$_download_sha256" \
--profile "$SRCDEST/PROFILE.json" --srcdir "$srcdir" --kit-sha256 "$_kit_sha256"
}

_verify() {
printf '%s %s\n' "$_download_sha256" "$SRCDEST/$_download_name" | sha256sum -c - || return 1
_verify_download check || return 1
_kit check || return 1
# Explicit checks still apply to --skipinteg, --noextract and --repackage.
printf '%s %s\n' "$_archive_sha256" "$srcdir/cua-profile-kit/${_stem}.tar.gz" | sha256sum -c - || return 1
printf '%s %s\n' "$_kit_sha256" "$srcdir/cua-profile-kit/KIT-PROVENANCE.json" | sha256sum -c - || return 1
Expand All @@ -178,10 +64,7 @@ _verify() {
}

_downstream() {
local name
for name in downstream.patch DOWNSTREAM-PROVENANCE.json downstream.py downstream_test.py; do
printf '%s %s\n' "${_downstream_sha256[$name]}" "$SRCDEST/$name" | sha256sum -c - || return 1
done
_inputs || return 1
python3 -B "$SRCDEST/downstream.py" "$1" \
--pristine "$srcdir/$_stem" --source "$srcdir/omarchy-source" \
--patch "$SRCDEST/downstream.patch" --manifest "$SRCDEST/DOWNSTREAM-PROVENANCE.json" \
Expand All @@ -190,7 +73,7 @@ _downstream() {
}

prepare() {
_verify_download extract || return 1
_kit extract || return 1
_verify || return 1
_downstream prepare
}
Expand All @@ -212,6 +95,8 @@ build() {
check() {
_verify || return 1
_downstream check || return 1
python3 -B "$SRCDEST/kit_test.py" "$SRCDEST/$_download_name" "$_download_sha256" \
"$SRCDEST/PROFILE.json" "$_kit_sha256" || return 1
python3 -B "$SRCDEST/downstream_test.py" || return 1
(
unset LD_PRELOAD FAKEROOTKEY FAKED_MODE
Expand Down
12 changes: 6 additions & 6 deletions pkgbuilds/cua-hyprland-plugin/PROFILE.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"package_version": "0.56.2-4",
"sha256": "55da553be71222566ee73b973d2f56dbb9939044d8f22f81aa54b66c83f2f6d1"
},
"kit_version": "1.1.0",
"kit_version": "1.3.0",
"package_release": 3,
"profile_id": "omarchy-hyprland-0562r4-remaps",
"profile_id": "omarchy-edge-20261004-abi",
"runtime": {
"basename": "libstdc++.so.6.0.36",
"packages": {
Expand All @@ -32,9 +32,9 @@
},
"schema": 2,
"source": {
"archive_sha256": "25bc3b2d353ba6bb6ecd17e4b67b11b0d6b731a5ae01025197442c97e50acf7a",
"driver_version": "0.32.0",
"manifest_sha256": "292ac8fa09bec96cbd499d5d57cc8ea9b1c00fe6347162fb6960c45f972bdb9d",
"revision": "58aba84b5b83d77e7e2b0f006547699eb594e50d"
"archive_sha256": "79596a9a5e7300546ad4ab0646430edcf3e0c0456a541458de2a52b8c44a8fad",
"driver_version": "0.33.2",
"manifest_sha256": "9a7eba9fd642d6697213729311da620fad292cd3f693c8b49b8a07163ef22a1d",
"revision": "c82d32e3e1adbc6578a148962002ddf6e3e8a15a"
}
}
Loading
Loading