Import the vocalinux source tree (tray app, Next.js site in web/, packaging, installers, docs and tests) on top of the Gitea template commit. The project README replaces the template README, and the template CI files (.gitea/workflows/ci.yml, .jscpd.json, CI.md) are kept.
98 lines
3.5 KiB
Bash
Executable File
98 lines
3.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Install the built native package inside its distro container and prove the
|
|
# app it ships actually runs.
|
|
#
|
|
# Usage (mount the package dir at /out and this script's dir at /pk):
|
|
# docker run --rm -v "$PWD/dist:/out:ro" -v "$PWD/packaging/native:/pk:ro" \
|
|
# debian:12 bash /pk/smoke-test.sh
|
|
# or: just native-smoke debian:12
|
|
#
|
|
# What this proves: the package manager accepts the package and resolves its
|
|
# declared dependencies, the /usr/bin launcher runs, and the import graph —
|
|
# gi, GTK, the app modules and the vendored wheels — resolves against the
|
|
# distro interpreter. It is the native-package counterpart of install-gate
|
|
# and the AppImage boot matrix: Debian and Ubuntu exercise the .deb, Fedora
|
|
# the .rpm.
|
|
#
|
|
# What it does not prove: dictation. No container here has audio or a
|
|
# display, and the point is the package, not the app — the app's own tests
|
|
# cover behaviour.
|
|
set -euo pipefail
|
|
|
|
fail() {
|
|
echo "FAIL: $*" >&2
|
|
exit 1
|
|
}
|
|
|
|
[ -r /etc/os-release ] || fail "/etc/os-release missing — not a distro container?"
|
|
# shellcheck disable=SC1091
|
|
. /etc/os-release
|
|
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
case "$ID" in
|
|
debian|ubuntu)
|
|
PKG="$(find /out -name '*.deb' -print -quit)"
|
|
[ -n "$PKG" ] || fail "no .deb under /out"
|
|
apt-get update
|
|
apt-get install -y "$PKG"
|
|
;;
|
|
fedora)
|
|
PKG="$(find /out -name '*.rpm' -print -quit)"
|
|
[ -n "$PKG" ] || fail "no .rpm under /out"
|
|
dnf install -y "$PKG"
|
|
;;
|
|
*)
|
|
fail "no smoke recipe for distro ID '$ID' — add one alongside the dependency list it is meant to exercise"
|
|
;;
|
|
esac
|
|
|
|
echo "== installed: $PKG"
|
|
|
|
# The launcher must answer: --version is an argparse action that exits
|
|
# before check_dependencies() touches GTK, so it proves the wrapper, the
|
|
# PYTHONPATH layout and the entry module's import chain — the dependency
|
|
# typelibs are exercised by the import smoke below.
|
|
vocalinux --version
|
|
vocalinux-gui --version
|
|
|
|
# Import smoke in the shape of the AUR gate: the app modules, the vendored
|
|
# pywhispercpp wheel, and the distro gi/GTK typelibs, all through the same
|
|
# interpreter and environment the launcher sets up. pynput is only checked
|
|
# for presence: its __init__ selects a display backend and raises ImportError
|
|
# with no DISPLAY, which is why the app guards it with PYNPUT_AVAILABLE.
|
|
PYTHONPATH="/usr/lib/vocalinux/app:/usr/lib/vocalinux/vendor" \
|
|
PYTHONNOUSERSITE=1 \
|
|
LD_LIBRARY_PATH="/usr/lib/vocalinux/vendor/pywhispercpp.libs" \
|
|
/usr/bin/python3 - <<'PY'
|
|
import importlib
|
|
import importlib.util
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
MODULES = (
|
|
"vocalinux.main",
|
|
"vocalinux.ui.tray_indicator",
|
|
"vocalinux.speech_recognition.recognition_manager",
|
|
"vocalinux.speech_recognition.command_processor",
|
|
"vocalinux.text_injection.text_injector",
|
|
"vocalinux.text_injection.ibus_engine",
|
|
"vocalinux.ui.keyboard_backends",
|
|
"pywhispercpp.model",
|
|
)
|
|
for module in MODULES:
|
|
importlib.import_module(module)
|
|
|
|
spec = importlib.util.find_spec("pynput")
|
|
assert spec and spec.origin and spec.origin.startswith("/usr/lib/vocalinux/vendor/"), \
|
|
f"vendored pynput not found on sys.path: {spec}"
|
|
|
|
tag = f"cpython-{sys.version_info.major}{sys.version_info.minor}-"
|
|
exts = [p.name for p in Path("/usr/lib/vocalinux/vendor").glob("_pywhispercpp.*.so")]
|
|
assert any(tag in name for name in exts), \
|
|
f"no _pywhispercpp extension for {tag[:-1]} among {exts}"
|
|
|
|
print("import-smoke OK:", ", ".join(MODULES))
|
|
PY
|
|
|
|
echo "SMOKE-TEST PASSED"
|