mirror of
https://github.com/kuhyx/utils.git
synced 2026-11-10 18:07:24 +01:00
aur-publish/publish.sh 439 -> 148 + lib/aur_registration 107
+ lib/aur_verify 122 + lib/aur_publish_one 107
guard-lib/lib/file_guard.sh 350 -> 140 + file_guard_unlock 214
file_length/config.py 252 -> 45 + _tables 202 + exemptions 77
The libs are sourced, never executed: they read the readonly config the entry
script declares, and a `readonly` re-run inside a twice-sourced lib aborts
under `set -e`. Verified by function parity rather than by eye — publish.sh
resolves the same 17 functions as before the split, guardctl the same 15 —
plus `shellcheck -x` clean on every file and a real `--help` / bad-option run.
file_length is the gate's own code, so a broken import there turns the gate
into a no-op. Split three ways to avoid an import cycle without a `# noqa`:
_tables holds the data, exemptions the rules that read it, config re-exports
both so `from file_length.config import is_generated` still resolves. The
first attempt was wrong — EXCLUDED_DIRS was left behind and every invocation
raised — caught because the gate was re-run in both modes rather than
assumed. Now verified: exit 0 on a clean file, exit 1 on an over-cap one,
--explain intact, and the same 61 exemption decisions as HEAD.
Also deletes baseline-2026-08-14.json and SURVEY-2026-08-14.txt: the task
forbids a baseline file, and nothing in the tree read either.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CFSGeWxHPY5rHUGrPqhcmG
108 lines
3.8 KiB
Bash
108 lines
3.8 KiB
Bash
#!/bin/bash
|
|
|
|
# ============================================================================
|
|
# Building, verifying and pushing one package to the AUR.
|
|
#
|
|
# Sourced by publish.sh, never executed: these functions read the readonly
|
|
# config (AUR_HOST, AUR_ROOT, DRY_RUN, PUBLISHED, FAILED) that the entry script declares, and
|
|
# a `readonly` re-run inside a twice-sourced lib would abort under `set -e`.
|
|
# ============================================================================
|
|
|
|
set -euo pipefail
|
|
|
|
publish_one() {
|
|
local pkg="$1" repo="$2" wrapper="$3" binary="$4" expected="$5"
|
|
local dir="$AUR_ROOT/$pkg"
|
|
local version
|
|
|
|
log "$pkg"
|
|
|
|
[[ -d "$repo" ]] || { warn "$pkg: no repo at $repo"; return 1; }
|
|
[[ -f "$dir/PKGBUILD" ]] || { warn "$pkg: no PKGBUILD at $dir"; return 1; }
|
|
|
|
version="$(newest_tag "$repo")"
|
|
[[ -n "$version" ]] || { warn "$pkg: no vX.Y.Z tag on the remote"; return 1; }
|
|
info "newest release tag: v$version"
|
|
|
|
cd "$dir"
|
|
sed -i -E "s/^pkgver=.*/pkgver=$version/" PKGBUILD
|
|
# The tarball for a tag contains the PKGBUILD, so the checksum can only be
|
|
# computed after the tag exists — never committed ahead of time.
|
|
updpkgsums >/dev/null 2>&1 || { warn "$pkg: updpkgsums failed (tag missing?)"; return 1; }
|
|
|
|
info "building"
|
|
if ! env PATH=/usr/bin:/bin:/usr/local/bin makepkg -Cf --noconfirm >/dev/null 2>&1; then
|
|
warn "$pkg: makepkg failed"
|
|
return 1
|
|
fi
|
|
|
|
local built
|
|
built="$(find . -maxdepth 1 -name "$pkg-$version-*.pkg.tar.zst" | head -1)"
|
|
[[ -n "$built" ]] || { warn "$pkg: no package produced"; return 1; }
|
|
|
|
# namcap's "ELF files outside of a valid path ('opt/')" is a false positive
|
|
# for /opt-installed apps, so only genuinely new errors are worth failing on.
|
|
local findings
|
|
findings="$(namcap "$built" 2>&1 | grep -E ' E: ' | grep -v "outside of a valid path" || true)"
|
|
if [[ -n "$findings" ]]; then
|
|
warn "$pkg: namcap errors:"
|
|
printf ' %s\n' "$findings"
|
|
return 1
|
|
fi
|
|
|
|
info "installing and launching"
|
|
sudo pacman -U --noconfirm "$built" >/dev/null 2>&1 \
|
|
|| { warn "$pkg: pacman -U failed"; return 1; }
|
|
verify_installed "$binary" "$expected" "$wrapper" || { warn "$pkg: launch check failed"; return 1; }
|
|
|
|
# Generated before the rule check, which verifies it matches the PKGBUILD.
|
|
makepkg --printsrcinfo > .SRCINFO
|
|
check_aur_rules "$pkg" || return 1
|
|
|
|
# The AUR repo is a separate remote living alongside the build dir; adding
|
|
# it here (rather than cloning into a fresh path) keeps the verified
|
|
# PKGBUILD and the thing being pushed byte-identical.
|
|
if [[ ! -d .git ]]; then
|
|
git init -q -b master .
|
|
git remote add origin "ssh://aur@$AUR_HOST/$pkg.git"
|
|
fi
|
|
git remote get-url origin >/dev/null 2>&1 \
|
|
|| git remote add origin "ssh://aur@$AUR_HOST/$pkg.git"
|
|
|
|
# Fetch first: an existing AUR package must be built on, not overwritten.
|
|
if git fetch -q origin master 2>/dev/null; then
|
|
git reset -q --soft FETCH_HEAD 2>/dev/null || true
|
|
fi
|
|
|
|
cat > .gitignore <<'EOF'
|
|
# Build products; the AUR tracks only the recipe.
|
|
*.pkg.tar.zst
|
|
*.tar.gz
|
|
src/
|
|
pkg/
|
|
EOF
|
|
|
|
git add PKGBUILD .SRCINFO .gitignore
|
|
if git diff --cached --quiet; then
|
|
info "already up to date on the AUR; nothing to push"
|
|
PUBLISHED+=("$pkg v$version (unchanged)")
|
|
return 0
|
|
fi
|
|
|
|
git -c user.name='Krzysztof Rudnicki' \
|
|
-c user.email='krzysztofrudnicki0@gmail.com' \
|
|
commit -q -m "$pkg $version-1"
|
|
|
|
if ((DRY_RUN)); then
|
|
info "DRY RUN — not pushing"
|
|
PUBLISHED+=("$pkg v$version (dry run)")
|
|
return 0
|
|
fi
|
|
|
|
info "pushing to the AUR"
|
|
git push -q origin master 2>&1 | tail -3 || { warn "$pkg: push failed"; return 1; }
|
|
PUBLISHED+=("$pkg v$version")
|
|
return 0
|
|
}
|
|
|