#!/usr/bin/env bash # # Build a Void Linux binary package (.xbps) for Voiced from this source tree, # without needing the full xbps-src / void-packages setup. # # ./packaging/void/build-xbps.sh # # Output: # dist/void/repo/voiced-_1..xbps (and a local repository index) # # Install it with: # sudo xbps-install -S --repository="$(pwd)/dist/void/repo" voiced # # Remove it with: # sudo xbps-remove voiced # set -euo pipefail ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" cd "$ROOT" need() { command -v "$1" >/dev/null 2>&1 || { echo "error: '$1' is required but not on PATH" >&2; exit 1; } } for tool in xbps-create xbps-rindex node npm cargo; do need "$tool"; done VERSION="$(node -p "require('./package.json').version")" REVISION="${REVISION:-1}" ARCH="$(xbps-uhelper arch 2>/dev/null || uname -m)" PKGVER="voiced-${VERSION}_${REVISION}" echo "==> Building the Linux binary (frontend embedded via the Tauri CLI)" npx tauri build --no-bundle --features custom-protocol BIN="src-tauri/target/release/voiced" [ -x "$BIN" ] || { echo "error: expected binary not found at $BIN" >&2; exit 1; } echo "==> Staging install tree" STAGE="$(mktemp -d)" trap 'rm -rf "$STAGE"' EXIT install -Dm755 "$BIN" "$STAGE/usr/bin/voiced" install -Dm644 packaging/void/voiced.desktop "$STAGE/usr/share/applications/voiced.desktop" install_icon() { [ -f "$1" ] || return 0 install -Dm644 "$1" "$STAGE/usr/share/icons/hicolor/$2/apps/voiced.png" } install_icon src-tauri/icons/32x32.png 32x32 install_icon src-tauri/icons/64x64.png 64x64 install_icon src-tauri/icons/128x128.png 128x128 install_icon src-tauri/icons/128x128@2x.png 256x256 install_icon src-tauri/icons/icon.png 512x512 install -Dm644 README.md "$STAGE/usr/share/doc/voiced/README.md" # Bundled fonts: one subdirectory per family under /usr/share/fonts/voiced, plus # each family's OFL text. Only *.ttf files are installed (not manifest.json, and # not the legacy woff/woff2 files that sit directly in public/fonts). for dir in public/fonts/*/; do family="$(basename "$dir")" for ttf in "$dir"*.ttf; do install -Dm644 "$ttf" "$STAGE/usr/share/fonts/voiced/$family/$(basename "$ttf")" done install -Dm644 "${dir}OFL.txt" "$STAGE/usr/share/licenses/voiced/${family}-OFL.txt" done # xbps action scripts. xbps-create packs INSTALL and REMOVE found at the root of # the destdir into the archive (verified: they appear as ./INSTALL and ./REMOVE # members and are excluded from files.plist), and xbps runs them with $1 set to # the action. They refresh the fontconfig cache for /usr/share/fonts/voiced. # Fallback if a future xbps-create stops carrying them: font cache refresh would # then rely on fontconfig regenerating its cache on first use, or on the xbps-src # template (which uses the same scripts). install -Dm755 packaging/void/INSTALL "$STAGE/INSTALL" install -Dm755 packaging/void/REMOVE "$STAGE/REMOVE" echo "==> Creating $PKGVER.$ARCH.xbps" # Kept outside Vite's `dist/` output directory, which is wiped on every build. OUT="$ROOT/build/void" REPO="$OUT/repo" mkdir -p "$REPO" # xbps-create writes the package into the current directory. ( cd "$OUT" xbps-create \ -A "$ARCH" \ -n "$PKGVER" \ -s "Offline invoicing app by Bongbetic" \ -S "Voiced is an offline-first invoice generator with automatic numbering, GST support, optional signatures and print-ready PDF export." \ -l "Apache-2.0" \ -H "https://git.bongbetic.com/xavierk/Voiced" \ -m "Xavier Karma " \ -D "libwebkit2gtk41>=2.50_1 fontconfig>=0 xdg-utils>=0 hicolor-icon-theme>=0 desktop-file-utils>=0" \ -t "office finance" \ --compression zstd \ "$STAGE" ) mv -f "$OUT"/${PKGVER}.*.xbps "$REPO/" echo "==> Indexing local repository" # -f re-adds a package whose version is already indexed. Without it a rebuild of the # same version keeps the old checksum in the index and xbps-install rejects the new file. xbps-rindex -f -a "$REPO"/*.xbps echo echo "Package: $REPO/${PKGVER}.${ARCH}.xbps" echo "Install: sudo xbps-install -S --repository=\"$REPO\" voiced"