Add packaging, date-based versioning, and full install docs

Versions are now the release date and a revision within that day, padded to
two digits so they sort as text: 2026-08-21_01.

Neither packaging system accepts that form, so it is converted at the edge
rather than kept as a second version string that could drift out of step:
PEP 440 forbids dashes and underscores in a release segment, and a Debian
version may not contain an underscore at all. The date and revision in
__init__.py are the single source; pyproject reads the converted form, and
the tests check that pip and dpkg both order releases correctly.

packaging/build-deb.sh builds a .deb with plain dpkg-deb. Every dependency
is already in Debian, so apt resolves the lot; the package also blacklists
the DVB-T driver that would otherwise claim the receiver. Deliberately not
debhelper: the payload is pure Python with nothing to compile, and this way
the build needs nothing installed beyond dpkg.

The speech recognisers are not packaged for Debian and can only come from
pip, so they are suggested rather than depended on -- transcription is off
by default and reports plainly when no recogniser is present.

README now documents every dependency with its package name on Debian,
Fedora and Arch, how to let a user reach the receiver, and how to check the
install worked.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
The Dust Council 2026-08-21 21:05:51 -07:00
parent db3e0c79b9
commit 52fe16123f
5 changed files with 313 additions and 30 deletions

87
packaging/build-deb.sh Executable file
View file

@ -0,0 +1,87 @@
#!/bin/sh
# Build a .deb that pulls in every dependency through apt.
#
# Deliberately plain dpkg-deb rather than debhelper: everything this package
# needs is already in Debian, the payload is pure Python with no compiled
# parts, and this way the build needs nothing installed beyond dpkg itself.
set -eu
here=$(cd "$(dirname "$0")/.." && pwd)
version=$(cd "$here" && python3 -c 'import bandsaunter; print(bandsaunter.debian_version())')
revision=${DEB_REVISION:-1}
arch=all
stage=$(mktemp -d)
trap 'rm -rf "$stage"' EXIT
pkgdir="$stage/bandsaunter_${version}-${revision}_${arch}"
site="$pkgdir/usr/lib/python3/dist-packages"
mkdir -p "$site/bandsaunter" "$pkgdir/usr/bin" "$pkgdir/DEBIAN" \
"$pkgdir/usr/share/doc/bandsaunter"
cp "$here"/bandsaunter/*.py "$site/bandsaunter/"
cp "$here/README.md" "$pkgdir/usr/share/doc/bandsaunter/"
gzip -9n "$pkgdir/usr/share/doc/bandsaunter/README.md"
cat > "$pkgdir/usr/bin/bandsaunter" <<'EOF'
#!/usr/bin/python3
import sys
from bandsaunter.cli import main
sys.exit(main())
EOF
chmod 755 "$pkgdir/usr/bin/bandsaunter"
# Every one of these is in Debian, so apt resolves the lot. The speech
# recognisers are not packaged for Debian and can only come from pip, so they
# are suggested rather than depended on -- transcription is off by default and
# says so plainly when no recogniser is present.
cat > "$pkgdir/DEBIAN/control" <<EOF
Package: bandsaunter
Version: ${version}-${revision}
Section: hamradio
Priority: optional
Architecture: ${arch}
Depends: python3 (>= 3.10), python3-numpy, python3-scipy, python3-rich,
python3-yaml, librtlsdr0
Recommends: espeak-ng
Suggests: rtl-sdr
Maintainer: bandsaunter
Installed-Size: $(du -ks "$pkgdir" | cut -f1)
Description: signal scanner and recorder for RTL-SDR receivers
Sweeps any set of frequency ranges, or presets from a built-in US band plan,
records what it finds and works out what kind of signal it was.
.
Captures are kept only if they carry voice, decodable CW or an identified
digital keying scheme, so static and interference are discarded rather than
filling the disk. CW is decoded to text, and speech can be transcribed when
a recogniser is installed.
EOF
cat > "$pkgdir/DEBIAN/postinst" <<'EOF'
#!/bin/sh
set -e
if [ "$1" = configure ]; then
# The DVB-T driver claims the dongle on sight and has to be kept off it.
if [ ! -e /etc/modprobe.d/blacklist-rtlsdr.conf ]; then
echo 'blacklist dvb_usb_rtl28xxu' > /etc/modprobe.d/blacklist-rtlsdr.conf
echo 'bandsaunter: blacklisted dvb_usb_rtl28xxu; unplug and replug the'
echo ' receiver, or run: sudo rmmod dvb_usb_rtl28xxu'
fi
fi
exit 0
EOF
chmod 755 "$pkgdir/DEBIAN/postinst"
cat > "$pkgdir/DEBIAN/prerm" <<'EOF'
#!/bin/sh
set -e
if [ "$1" = remove ] || [ "$1" = purge ]; then
rm -f /etc/modprobe.d/blacklist-rtlsdr.conf
fi
exit 0
EOF
chmod 755 "$pkgdir/DEBIAN/prerm"
out=${1:-$here/dist}
mkdir -p "$out"
fakeroot dpkg-deb --build "$pkgdir" "$out" >/dev/null
echo "$out/bandsaunter_${version}-${revision}_${arch}.deb"