feat(identity): rename user-visible identity to voculinux with one-time legacy import

The fork takes its own name everywhere a user can see it: binaries
(voculinux, voculinux-gui), desktop entry, autostart, tray, D-Bus
namespace (com.voculinux.Voculinux, no alias for the old name),
config/data/cache dirs, single-instance lock, IBus engine identity,
tray icons, resource prefixes, VOCULINUX_* environment names, and the
update-checker user agent. The internal Python module stays vocalinux
and the distribution metadata keeps the upstream URLs as provenance.

On first run a previous Vocalinux install's config.json, custom
dictionary, and portal restore token are copied once into the new
locations (new config always wins, no merge, no write-back); models
re-resolve through the pinned-checksum download path. An offline
naming-sweep test proves no old-name strings remain on user-visible
surfaces outside the allowlist.

Refs #18
This commit is contained in:
soubarnak
2026-11-06 01:29:39 +05:30
parent c565e6d946
commit ea7be5f111
251 changed files with 2449 additions and 1991 deletions
+22 -22
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
# Build vocalinux_<version>_<arch>.deb and vocalinux-<version>.<arch>.rpm.
# Build voculinux_<version>_<arch>.deb and voculinux-<version>.<arch>.rpm.
#
# Usage: build.sh <path-to-vocalinux-wheel> <version> [output-dir]
# Usage: build.sh <path-to-voculinux-wheel> <version> [output-dir]
# version release version, e.g. 0.18.0 or 0.19.0-beta
#
# CI and releases run this inside docker-build.sh's pinned Debian 12 image;
@@ -63,18 +63,18 @@ NFPM="$TOOLS/nfpm"
PAYLOAD="$TOOLS/payload"
DOC="$TOOLS/pkg-doc"
install -d \
"$PAYLOAD/usr/lib/vocalinux/app" \
"$PAYLOAD/usr/lib/vocalinux/vendor" \
"$PAYLOAD/usr/lib/voculinux/app" \
"$PAYLOAD/usr/lib/voculinux/vendor" \
"$PAYLOAD/usr/bin" \
"$PAYLOAD/usr/share/applications" \
"$PAYLOAD/usr/share/icons/hicolor/scalable/apps" \
"$DOC"
# --- application payload ------------------------------------------------
# The wheel is a zip; -m zipfile lays out vocalinux/ and its dist-info
# The wheel is a zip; -m zipfile lays out voculinux/ and its dist-info
# exactly where pip --target would, without pip's EXTERNALLY-MANAGED refusal
# on Debian 12.
python3 -m zipfile -e "$WHEEL" "$PAYLOAD/usr/lib/vocalinux/app/"
python3 -m zipfile -e "$WHEEL" "$PAYLOAD/usr/lib/voculinux/app/"
# --- vendored wheels -----------------------------------------------------
# Download each supported CPython's pywhispercpp wheel — it has no abi3 tag,
@@ -99,7 +99,7 @@ for PYV in $VENDOR_PYS; do
--python-version "$PYV" -r "$PINS_VENDOR" -d "$TOOLS/wheels/$PYV" >/dev/null
done
for VENDOR_WHEEL in "$TOOLS"/wheels/*/*.whl; do
python3 -m zipfile -e "$VENDOR_WHEEL" "$PAYLOAD/usr/lib/vocalinux/vendor/"
python3 -m zipfile -e "$VENDOR_WHEEL" "$PAYLOAD/usr/lib/voculinux/vendor/"
done
# --- portable libggml-cpu -------------------------------------------------
@@ -144,7 +144,7 @@ swapped=0
while IFS= read -r vendored; do
cp "$BASELINE_CPU" "$vendored"
swapped=$((swapped + 1))
done < <(find "$PAYLOAD/usr/lib/vocalinux/vendor" -name 'libggml-cpu*.so*')
done < <(find "$PAYLOAD/usr/lib/voculinux/vendor" -name 'libggml-cpu*.so*')
[ "$swapped" -gt 0 ] || fail "found no vendored libggml-cpu to replace"
# The baseline library's own NEEDED entries use the unmangled sonames
# (libggml-base.so.0, libgomp.so.1), so alias the vendored copies — the same
@@ -157,30 +157,30 @@ while IFS= read -r libs_dir; do
vendored_gomp="$(find "$libs_dir" -name 'libgomp*.so*' | head -1)"
[ -n "$vendored_gomp" ] || fail "no vendored libgomp in $libs_dir"
cp "$vendored_gomp" "$libs_dir/libgomp.so.1"
done < <(find "$PAYLOAD/usr/lib/vocalinux/vendor" -type d -name 'pywhispercpp.libs')
done < <(find "$PAYLOAD/usr/lib/voculinux/vendor" -type d -name 'pywhispercpp.libs')
# --- launchers -----------------------------------------------------------
# Same environment install.sh's wrapper establishes: the vendored
# pywhispercpp.libs on LD_LIBRARY_PATH, user site-packages off so they cannot
# shadow the distro modules, and sg input so evdev hotkeys work on Wayland
# when the user is already in the input group but the session has not picked
# up the membership yet. vocalinux-gui exists because the wheel declares a
# up the membership yet. voculinux-gui exists because the wheel declares a
# gui-script of that name; on Linux it runs the same entry.
write_launcher() {
local path="$1"
cat > "$path" <<'LAUNCHER_EOF'
#!/bin/sh
# Launcher for the distro-packaged Vocalinux. The vendored wheels (the
# Launcher for the distro-packaged Voculinux. The vendored wheels (the
# pywhispercpp/pynput copies Debian and Fedora do not ship) live under
# /usr/lib/vocalinux/vendor with the app itself under .../app; the loader in
# /usr/lib/voculinux/vendor with the app itself under .../app; the loader in
# utils/pywhispercpp_loader.py finds the bundled .so files from sys.path.
PYTHONNOUSERSITE=1
VOCALINUX_VENDOR="/usr/lib/vocalinux/vendor"
if [ -d "$VOCALINUX_VENDOR/pywhispercpp.libs" ]; then
LD_LIBRARY_PATH="$VOCALINUX_VENDOR/pywhispercpp.libs${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
VOCULINUX_VENDOR="/usr/lib/voculinux/vendor"
if [ -d "$VOCULINUX_VENDOR/pywhispercpp.libs" ]; then
LD_LIBRARY_PATH="$VOCULINUX_VENDOR/pywhispercpp.libs${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
export LD_LIBRARY_PATH
fi
export PYTHONNOUSERSITE PYTHONPATH="/usr/lib/vocalinux/app:$VOCALINUX_VENDOR${PYTHONPATH:+:$PYTHONPATH}"
export PYTHONNOUSERSITE PYTHONPATH="/usr/lib/voculinux/app:$VOCULINUX_VENDOR${PYTHONPATH:+:$PYTHONPATH}"
if grep -q "^input:.*\b$(whoami)\b" /etc/group 2>/dev/null \
&& ! groups | grep -q "\binput\b" && command -v sg >/dev/null 2>&1; then
# sg(1) takes a single command string, so each argument is re-quoted for
@@ -196,14 +196,14 @@ exec /usr/bin/python3 -m vocalinux.main "$@"
LAUNCHER_EOF
chmod 755 "$path"
}
write_launcher "$PAYLOAD/usr/bin/vocalinux"
write_launcher "$PAYLOAD/usr/bin/vocalinux-gui"
write_launcher "$PAYLOAD/usr/bin/voculinux"
write_launcher "$PAYLOAD/usr/bin/voculinux-gui"
# --- desktop entry, icon, license ----------------------------------------
install -Dm644 "$REPO_ROOT/vocalinux.desktop" \
"$PAYLOAD/usr/share/applications/vocalinux.desktop"
install -Dm644 "$REPO_ROOT/resources/icons/scalable/vocalinux.svg" \
"$PAYLOAD/usr/share/icons/hicolor/scalable/apps/vocalinux.svg"
install -Dm644 "$REPO_ROOT/voculinux.desktop" \
"$PAYLOAD/usr/share/applications/voculinux.desktop"
install -Dm644 "$REPO_ROOT/resources/icons/scalable/voculinux.svg" \
"$PAYLOAD/usr/share/icons/hicolor/scalable/apps/voculinux.svg"
install -Dm644 "$REPO_ROOT/LICENSE" "$DOC/LICENSE"
# --- package -------------------------------------------------------------