-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.sh
More file actions
executable file
·210 lines (194 loc) · 11.5 KB
/
Copy pathinstall.sh
File metadata and controls
executable file
·210 lines (194 loc) · 11.5 KB
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#!/usr/bin/env bash
# vinary-viewer installer (v0.2 — a standalone ClojureScript / Electron application, inspired by vmd).
#
# • npm install + shadow-cljs release (builds the GUI dist/main/main.js + the terminal dist/cli, dist/tui)
# • installs the `vv`/`vinary-viewer` launcher into $BIN (default ~/.local/bin) — one command, three modes:
# vv [--gui] files… GUI (default) vv --cli file terminal render vv --tui file terminal viewer
# • migrates off the v0.1.0 vmd-patching tool (advisory — see below)
#
# Idempotent + re-runnable. Override with BIN=/some/dir and/or VV_BUILD=compile ./install.sh
set -euo pipefail
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BIN="${BIN:-$HOME/.local/bin}"
# 'release' = optimized production build (:simple optimization — strips devtools + minifies; NOT
# :advanced, whose property-renaming breaks the re-frame / DataScript / remark interop). 'compile' = dev.
VV_BUILD="${VV_BUILD:-release}"
echo "==> vinary-viewer install (repo: $REPO)"
command -v npx >/dev/null 2>&1 || { echo "error: node/npx not found on PATH" >&2; exit 1; }
echo "==> npm install"
# The Rholang grammar ships in the private @f1r3fly-io/tree-sitter-rholang-js-with-comments package (served from
# the GitHub Packages npm registry — needs ~/.npmrc auth + a GitHub PAT). It is an OPTIONAL dependency, so a
# missing/misconfigured token normally just warns and npm continues. Should a specific registry/auth error (e.g.
# an invalid-PAT 401) still be fatal, retry ONCE without optional deps so the core install proceeds; the skipped
# Rholang grammar (and how to enable it) is reported after the grammar sync below.
if ! ( cd "$REPO" && npm install --no-fund --no-audit ); then
echo " (warn: npm install failed — often the private @f1r3fly-io Rholang grammar needs a GitHub PAT;"
echo " retrying without optional dependencies so the core install can proceed…)"
( cd "$REPO" && npm install --no-fund --no-audit --omit=optional )
fi
echo "==> syncing terminal-renderer assets (tree-sitter grammars + graphics wasm)"
# grammars/graphics wasm are runtime assets shared by the GUI source-preview and the cli/tui renderers, so
# sync them ONCE here — not once per :cli and again per :tui (the release:cli / release:tui npm scripts each
# prepend grammars:sync + graphics:sync, which is why a plain install re-fetched every grammar twice).
# --skip-existing leaves already-built grammars untouched (fast, idempotent re-installs; no source.json churn);
# the sync is quiet by default (pass --verbose to grammars:sync to see the per-repo git/tree-sitter output).
# --allow-failures: a grammar that can't be downloaded/built (a transient network hiccup, or the auth/local-gated
# rholang/metta) is SKIPPED rather than aborting the install — skipped grammars are reported just below. Run
# graphics:sync on its own line (not chained with &&) so the graphics wasm still syncs even if a grammar failed.
( cd "$REPO" && npm run grammars:sync -- --skip-existing --allow-failures )
( cd "$REPO" && npm run graphics:sync )
# Report skipped grammars and — for the auth/local-gated ones — exactly how to enable them. sync-grammars.mjs
# writes the outcome to .cache/tree-sitter-grammars/last-sync.json (gitignored); read the failed ids from it.
SYNC_REPORT="$REPO/.cache/tree-sitter-grammars/last-sync.json"
FAILED_IDS="$(node -e 'const fs=require("fs");try{const s=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));process.stdout.write((s.failed||[]).map(f=>f.id).join(" "))}catch(_){}' "$SYNC_REPORT" 2>/dev/null || true)"
if [ -n "$FAILED_IDS" ]; then
echo ""
echo "==> NOTE: some tree-sitter grammars were skipped (the app still works without them — those file"
echo " types just won't get syntax highlighting): $FAILED_IDS"
echo " Re-run ./install.sh to retry them (already-built grammars are left untouched)."
case " $FAILED_IDS " in
*" rholang "*)
echo ""
echo " • rholang — its grammar ships in the PRIVATE npm package"
echo " @f1r3fly-io/tree-sitter-rholang-js-with-comments (GitHub Packages registry),"
echo " which needs a GitHub Personal Access Token. To enable it:"
echo " 1. Create a classic PAT with the 'read:packages' scope:"
echo " https://github.com/settings/tokens/new?scopes=read:packages"
echo " 2. Add these two lines to ~/.npmrc:"
echo " @f1r3fly-io:registry=https://npm.pkg.github.com"
echo " //npm.pkg.github.com/:_authToken=YOUR_GITHUB_PAT"
echo " 3. Re-run ./install.sh"
;;
esac
case " $FAILED_IDS " in
*" metta "*)
echo ""
echo " • metta — its grammar is built from the sibling checkout ../MeTTa-Compiler. To enable it:"
echo " git clone https://github.com/F1R3FLY-io/MeTTa-Compiler ../MeTTa-Compiler"
echo " (so ../MeTTa-Compiler/tree-sitter-metta exists), then re-run ./install.sh"
;;
esac
fi
echo "==> building GUI ($VV_BUILD)"
( cd "$REPO" && npx shadow-cljs "$VV_BUILD" main renderer )
echo "==> building terminal tools ($VV_BUILD cli, $VV_BUILD tui)"
# build the :cli/:tui targets directly (one shadow-cljs run, no redundant re-sync — the assets are ready above)
( cd "$REPO" && npx shadow-cljs "$VV_BUILD" cli tui )
echo "==> installing launcher into $BIN"
mkdir -p "$BIN"
VERSION="$(node -p "require('$REPO/package.json').version" 2>/dev/null || echo unknown)"
# vinary-viewer is one command with three modes: GUI (default) | --cli | --tui. $REPO and $VERSION are baked in;
# runtime variables (\$@, \${1:-}, \$REPO) are escaped so they stay literal in the generated launcher.
cat > "$BIN/vinary-viewer" <<EOF
#!/usr/bin/env bash
# vinary-viewer launcher (generated by install.sh) — GUI (default) · --cli · --tui
REPO="$REPO"
case "\${1:-}" in
--cli) shift; exec node "\$REPO/dist/cli/vv-cli.js" "\$@" ;;
--tui) shift; exec node "\$REPO/dist/tui/vv-tui.js" "\$@" ;;
--gui) shift ;;
--no-daemon) shift; exec "\$REPO/node_modules/.bin/electron" "\$REPO" "\$@" ;; # fresh process, bypass the daemon
-h|--help) cat <<'USAGE'
vinary-viewer — preview Markdown, PDFs, images, diagrams & source
Usage:
vv [--gui] [files…] open in the desktop GUI (default), one tab per file/URL
vv --cli <file> render a document to the terminal (pipe-friendly: vv --cli x.md | less)
vv --tui <file> interactively page a document (scroll · / find · t contents · q quit)
vv --no-daemon [files…] open in a fresh process (do not reuse the warm daemon)
vv --help | --version
Mode options: vv --cli --help · vv --tui --help
USAGE
exit 0 ;;
-V|--version) echo "vinary-viewer $VERSION"; exit 0 ;;
esac
# GUI (default): hand the files to the warm resident process over its Unix socket (a new window opens with no
# cold start). The client is systemd-INDEPENDENT — it starts the daemon itself if none is running. systemd, if
# present, merely keeps a --daemon warm at login (see the user unit below). --no-daemon (above) bypasses all this.
exec node "\$REPO/scripts/vv-open.mjs" "\$@"
EOF
chmod +x "$BIN/vinary-viewer"
ln -sf "$BIN/vinary-viewer" "$BIN/vv"
echo " vv [files…] -> GUI (default)"
echo " vv --cli FILE -> render to the terminal"
echo " vv --tui FILE -> interactive terminal viewer"
# ---- desktop entry + hicolor icons (Linux application-menu integration) --------------------------
# Registers the app in the desktop launcher with its logo, from the vendored set in resources/icons/
# (the Full-Automaton mark). macOS/Windows show the icon at runtime via the window / dock (core.cljs),
# so this XDG step is Linux-only; the cache refreshes are optional (guarded, non-fatal).
if [ "$(uname -s)" = "Linux" ]; then
DATA_HOME="${XDG_DATA_HOME:-$HOME/.local/share}"
ICONS="$DATA_HOME/icons/hicolor"
APPS="$DATA_HOME/applications"
echo "==> installing desktop entry + icons"
for sz in 16 32 48 64 128 256 512; do
case $sz in 16) src="favicon-16.png" ;; *) src="appicon-$sz.png" ;; esac
install -Dm644 "$REPO/resources/icons/$src" "$ICONS/${sz}x${sz}/apps/vinary-viewer.png"
done
install -Dm644 "$REPO/resources/icons/vinary-viewer-appicon.svg" "$ICONS/scalable/apps/vinary-viewer.svg"
mkdir -p "$APPS"
cat > "$APPS/vinary-viewer.desktop" <<EOF
[Desktop Entry]
Type=Application
Version=1.0
Name=Vinary Viewer
GenericName=Document Viewer
Comment=Fast Markdown / document / source viewer
Exec=$BIN/vinary-viewer %F
Icon=vinary-viewer
Terminal=false
Categories=Utility;Viewer;TextTools;
StartupWMClass=vinary-viewer
StartupNotify=true
EOF
update-desktop-database "$APPS" 2>/dev/null || true
gtk-update-icon-cache -f -t "$ICONS" 2>/dev/null || true
echo " desktop entry: $APPS/vinary-viewer.desktop"
echo " hicolor icons: $ICONS/{16x16..512x512,scalable}/apps/vinary-viewer.*"
fi
# ---- optional: a systemd user service to keep the warm daemon up at login ------------------------
# The daemon does NOT require systemd (the `vv` launcher starts it over the socket on demand); this unit just
# keeps it warm from login on systemd systems so even the first open is instant. On non-systemd systems this is
# simply skipped — nothing else changes.
if command -v systemctl >/dev/null 2>&1; then
UNIT_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/systemd/user"
mkdir -p "$UNIT_DIR"
cat > "$UNIT_DIR/vinary-viewer.service" <<EOF
[Unit]
Description=vinary-viewer warm document-viewer daemon
After=graphical-session.target
PartOf=graphical-session.target
[Service]
Type=simple
ExecStart=$REPO/node_modules/.bin/electron $REPO --daemon
Restart=on-failure
RestartSec=2
[Install]
WantedBy=graphical-session.target
EOF
systemctl --user daemon-reload 2>/dev/null || true
# Enable at login AND (re)start now onto the freshly-built dist/. `restart` (not `enable --now`) is the key:
# `--now` is a no-op on an ALREADY-running daemon, so a re-install would otherwise leave the OLD dist/main
# loaded (and its warm pool windows on the OLD renderer) until the next manual restart. `restart` starts the
# daemon if it's stopped and reloads it if it's running — so a re-install always ends on the new build.
if systemctl --user enable vinary-viewer.service 2>/dev/null \
&& systemctl --user restart vinary-viewer.service 2>/dev/null; then
echo " systemd: vinary-viewer.service enabled + (re)started on the new build"
else
echo " systemd: unit installed; start with 'systemctl --user enable --now vinary-viewer.service'"
fi
else
echo " (no systemd — the daemon starts on demand via 'vv'; no service needed)"
fi
# ---- migrate off v0.1.0 (the vmd-patching tool) -------------------------------------------------
# v0.1.0 patched the system `vmd` npm package, set ~/.vmdrc styles.extra, and installed a vmd() shell
# wrapper. This standalone app replaces all of that. We do NOT auto-edit your shell rc or the global
# vmd package; we detect the old install and tell you how to revert it. Your
# ~/.config/vinary-viewer/ (theme, keybindings.edn, grammars/) is preserved.
OLD_DEPLOY="$HOME/.local/share/vinary-viewer"
if [ -e "$OLD_DEPLOY/sidebar.js" ] || grep -qs 'vmd()' "$HOME/.bashrc" "$HOME/.zshrc" 2>/dev/null; then
echo "==> NOTE: a v0.1.0 vmd-patching install was detected. To fully revert it, run:"
echo " git -C \"$REPO\" show v0.1.0:uninstall.sh | bash"
echo " and remove any 'vmd()' wrapper block from your ~/.bashrc / ~/.zshrc."
fi
case ":$PATH:" in *":$BIN:"*) : ;; *) echo "==> NOTE: add $BIN to your PATH" ;; esac
echo "==> done. Try: vv README.md · vv --cli README.md | less · vv --tui README.md · vv --help"