-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbootstrap.sh
More file actions
executable file
·141 lines (124 loc) · 6.79 KB
/
Copy pathbootstrap.sh
File metadata and controls
executable file
·141 lines (124 loc) · 6.79 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
#!/usr/bin/env bash
#
# LevelCode M0 bootstrap — clone a pinned Code-OSS, apply LevelCode branding, install deps.
# Safe to re-run. Run this on your Mac (the build that produces a .app must be native).
#
# Usage:
# ./scripts/bootstrap.sh # uses pinned tag below
# VSCODE_TAG=1.124.0 ./scripts/bootstrap.sh # override the tag
#
set -euo pipefail
# --- config -----------------------------------------------------------------
# Pin to a known-good upstream tag. Override with VSCODE_TAG=... if this tag
# ever 404s or you want to track a newer release.
VSCODE_TAG="${VSCODE_TAG:-1.126.0}"
REPO_URL="https://github.com/microsoft/vscode.git"
# --- paths ------------------------------------------------------------------
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
VSCODE_DIR="$ROOT_DIR/vscode"
bold() { printf "\033[1m%s\033[0m\n" "$*"; }
info() { printf "\033[36m[bootstrap]\033[0m %s\n" "$*"; }
err() { printf "\033[31m[bootstrap] %s\033[0m\n" "$*" >&2; }
# --- preflight --------------------------------------------------------------
bold "LevelCode bootstrap — Code-OSS @ ${VSCODE_TAG}"
command -v git >/dev/null || { err "git not found"; exit 1; }
command -v node >/dev/null || { err "node not found — install Node 24 (nvm/nodenv recommended)"; exit 1; }
# Node: Code-OSS pins an exact version in .nvmrc (checked again after clone).
# Up front we require at least Node 22 — older majors fail to compile native modules.
NODE_MAJOR="$(node -p 'process.versions.node.split(".")[0]')"
if [ "$NODE_MAJOR" -lt 22 ]; then
err "Node $(node -v) detected; this Code-OSS tag needs Node 22+ (it pins 24.x in .nvmrc)."
err " nodenv: nodenv install 24.15.0 && nodenv local 24.15.0"
err " nvm: nvm install 24 && nvm use 24"
exit 1
fi
# Arch consistency: native modules (esbuild, tsgo) are arch-specific. If Node's arch
# doesn't match the host CPU, you're in Rosetta and the install will produce x64
# binaries that crash under arm64 (or vice versa). Catch it before the slow npm ci.
HOST_ARCH="$(uname -m)" # arm64 or x86_64
case "$HOST_ARCH" in
arm64) EXPECT_NODE_ARCH="arm64" ;;
x86_64) EXPECT_NODE_ARCH="x64" ;;
*) EXPECT_NODE_ARCH="" ;;
esac
NODE_ARCH="$(node -p 'process.arch')"
if [ -n "$EXPECT_NODE_ARCH" ] && [ "$NODE_ARCH" != "$EXPECT_NODE_ARCH" ]; then
err "Architecture mismatch: host is ${HOST_ARCH} but Node reports arch '${NODE_ARCH}'."
err "You're almost certainly in a Rosetta shell. Native modules will be built for the"
err "wrong arch and crash later (esbuild/tsgo 'wrong platform' or 'exited with code unknown')."
err "Fix: open a NATIVE arm64 Terminal (Get Info > uncheck 'Open using Rosetta'),"
err " reinstall Node there (nodenv uninstall -f ${WANT_NODE:-24.15.0} && nodenv install ${WANT_NODE:-24.15.0}),"
err " then re-run this script. 'arch' must print arm64 and 'node -p process.arch' must match."
exit 1
fi
info "Arch OK: host ${HOST_ARCH} / node ${NODE_ARCH} ✓"
# Python: node-gyp's bundled gyp uses the := walrus operator -> needs Python >= 3.8.
# Honor a PYTHON override (npm/node-gyp read it too).
PYBIN="${PYTHON:-python3}"
if ! command -v "$PYBIN" >/dev/null; then
err "python3 not found — node-gyp needs it. On macOS: 'xcode-select --install'."
exit 1
fi
PY_OK="$("$PYBIN" -c 'import sys; print(1 if sys.version_info[:2] >= (3,8) else 0)' 2>/dev/null || echo 0)"
if [ "$PY_OK" != "1" ]; then
err "Active python is $("$PYBIN" --version 2>&1) — node-gyp needs Python >= 3.8."
err "You appear to use pyenv; pick a newer interpreter, e.g.:"
err " pyenv install 3.12.4 && pyenv local 3.12.4 # in this folder"
err " # or point this build at the system python without changing pyenv:"
err " PYTHON=/usr/bin/python3 ./scripts/bootstrap.sh"
exit 1
fi
export PYTHON="$PYBIN" # node-gyp picks this up for the npm ci step
# --- clone (shallow, pinned) ------------------------------------------------
if [ -d "$VSCODE_DIR/.git" ]; then
info "vscode/ already exists — fetching tag ${VSCODE_TAG}"
git -C "$VSCODE_DIR" fetch --depth 1 origin "refs/tags/${VSCODE_TAG}:refs/tags/${VSCODE_TAG}"
git -C "$VSCODE_DIR" checkout -f "tags/${VSCODE_TAG}"
else
info "Cloning Code-OSS (shallow) at ${VSCODE_TAG}"
git clone --depth 1 --branch "${VSCODE_TAG}" "$REPO_URL" "$VSCODE_DIR"
fi
# Record what we pinned to (handy for rebases later).
echo "${VSCODE_TAG}" > "$ROOT_DIR/.vscode-pinned-tag"
# Exact Node check against the checkout's .nvmrc (more precise than the major check).
if [ -f "$VSCODE_DIR/.nvmrc" ]; then
WANT_NODE="$(tr -d '[:space:]' < "$VSCODE_DIR/.nvmrc")"
WANT_MAJOR="${WANT_NODE%%.*}"
if [ "$NODE_MAJOR" != "$WANT_MAJOR" ]; then
err "This tag's .nvmrc wants Node ${WANT_NODE} (major ${WANT_MAJOR}); you have $(node -v)."
err " nodenv install ${WANT_NODE} && nodenv local ${WANT_NODE}"
err " # then re-run ./scripts/bootstrap.sh (downloads are cached, so it's fast)"
exit 1
fi
info "Node $(node -v) matches .nvmrc (${WANT_NODE}) ✓"
fi
# --- apply branding + extensions --------------------------------------------
info "Applying LevelCode branding overlay + installing extensions"
node "$SCRIPT_DIR/apply-branding.mjs" "$VSCODE_DIR"
# --- apply core source patches ----------------------------------------------
# A fresh checkout is pristine; these patches re-apply our [LevelCode] core edits.
if [ -f "$ROOT_DIR/patches/levelcode-core.patch" ]; then
info "Applying LevelCode core patches"
if ! git -C "$VSCODE_DIR" apply --3way "$ROOT_DIR/patches/levelcode-core.patch"; then
err "Core patch failed to apply (upstream likely changed these files on tag ${VSCODE_TAG})."
err "Re-create it after resolving — see docs/CORE-PATCHES.md."
exit 1
fi
fi
# Content-based de-branding of user-visible "VS Code" strings (settings, notifications, menu labels).
# Kept OUT of the line-anchored patch above on purpose: a content match survives upstream line movement
# and no-ops if a string is gone, so it's far more durable across Code-OSS bumps. Warns (never fails) on
# drift — see scripts/de-brand.mjs + docs/CORE-PATCHES.md.
info "De-branding user-visible VS Code strings"
node "$ROOT_DIR/scripts/de-brand.mjs" "$VSCODE_DIR"
# --- install deps -----------------------------------------------------------
info "Installing dependencies (this is the slow part — several minutes)"
info "Using Python: $("$PYTHON" --version 2>&1) at $(command -v "$PYTHON")"
( cd "$VSCODE_DIR" && npm ci --python="$PYTHON" )
# NOTE: proprietary Copilot/MS packages are stripped from the BUILT APP by build-macos.sh — NOT here.
# The source checkout keeps the real packages so dev-mode typecheck (run-dev.sh → tsgo) compiles.
bold "Bootstrap complete."
echo "Next:"
echo " ./scripts/run-dev.sh # launch LevelCode from source to sanity-check"
echo " ./scripts/build-macos.sh # produce LevelCode.app"