aboutsummaryrefslogtreecommitdiffstats
path: root/packaging/stage.sh
blob: e53310fae3fd3e3355d1aba1470b97bbdc7fe9b1 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
#!/usr/bin/env bash
# stage.sh <stage-dir> <version> <bin-name> <cargo-bin>
#
# Assembles the exact tree that gets tarred up and shipped. Layout:
#
#   <pkg>/
#     install.sh              installer that runs on the target machine
#     VERSION
#     bin/sl0ppij             the multiplexer
#     bin/pir                 session-resume helper
#     libexec/bun             pinned runtime
#     libexec/sl0ppi.js       the CLI, bundled to one file
#     libexec/pi/             pinned agent + deps
#     share/sl0ppij/config.kdl
#     share/sl0ppij/layouts/  share/sl0ppij/themes/  share/sl0ppij/plugins/
#     share/pi-ext/           extensions installed into the user's pi dir
#
# bin/pi and bin/sl0ppi are NOT staged: the installer generates them as wrappers,
# because they must point at wherever libexec landed.
set -euo pipefail

STAGE="${1:?stage dir}"
VERSION="${2:?version}"
BIN_NAME="${3:?installed binary name}"
CARGO_BIN="${4:?cargo binary name}"

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
VENDOR="$ROOT/vendor/cache"
BUN_VERSION="$(awk -F'= ' '/^BUN_VERSION/{print $2}' "$ROOT/Makefile" | tr -d ' ')"
PI_VERSION="$(awk -F'= ' '/^PI_VERSION/{print $2}' "$ROOT/Makefile" | tr -d ' ')"

log() { printf '\033[36m==>\033[0m %s\n' "$*"; }
need() { [ -e "$1" ] || { echo "stage: missing $1 -- run 'make $2' first" >&2; exit 1; }; }

rm -rf "$STAGE"
mkdir -p "$STAGE"/{bin,libexec,share/sl0ppij/{layouts,themes,plugins},share/pi-ext}

# --- the multiplexer -------------------------------------------------------
# Built for an explicit target triple (static musl by default) so the artifact
# does not inherit the build box's glibc.
TARGET="${SL0PPI_TARGET:-x86_64-unknown-linux-musl}"
FORK_BIN="$ROOT/sl0ppij/target/$TARGET/release/$CARGO_BIN"
need "$FORK_BIN" build
install -m755 "$FORK_BIN" "$STAGE/bin/$BIN_NAME"

if ldd "$STAGE/bin/$BIN_NAME" >/dev/null 2>&1; then
    echo "stage: WARNING $BIN_NAME is dynamically linked; it will only run where" >&2
    echo "stage:         this box's libc version (or newer) is present." >&2
else
    log "$BIN_NAME is statically linked (no libc dependency)"
fi

# --- wasm plugins ----------------------------------------------------------
# Both are load-bearing for the shipped config: config.kdl binds pane-finder,
# and layouts/default.kdl replaces the stock tab-bar+status-bar with zjstatus.
PANE_FINDER="$ROOT/sl0ppij/target/wasm32-wasip1/release/zj-pane-finder.wasm"
need "$PANE_FINDER" plugins
install -m644 "$PANE_FINDER" "$STAGE/share/sl0ppij/plugins/pane-finder.wasm"

ZJSTATUS="$ROOT/sl0pstatus/target/wasm32-wasip1/release/zjstatus.wasm"
need "$ZJSTATUS" plugins
install -m644 "$ZJSTATUS" "$STAGE/share/sl0ppij/plugins/zjstatus.wasm"

# --- opinionated config ----------------------------------------------------
install -m644 "$ROOT/config/config.kdl"          "$STAGE/share/sl0ppij/config.kdl"
install -m644 "$ROOT/config/layouts/"*.kdl       "$STAGE/share/sl0ppij/layouts/"
install -m644 "$ROOT/config/themes/"*.kdl        "$STAGE/share/sl0ppij/themes/"
install -m644 "$ROOT/config/answers.example.md"  "$STAGE/share/sl0ppij/answers.example.md"

# --- pi extensions ---------------------------------------------------------
# Mirrors pi-ext/install.sh's exclude policy: dev-only extensions do not ship.
EXCLUDE=(sixel-images.ts)
shopt -s nullglob
for f in "$ROOT/pi-ext/"*.ts; do
    base="$(basename "$f")"
    skip=""
    for x in "${EXCLUDE[@]}"; do [ "$base" = "$x" ] && skip=1; done
    [ -n "$skip" ] && { log "excluded (dev-only) $base"; continue; }
    install -m644 "$f" "$STAGE/share/pi-ext/$base"
done
shopt -u nullglob
install -m755 "$ROOT/pi-ext/scripts/pi-resume" "$STAGE/bin/pir"

# --- the orchestrator -------------------------------------------------------
CLI_BUNDLE="$ROOT/cli/dist/sl0ppi.js"
need "$CLI_BUNDLE" cli
install -m644 "$CLI_BUNDLE" "$STAGE/libexec/sl0ppi.js"

# --- vendored runtime + agent ----------------------------------------------
need "$VENDOR/bun-$BUN_VERSION/bun" vendor
need "$VENDOR/pi-$PI_VERSION/node_modules" vendor
install -m755 "$VENDOR/bun-$BUN_VERSION/bun" "$STAGE/libexec/bun"
cp -a "$VENDOR/pi-$PI_VERSION/node_modules" "$STAGE/libexec/pi"

# --- installer + metadata --------------------------------------------------
install -m755 "$ROOT/packaging/install.sh" "$STAGE/install.sh"
echo "$VERSION" > "$STAGE/VERSION"
{
    echo "sl0ppi $VERSION"
    echo "sl0ppij $(grep -m1 '^version = ' "$ROOT/sl0ppij/Cargo.toml" | cut -d'"' -f2)"
    echo "sl0pstatus $(grep -m1 '^version = ' "$ROOT/sl0pstatus/Cargo.toml" | cut -d'"' -f2)"
    echo "pi $PI_VERSION"
    echo "bun $BUN_VERSION"
} > "$STAGE/MANIFEST"

log "staged $(du -sh "$STAGE" | cut -f1) at $STAGE"