From cb2f687a6baabfd61c37e875498e071935bcc395 Mon Sep 17 00:00:00 2001 From: Seth Freiberg Date: Wed, 29 Apr 2026 10:28:55 -0400 Subject: [PATCH] feat: add deps-debian.sh (build-dep manifest + checker) Co-Authored-By: Claude Sonnet 4.6 --- scripts/lib/deps-debian.sh | 65 ++++++++++++++++++++++++++++++++ tests-impl/test-deps-debian.bats | 63 +++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100755 scripts/lib/deps-debian.sh create mode 100644 tests-impl/test-deps-debian.bats diff --git a/scripts/lib/deps-debian.sh b/scripts/lib/deps-debian.sh new file mode 100755 index 0000000..2706138 --- /dev/null +++ b/scripts/lib/deps-debian.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env bash +# Single source of truth for sethLabels build dependencies on Debian-family Linux. +# +# When SOURCED: exposes SETHLABELS_DEPS array (no side effects). +# When EXECUTED: verifies each dep is installed; prints actionable +# `sudo apt install ...` command on missing deps; exits 1. +# On clean state, prints "All build dependencies present." and exits 0. +# +# Spec: sethlabels-docs/specs/2026-04-29-packaging-design.md §5.1 +set -euo pipefail + +SETHLABELS_DEPS=( + build-essential cmake ninja-build pkg-config + qt6-base-dev qt6-base-dev-tools + qt6-svg-dev + qt6-tools-dev qt6-tools-dev-tools + qt6-l10n-tools + libqt6printsupport6 libqt6svg6 libqt6widgets6 libqt6xml6 libqt6gui6 + libqt6concurrent6 libqt6core6 libqt6test6 + zlib1g-dev libqrencode-dev libzint-dev libgnubarcode-dev + file dpkg-dev fakeroot + wget + bats +) + +# Detect sourced vs. executed. +# When sourced: BASH_SOURCE[0] != $0 +# When executed: BASH_SOURCE[0] == $0 +if [ "${BASH_SOURCE[0]}" != "${0}" ]; then + return 0 2>/dev/null || exit 0 +fi + +# --- Executed path --- + +# Sanity check the build host +if [ ! -f /etc/os-release ]; then + echo "WARNING: /etc/os-release missing; not Debian-family. This script is designed for Debian 13 / Ubuntu LTS." >&2 +fi + +if [ -f /etc/os-release ]; then + . /etc/os-release + if [[ "${ID:-}" != "debian" && "${ID:-}" != "ubuntu" ]] && [[ "${ID_LIKE:-}" != *debian* && "${ID_LIKE:-}" != *ubuntu* ]]; then + echo "WARNING: not running on Debian or Ubuntu (detected ID='${ID:-unknown}'). Build deps may differ." >&2 + fi +fi + +missing=() +for pkg in "${SETHLABELS_DEPS[@]}"; do + if ! dpkg-query -W -f='${Status}' "$pkg" 2>/dev/null | grep -q "install ok installed"; then + missing+=("$pkg") + fi +done + +if [ "${#missing[@]}" -gt 0 ]; then + echo "Missing build dependencies (${#missing[@]}):" + for p in "${missing[@]}"; do + echo " - $p" + done + echo "" + echo "Install with:" + echo " sudo apt install -y ${missing[*]}" + exit 1 +fi + +echo "All build dependencies present (${#SETHLABELS_DEPS[@]} packages verified)." diff --git a/tests-impl/test-deps-debian.bats b/tests-impl/test-deps-debian.bats new file mode 100644 index 0000000..cfdc854 --- /dev/null +++ b/tests-impl/test-deps-debian.bats @@ -0,0 +1,63 @@ +#!/usr/bin/env bats + +# Tests for scripts/lib/deps-debian.sh + +setup() { + REPO_ROOT="$(git rev-parse --show-toplevel)" + SCRIPT="$REPO_ROOT/scripts/lib/deps-debian.sh" +} + +@test "script exists and is executable" { + [ -x "$SCRIPT" ] +} + +@test "sourceable: exposes SETHLABELS_DEPS array" { + source "$SCRIPT" + [ "${#SETHLABELS_DEPS[@]}" -gt 5 ] +} + +@test "SETHLABELS_DEPS contains core build tools" { + source "$SCRIPT" + [[ " ${SETHLABELS_DEPS[*]} " == *" cmake "* ]] + [[ " ${SETHLABELS_DEPS[*]} " == *" ninja-build "* ]] + [[ " ${SETHLABELS_DEPS[*]} " == *" build-essential "* ]] +} + +@test "SETHLABELS_DEPS contains Qt6 libraries" { + source "$SCRIPT" + [[ " ${SETHLABELS_DEPS[*]} " == *" qt6-base-dev "* ]] + [[ " ${SETHLABELS_DEPS[*]} " == *" qt6-svg-dev "* ]] + [[ " ${SETHLABELS_DEPS[*]} " == *" qt6-tools-dev "* ]] +} + +@test "SETHLABELS_DEPS contains barcode + zlib deps" { + source "$SCRIPT" + [[ " ${SETHLABELS_DEPS[*]} " == *" zlib1g-dev "* ]] + [[ " ${SETHLABELS_DEPS[*]} " == *" libqrencode-dev "* ]] + [[ " ${SETHLABELS_DEPS[*]} " == *" libzint-dev "* ]] +} + +@test "SETHLABELS_DEPS contains packaging tools" { + source "$SCRIPT" + [[ " ${SETHLABELS_DEPS[*]} " == *" dpkg-dev "* ]] + [[ " ${SETHLABELS_DEPS[*]} " == *" fakeroot "* ]] + [[ " ${SETHLABELS_DEPS[*]} " == *" wget "* ]] +} + +@test "executed: prints status and exits 0 (when all installed) OR 1 with apt-install hint" { + run "$SCRIPT" + if [ "$status" -eq 0 ]; then + [[ "$output" == *"All build dependencies present"* ]] + else + [[ "$output" == *"sudo apt install"* ]] + fi +} + +@test "executed: warns if not on Debian/Ubuntu" { + # Simulate non-Debian by overriding /etc/os-release path via env var + if [ -f /etc/os-release ] && grep -qE '^ID=(debian|ubuntu)' /etc/os-release; then + skip "currently on Debian/Ubuntu — non-Debian path covered by source review" + fi + run "$SCRIPT" + [[ "$output" == *"Debian"* || "$output" == *"Ubuntu"* ]] +}