summaryrefslogtreecommitdiffstats
path: root/packaging/build
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-14 22:20:15 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-14 22:20:15 +0200
commit422647e7898b8df67cd11f8fb060aec23dec84aa (patch)
tree7ecca0e8df1bc8a7d26cf4b471bd44906dd9cfd1 /packaging/build
parent28c88908b88c58cba4de08710f6bb268ede02d57 (diff)
downloadmeshbay-422647e7898b8df67cd11f8fb060aec23dec84aa.tar.gz
feat(cli): meshbay-cli, a command-line client for members
Signs in to the hub, lists the account's groups and their folders, and downloads and uploads files directly with each group's node, end-to-end encrypted. With no argument it opens a two-pane interactive mode (Textual). Session and device keys are kept encrypted under the system's key storage, or a 0600 key file where there is none; node keys are pinned at first contact; a new machine links as a device. Packaged on its own on Linux (deb and rpm, on meshbay-common's venv, with a man page generated from the parser) and frozen next to meshbay-node in the full Windows installer, not the light one, with a self-test the build runs. client/keys.py ports keyderive.js and is LGPL like it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packaging/build')
-rwxr-xr-xpackaging/build/build-cli.sh82
-rwxr-xr-xpackaging/build/build-common.sh19
-rwxr-xr-xpackaging/build/build-packages.sh16
3 files changed, 109 insertions, 8 deletions
diff --git a/packaging/build/build-cli.sh b/packaging/build/build-cli.sh
new file mode 100755
index 0000000..b697f10
--- /dev/null
+++ b/packaging/build/build-cli.sh
@@ -0,0 +1,82 @@
+#!/usr/bin/env bash
+# Build the meshbay-cli package: the command-line client, and the Python
+# packages only it needs, on top of meshbay-common.
+#
+# Expects build-common.sh to have run first: it installed the CLI last, after
+# listing the servers' packages in servers-site.txt and servers-bin.txt, so
+# everything not in those lists is the CLI's and moves here.
+#
+# Usage: ./build-cli.sh [staging-dir]
+set -euo pipefail
+
+REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
+STAGING="${1:-/tmp/meshbay-build}"
+COMMON_ROOT="$STAGING/meshbay-common-root"
+ROOT="$STAGING/meshbay-cli-root"
+
+VENV="$COMMON_ROOT/opt/meshbay-common/venv"
+PYVER=$(basename "$VENV"/lib/python3.*)
+SITE="$VENV/lib/$PYVER/site-packages"
+
+VERSION=$(python3 -c "
+import tomllib, pathlib
+p = pathlib.Path('$REPO/packages/meshbay-cli/pyproject.toml')
+print(tomllib.loads(p.read_text())['project']['version'])
+")
+echo "==> meshbay-cli $VERSION"
+
+[ -d "$VENV" ] || { echo "!! shared venv not found — run build-common.sh first" >&2; exit 1; }
+[ -f "$STAGING/servers-site.txt" ] || {
+ echo "!! $STAGING/servers-site.txt missing — run build-common.sh first" >&2; exit 1; }
+[ -d "$SITE/meshbay_cli" ] || {
+ echo "!! meshbay_cli not in the shared venv — was build-cli.sh already run?" >&2; exit 1; }
+
+rm -rf "$ROOT"
+mkdir -p "$ROOT/opt/meshbay-cli"
+
+# Run from the staged venv with no bytecode written: whatever it imports
+# would otherwise leave __pycache__ in files other packages own.
+run_venv() { PYTHONDONTWRITEBYTECODE=1 "$VENV/bin/python" "$@"; }
+
+# --- Before moving anything: the notices and the man page -----------------
+# Both need the CLI importable, which it is only where build-common.sh put it.
+echo " writing THIRD-PARTY-NOTICES.txt"
+run_venv "$REPO/packaging/third_party_notices.py" \
+ -o "$ROOT/opt/meshbay-cli/THIRD-PARTY-NOTICES.txt" meshbay-cli
+
+echo " generating the man page"
+mkdir -p "$ROOT/usr/share/man/man1"
+run_venv -m meshbay_cli.manpage | gzip -9n > "$ROOT/usr/share/man/man1/meshbay-cli.1.gz"
+[ "$(gzip -dc "$ROOT/usr/share/man/man1/meshbay-cli.1.gz" | head -c 3)" = ".TH" ] || {
+ echo "!! the man page did not generate" >&2; exit 1; }
+
+# --- The CLI and its own dependencies, out of the common tree ---------------
+# MOVE (not copy), as build-hub.sh and build-node.sh do: dpkg/rpm then know
+# these files belong to meshbay-cli. The list is kept for the maintainer
+# scripts, which remove the bytecode compiled next to these files.
+CLI_SITE="$ROOT/opt/meshbay-common/venv/lib/$PYVER/site-packages"
+CLI_BIN="$ROOT/opt/meshbay-common/venv/bin"
+mkdir -p "$CLI_SITE" "$CLI_BIN"
+: > "$ROOT/opt/meshbay-cli/site-packages.list"
+while IFS= read -r entry; do
+ mv "$SITE/$entry" "$CLI_SITE/"
+ echo "$entry" >> "$ROOT/opt/meshbay-cli/site-packages.list"
+done < <(LC_ALL=C comm -13 "$STAGING/servers-site.txt" <(LC_ALL=C ls -1A "$SITE"))
+while IFS= read -r entry; do
+ mv "$VENV/bin/$entry" "$CLI_BIN/"
+done < <(LC_ALL=C comm -13 "$STAGING/servers-bin.txt" <(LC_ALL=C ls -1A "$VENV/bin"))
+echo " moved: $(tr '\n' ' ' < "$ROOT/opt/meshbay-cli/site-packages.list")"
+
+# Only the client is on PATH; the dependencies' own scripts (pygmentize,
+# keyring, ...) stay inside the venv.
+mkdir -p "$ROOT/usr/bin"
+ln -sf /opt/meshbay-common/venv/bin/meshbay-cli "$ROOT/usr/bin/meshbay-cli"
+
+find "$ROOT" -type d -name __pycache__ -exec rm -rf {} + 2>/dev/null || true
+
+# What the venv holds of this package, for the rpm spec's %files: the entries
+# differ with every dependency upgrade, so no list is kept by hand.
+( cd "$ROOT" && find opt/meshbay-common/venv/lib/*/site-packages opt/meshbay-common/venv/bin \
+ -mindepth 1 -maxdepth 1 | LC_ALL=C sort | sed 's|^|/|' ) > "$ROOT.files"
+
+echo "==> meshbay-cli staging ready at $ROOT"
diff --git a/packaging/build/build-common.sh b/packaging/build/build-common.sh
index 5f119c6..2010d1b 100755
--- a/packaging/build/build-common.sh
+++ b/packaging/build/build-common.sh
@@ -29,9 +29,9 @@ echo " creating venv at $VENV_BUILD"
python3 -m venv "$VENV_BUILD"
"$VENV_BUILD/bin/pip" install --upgrade pip wheel 2>&1 | tail -1
-# --- Build wheels for all three packages -----------------------------------
+# --- Build wheels for every package ----------------------------------------
echo " building wheels"
-for pkg in meshbay-common meshbay-hub meshbay-node; do
+for pkg in meshbay-common meshbay-hub meshbay-node meshbay-cli; do
"$VENV_BUILD/bin/pip" wheel \
--no-deps \
--wheel-dir "$WHEEL_DIR" \
@@ -44,6 +44,17 @@ echo " installing all packages + dependencies"
--find-links "$WHEEL_DIR" \
meshbay-common meshbay-hub meshbay-node 2>&1 | tail -3
+# The command-line client goes in last, after a list of what the servers need:
+# whatever its install adds is the CLI's alone, and build-cli.sh moves it into
+# the meshbay-cli package, so a server carries no Textual.
+SITE_BUILD=$(echo "$VENV_BUILD"/lib/python3.*/site-packages)
+LC_ALL=C ls -1A "$SITE_BUILD" > "$STAGING/servers-site.txt"
+LC_ALL=C ls -1A "$VENV_BUILD/bin" > "$STAGING/servers-bin.txt"
+echo " installing meshbay-cli + its own dependencies"
+"$VENV_BUILD/bin/pip" install \
+ --find-links "$WHEEL_DIR" \
+ meshbay-cli 2>&1 | tail -1
+
# --- Third-party notices: every package the venv ships, with its licence -------
echo " writing THIRD-PARTY-NOTICES.txt"
"$VENV_BUILD/bin/python" "$REPO/packaging/third_party_notices.py" \
@@ -64,7 +75,9 @@ for f in "$VENV_BUILD/bin"/*; do
[ -f "$f" ] || continue
[ -L "$f" ] && continue
head -1 "$f" | grep -q "^#!" || continue
- sed -i "1s|$ROOT||" "$f"
+ # Line 2 too: past 127 characters, pip writes a `#!/bin/sh` trampoline that
+ # names the interpreter on the next line.
+ sed -i "1,2s|$ROOT||" "$f"
done
sed -i "s|$ROOT||g" "$VENV_BUILD/pyvenv.cfg"
diff --git a/packaging/build/build-packages.sh b/packaging/build/build-packages.sh
index 8ca0e23..7bbf6b5 100755
--- a/packaging/build/build-packages.sh
+++ b/packaging/build/build-packages.sh
@@ -63,19 +63,23 @@ mkdir -p "$OUT"
# --- Step 1: Build staging trees ------------------------------------------
-echo "--- [1/4] meshbay-common (shared venv + all deps) ---"
+echo "--- [1/5] meshbay-common (shared venv + all deps) ---"
bash "$SCRIPT_DIR/build-common.sh" "$STAGING"
echo ""
-echo "--- [2/4] meshbay-hub ---"
+echo "--- [2/5] meshbay-hub ---"
bash "$SCRIPT_DIR/build-hub.sh" "$STAGING"
echo ""
-echo "--- [3/4] meshbay-node ---"
+echo "--- [3/5] meshbay-node ---"
bash "$SCRIPT_DIR/build-node.sh" "$STAGING"
echo ""
-echo "--- [4/4] meshbay-client ---"
+echo "--- [4/5] meshbay-cli ---"
+bash "$SCRIPT_DIR/build-cli.sh" "$STAGING"
+
+echo ""
+echo "--- [5/5] meshbay-client ---"
bash "$SCRIPT_DIR/build-client.sh" "$STAGING" $ARM64_FLAG
# --- Step 2: Package ------------------------------------------------------
@@ -143,6 +147,7 @@ if [ "$FORMAT" = "deb" ]; then
build_deb meshbay-common
build_deb meshbay-hub
build_deb meshbay-node
+ build_deb meshbay-cli
build_deb meshbay-client
elif [ "$FORMAT" = "rpm" ]; then
@@ -175,6 +180,7 @@ elif [ "$FORMAT" = "rpm" ]; then
build_rpm meshbay-common
build_rpm meshbay-hub
build_rpm meshbay-node
+ build_rpm meshbay-cli
build_rpm meshbay-client
fi
@@ -187,5 +193,5 @@ ls -lh "$OUT"/
echo ""
echo "Install order:"
echo " 1. meshbay-common"
-echo " 2. meshbay-hub and/or meshbay-node"
+echo " 2. meshbay-hub, meshbay-node and/or meshbay-cli"
echo " 3. meshbay-client"