Derive an exact Aquamarine 0.15.1-1 profile from the verified upstream kit so edge installations resolve without weakening native compatibility checks. Co-Authored-By: Codex GPT-6 Astra xhigh <noreply@openai.com>
209 lines
13 KiB
Bash
209 lines
13 KiB
Bash
# Verified upstream kit plus a separately pinned Omarchy keyboard-remap 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.26.1
|
|
pkgrel=6
|
|
pkgdesc='Cua input candidate for reviewed profile omarchy-hypr0562r3-aq0151-remaps'
|
|
arch=('x86_64')
|
|
url='https://github.com/trycua/cua'
|
|
license=('MIT')
|
|
depends=('hyprland=0.56.2-3' 'aquamarine=0.15.1-1' 'glibc=2.44+r24+g16be1518495f-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.26.1-cc54254464c0c9aebfd6547fe7e4a0ceaf0456d7'
|
|
_archive_sha256='47bca9e018f32f4fcfe683f91c7475c60368f3b65d318cc35c1f2de88a4ee9ab'
|
|
_kit_sha256='819779b93655d603d9ebb0d33ea052326c3374674a1d473886106af25e0fffdd'
|
|
_profile_sha256='a2eade8b8195036be2c666788a1d28ac722403285a35987d92b3344e095f9a5e'
|
|
_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'
|
|
'PROFILE.json')
|
|
noextract=("$_download_name")
|
|
sha256sums=('a89bfa7f6490f598719dfabdd2a5badc137e27b0764fd25e6a05e1f969433520'
|
|
'a2eade8b8195036be2c666788a1d28ac722403285a35987d92b3344e095f9a5e')
|
|
|
|
# Downstream inputs are also checked explicitly when makepkg integrity is skipped.
|
|
declare -gA _downstream_sha256=(
|
|
['independent-keymaps.patch']='e74d9021111a5c217b12f3e13c1bbdd260e829c60db5fc2f7293ba4846e1a7d7'
|
|
['DOWNSTREAM-PROVENANCE.json']='e0c95350ec3ff2dd54a05e9377d79ddffffdb1cf494d05553a90207a3a919f7e'
|
|
['downstream.py']='7c9725805ad038737bd4d346c85f27991ce9ddfff436a32ebf515cad1bf98ca1'
|
|
['downstream_test.py']='7b9a992979b22a5e061fdf011ac6be59a3f1ae6e0d7c0a8ff631f74e71984c5a'
|
|
)
|
|
source+=('independent-keymaps.patch' 'DOWNSTREAM-PROVENANCE.json' 'downstream.py' 'downstream_test.py')
|
|
sha256sums+=('e74d9021111a5c217b12f3e13c1bbdd260e829c60db5fc2f7293ba4846e1a7d7' 'e0c95350ec3ff2dd54a05e9377d79ddffffdb1cf494d05553a90207a3a919f7e' '7c9725805ad038737bd4d346c85f27991ce9ddfff436a32ebf515cad1bf98ca1' '7b9a992979b22a5e061fdf011ac6be59a3f1ae6e0d7c0a8ff631f74e71984c5a')
|
|
|
|
_verify_download() {
|
|
python3 -I - "$SRCDEST/$_download_name" "$_download_sha256" "$srcdir" "$1" "$SRCDEST/PROFILE.json" <<'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'}
|
|
stem = 'cua-hyprland-plugin-0.26.1-cc54254464c0c9aebfd6547fe7e4a0ceaf0456d7'
|
|
|
|
def require(condition, message):
|
|
if not condition:
|
|
raise SystemExit(message)
|
|
|
|
def digest(data):
|
|
return hashlib.sha256(data).hexdigest()
|
|
|
|
archive, checksum, srcdir, mode, profile_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')
|
|
# Derive the reviewed Hyprland -3/Aquamarine 0.15.1 profile while preserving
|
|
# upstream source/tooling and compiler, compositor, header and runtime hashes.
|
|
profile_data = Path(profile_path).read_bytes()
|
|
require(digest(profile_data) == 'a2eade8b8195036be2c666788a1d28ac722403285a35987d92b3344e095f9a5e',
|
|
'local profile checksum mismatch')
|
|
profile = json.loads(payload['PROFILE.json'])
|
|
profile.update(profile_id='omarchy-hypr0562r3-aq0151-remaps', package_release=6)
|
|
profile['hyprland']['package_version'] = '0.56.2-3'
|
|
profile['runtime']['packages']['aquamarine'] = '0.15.1-1'
|
|
require(json.loads(profile_data) == profile, 'local profile changes more than the reviewed package versions')
|
|
payload['PROFILE.json'] = profile_data
|
|
provenance = json.loads(payload['KIT-PROVENANCE.json'])
|
|
provenance['profile_sha256'] = digest(profile_data)
|
|
payload['KIT-PROVENANCE.json'] = (json.dumps(provenance, sort_keys=True, indent=2) + '\n').encode()
|
|
recipe = payload['PKGBUILD'].decode()
|
|
for old, new in [('pkgrel=2\n', 'pkgrel=6\n'), ('omarchy-stable-20260910', profile['profile_id']),
|
|
('hyprland=0.56.2-2', 'hyprland=0.56.2-3'),
|
|
('aquamarine=0.15.0-2', 'aquamarine=0.15.1-1'),
|
|
('5dacea79a6a5927e59fca7b51e6c04e94fa45133ac1b8fb7f4e1f442d113eb9a', digest(profile_data)),
|
|
('7beb736adfd334eed52e84070177634269e3a09f8bb25971b38606933ff4c997', digest(payload['KIT-PROVENANCE.json']))]:
|
|
recipe = recipe.replace(old, new)
|
|
payload['PKGBUILD'] = recipe.encode()
|
|
payload['SHA256SUMS'] = ''.join(f'{digest(body)} {name}\n' for name, body in sorted(payload.items())
|
|
if name != 'SHA256SUMS').encode()
|
|
expected.update({'PROFILE.json': 'a2eade8b8195036be2c666788a1d28ac722403285a35987d92b3344e095f9a5e',
|
|
'KIT-PROVENANCE.json': '819779b93655d603d9ebb0d33ea052326c3374674a1d473886106af25e0fffdd',
|
|
'PKGBUILD': 'c3e4149eba3f7def10ef700b30b9d0abcea994e3dd32fb169014874a0b75687c',
|
|
'SHA256SUMS': 'd9057a9534f7a820ee04cbf5d60db567c5072fa96d1f71030a6a85b4bb7ce881'})
|
|
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
|
|
}
|
|
|
|
_verify() {
|
|
printf '%s %s\n' "$_download_sha256" "$SRCDEST/$_download_name" | sha256sum -c - || return 1
|
|
_verify_download 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
|
|
printf '%s %s\n' "$_profile_sha256" "$srcdir/cua-profile-kit/PROFILE.json" | sha256sum -c - || return 1
|
|
printf '%s %s\n' "$_verifier_sha256" "$srcdir/cua-profile-kit/profile_verify.py" | sha256sum -c - || return 1
|
|
python3 "$srcdir/cua-profile-kit/profile_verify.py" --kit "$srcdir/cua-profile-kit" --kit-sha256 "$_kit_sha256" \
|
|
--archive "$srcdir/cua-profile-kit/${_stem}.tar.gz" --source "$srcdir/$_stem" --cxx "$_cxx"
|
|
}
|
|
|
|
_downstream() {
|
|
local name
|
|
for name in independent-keymaps.patch DOWNSTREAM-PROVENANCE.json downstream.py downstream_test.py; do
|
|
printf '%s %s\n' "${_downstream_sha256[$name]}" "$SRCDEST/$name" | sha256sum -c - || return 1
|
|
done
|
|
python3 -B "$SRCDEST/downstream.py" "$1" \
|
|
--pristine "$srcdir/$_stem" --source "$srcdir/omarchy-source" \
|
|
--patch "$SRCDEST/independent-keymaps.patch" --manifest "$SRCDEST/DOWNSTREAM-PROVENANCE.json" \
|
|
--kit "$srcdir/cua-profile-kit" --kit-sha256 "$_kit_sha256" \
|
|
--archive "$srcdir/cua-profile-kit/${_stem}.tar.gz" --cxx "$_cxx" "${@:2}"
|
|
}
|
|
|
|
prepare() {
|
|
_verify_download extract || return 1
|
|
_verify || return 1
|
|
_downstream prepare
|
|
}
|
|
|
|
build() {
|
|
_verify || return 1
|
|
_downstream check || return 1
|
|
cmake -S "$srcdir/omarchy-source" -B "$srcdir/build" -G Ninja \
|
|
-DCMAKE_BUILD_TYPE=Release -DCMAKE_CXX_COMPILER="$_cxx" \
|
|
-DPKG_CONFIG_EXECUTABLE=/usr/bin/pkgconf -DPKG_CONFIG_ARGN= \
|
|
-DPKG_CONFIG_USE_CMAKE_PREFIX_PATH=OFF -DCMAKE_PREFIX_PATH= \
|
|
-DBUILD_TESTING=ON -DCUA_HYPRLAND_BUILD_PLUGIN=ON \
|
|
-DCUA_HYPRLAND_EXPECTED_VERSION=0.56.2 \
|
|
-DCUA_HYPRLAND_INPUT=ON -DCUA_HYPRLAND_TEST_INPUT=OFF \
|
|
-DCUA_HYPRLAND_INPUT_TRACE=OFF -DCUA_HYPRLAND_TEST_OPERATOR_KEY= || return 1
|
|
cmake --build "$srcdir/build"
|
|
}
|
|
|
|
check() {
|
|
_verify || return 1
|
|
_downstream check || return 1
|
|
python3 -B "$SRCDEST/downstream_test.py" || return 1
|
|
(
|
|
unset LD_PRELOAD FAKEROOTKEY FAKED_MODE
|
|
ctest --test-dir "$srcdir/build" --output-on-failure --no-tests=error
|
|
)
|
|
}
|
|
|
|
package() {
|
|
check || return 1
|
|
_downstream build --build "$srcdir/build" --output "$srcdir/BUILD-PROVENANCE.json" || return 1
|
|
install -Dm755 "$srcdir/build/cua-hyprland-plugin.so" \
|
|
"$pkgdir/usr/lib/cua/hyprland/cua-hyprland-plugin.so" || return 1
|
|
install -Dm644 "$srcdir/$_stem/LICENSE.md" \
|
|
"$pkgdir/usr/share/licenses/$pkgname/LICENSE" || return 1
|
|
install -Dm644 "$srcdir/$_stem/SOURCE-PROVENANCE.json" \
|
|
"$pkgdir/usr/share/$pkgname/SOURCE-PROVENANCE.json" || return 1
|
|
local name
|
|
install -Dm644 "$srcdir/BUILD-PROVENANCE.json" "$pkgdir/usr/share/$pkgname/BUILD-PROVENANCE.json" || return 1
|
|
for name in KIT-PROVENANCE.json PROFILE.json profile_verify.py; do
|
|
install -Dm644 "$srcdir/cua-profile-kit/$name" "$pkgdir/usr/share/$pkgname/$name" || return 1
|
|
done
|
|
for name in DOWNSTREAM-PROVENANCE.json independent-keymaps.patch; do
|
|
install -Dm644 "$SRCDEST/$name" "$pkgdir/usr/share/$pkgname/$name" || return 1
|
|
done
|
|
}
|