Add Android client, packaging, Makefile entrypoint and handover docs

Why: the set has to be installable and publishable, not just buildable, and
the next person needs the reasoning, not only the code.

What:
- android/: Kotlin client with no third-party dependencies. A
  DocumentsProvider publishes the mirrored databases to every file picker, so
  KeePassDX opens them as ordinary documents; closing a file it wrote
  triggers a sync. A foreground service holds the event stream open.
  Mirror.decide transcribes the Go merge table, so both platforms resolve a
  conflict identically.
- Makefile as the single entrypoint, with file targets so only what changed
  is rebuilt: host and cross builds, both .deb packages, the macOS DMG with
  its /Applications symlink, the Windows zip, the APK under its F-Droid
  publishing name, and manual-only android-publish.
- versions.mk holds one version per platform plus the Android versionCode;
  `make bump` and `make changelog` move them. Debian changelog is tracked.
- systemd units (hardened system unit for the server, user unit for the
  agent), macOS bundle and launch agent, Windows Task Scheduler job.
- docs/HANDOVER.md on architecture and every decision that shaped it,
  docs/PROTOCOL.md for the API, README for the quick start.

Proved: make check and make test-race both pass; built both .deb packages and
inspected their contents, built the Windows zip, cross-compiled all five
desktop targets, and exercised make bump. The Android module is written but
not compiled: no JDK or Android SDK in this environment, which HANDOVER.md
states plainly.
This commit is contained in:
2026-10-29 16:26:33 +01:00
parent 4d0d53ff04
commit 0e83acb9b1
40 changed files with 2563 additions and 24 deletions
+83
View File
@@ -0,0 +1,83 @@
#!/bin/sh
# Build one Debian package.
# build-deb.sh <client|server> <version> <arch> <output.deb>
set -eu
kind=$1
version=$2
arch=$3
out=$4
root=$(cd "$(dirname "$0")/.." && pwd)
stage=$root/build/deb-$kind-$arch
rm -rf "$stage"
case $kind in
client)
pkg=keeporg
binary=keeporg
mkdir -p "$stage/usr/bin" "$stage/usr/lib/systemd/user"
install -m 0755 "$root/build/linux-$arch/keeporg" "$stage/usr/bin/keeporg"
install -m 0644 "$root/packaging/systemd/keeporg.service" \
"$stage/usr/lib/systemd/user/keeporg.service"
;;
server)
pkg=keeporgd
binary=keeporgd
mkdir -p "$stage/usr/bin" "$stage/usr/lib/systemd/system" "$stage/etc/keeporg"
install -m 0755 "$root/build/linux-$arch/keeporgd" "$stage/usr/bin/keeporgd"
install -m 0644 "$root/packaging/systemd/keeporgd.service" \
"$stage/usr/lib/systemd/system/keeporgd.service"
"$root/build/linux-$arch/keeporgd" -write-config "$stage/etc/keeporg/server.json" >/dev/null
chmod 0640 "$stage/etc/keeporg/server.json"
;;
*)
echo "build-deb.sh: unknown package kind $kind" >&2
exit 2
;;
esac
mkdir -p "$stage/DEBIAN" "$stage/usr/share/doc/$pkg"
sed -e "s/@VERSION@/$version/" -e "s/@ARCH@/$arch/" \
"$root/packaging/deb/$kind/control.in" > "$stage/DEBIAN/control"
install -m 0644 "$root/packaging/deb/copyright" "$stage/usr/share/doc/$pkg/copyright"
gzip -9nc "$root/packaging/deb/changelog" > "$stage/usr/share/doc/$pkg/changelog.Debian.gz"
chmod 0644 "$stage/usr/share/doc/$pkg/changelog.Debian.gz"
if [ "$kind" = server ]; then
cat > "$stage/DEBIAN/conffiles" <<'CONF'
/etc/keeporg/server.json
CONF
cat > "$stage/DEBIAN/postinst" <<'POST'
#!/bin/sh
set -e
if [ "$1" = configure ]; then
if ! getent passwd keeporg >/dev/null; then
adduser --system --group --home /var/lib/keeporg \
--gecos "KeepOrg synchronization server" keeporg
fi
install -d -o keeporg -g keeporg -m 0700 /var/lib/keeporg
chgrp keeporg /etc/keeporg/server.json || true
chmod 0640 /etc/keeporg/server.json || true
if [ -d /run/systemd/system ]; then
systemctl daemon-reload || true
echo "keeporgd: edit /etc/keeporg/server.json, then" \
"systemctl enable --now keeporgd" >&2
fi
fi
exit 0
POST
cat > "$stage/DEBIAN/prerm" <<'PRERM'
#!/bin/sh
set -e
if [ "$1" = remove ] && [ -d /run/systemd/system ]; then
systemctl stop keeporgd || true
fi
exit 0
PRERM
chmod 0755 "$stage/DEBIAN/postinst" "$stage/DEBIAN/prerm"
fi
mkdir -p "$(dirname "$out")"
fakeroot dpkg-deb --root-owner-group --build "$stage" "$out" >/dev/null
printf 'built %s (%s %s %s)\n' "$out" "$binary" "$version" "$arch"