esprit-cli 0.7.13 → 0.7.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/npm/postinstall.mjs +9 -0
- package/package.json +1 -1
- package/scripts/install.ps1 +33 -0
- package/scripts/install.sh +65 -0
package/npm/postinstall.mjs
CHANGED
|
@@ -14,10 +14,19 @@ const installerPath = path.resolve(
|
|
|
14
14
|
isWindows ? "install.ps1" : "install.sh"
|
|
15
15
|
);
|
|
16
16
|
|
|
17
|
+
const majorNode = Number.parseInt(process.versions.node.split(".")[0], 10);
|
|
18
|
+
if (!Number.isFinite(majorNode) || majorNode < 18) {
|
|
19
|
+
console.error(
|
|
20
|
+
`Node.js 18+ is required for esprit-cli npm install (detected ${process.versions.node}).`
|
|
21
|
+
);
|
|
22
|
+
process.exit(1);
|
|
23
|
+
}
|
|
24
|
+
|
|
17
25
|
const installEnv = {
|
|
18
26
|
...process.env,
|
|
19
27
|
// npm installs should be fast/predictable; sandbox image is pulled at first scan.
|
|
20
28
|
ESPRIT_SKIP_DOCKER_WARM: "1",
|
|
29
|
+
ESPRIT_INSTALL_CHANNEL: "npm",
|
|
21
30
|
};
|
|
22
31
|
|
|
23
32
|
const result = isWindows
|
package/package.json
CHANGED
package/scripts/install.ps1
CHANGED
|
@@ -27,6 +27,7 @@ $RUNTIME_DIR = Join-Path $INSTALL_ROOT 'runtime'
|
|
|
27
27
|
$VENV_DIR = Join-Path $INSTALL_ROOT 'venv'
|
|
28
28
|
$LAUNCHER_CMD = Join-Path $BIN_DIR 'esprit.cmd'
|
|
29
29
|
$ESPRIT_IMAGE = if ($env:ESPRIT_IMAGE) { $env:ESPRIT_IMAGE } else { 'improdead/esprit-sandbox:latest' }
|
|
30
|
+
$INSTALL_CHANNEL = if ($env:ESPRIT_INSTALL_CHANNEL) { $env:ESPRIT_INSTALL_CHANNEL } else { 'manual' }
|
|
30
31
|
|
|
31
32
|
function Print-Message {
|
|
32
33
|
param([string]$Level, [string]$Message)
|
|
@@ -85,6 +86,30 @@ function Invoke-Python {
|
|
|
85
86
|
}
|
|
86
87
|
}
|
|
87
88
|
|
|
89
|
+
function Validate-PythonRuntime {
|
|
90
|
+
param([string]$PyBin)
|
|
91
|
+
|
|
92
|
+
$parts = $PyBin -split ' ', 2
|
|
93
|
+
$exe = $parts[0]
|
|
94
|
+
$prefix = @()
|
|
95
|
+
if ($parts.Length -gt 1) { $prefix += $parts[1] }
|
|
96
|
+
|
|
97
|
+
$moduleCheck = @()
|
|
98
|
+
$moduleCheck += $prefix
|
|
99
|
+
$moduleCheck += '-c'
|
|
100
|
+
$moduleCheck += 'import importlib.util; required=("venv","ensurepip","ssl"); missing=[m for m in required if importlib.util.find_spec(m) is None]; print(",".join(missing)); raise SystemExit(0 if not missing else 1)'
|
|
101
|
+
|
|
102
|
+
$missingModules = (& $exe @moduleCheck 2>$null | Out-String).Trim()
|
|
103
|
+
if ($LASTEXITCODE -ne 0) {
|
|
104
|
+
if (-not $missingModules) { $missingModules = 'unknown' }
|
|
105
|
+
Print-Message 'error' "Python runtime is missing required stdlib modules: $missingModules."
|
|
106
|
+
Print-Message 'info' 'Install a full Python 3.12+ build (with venv + ensurepip) and retry.'
|
|
107
|
+
exit 1
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
Invoke-Python $PyBin @('-m', 'pip', '--version')
|
|
111
|
+
}
|
|
112
|
+
|
|
88
113
|
function Sync-RuntimeRepo {
|
|
89
114
|
Print-Message 'info' 'Syncing Esprit runtime source...'
|
|
90
115
|
|
|
@@ -202,14 +227,22 @@ function Warm-DockerImage {
|
|
|
202
227
|
# ── Main ──────────────────────────────────────────────────────────────────────
|
|
203
228
|
|
|
204
229
|
try {
|
|
230
|
+
Print-Message 'info' 'Running install preflight checks...'
|
|
205
231
|
Require-Command 'git' 'Install git and re-run the installer.'
|
|
206
232
|
|
|
233
|
+
if ($INSTALL_CHANNEL -eq 'npm') {
|
|
234
|
+
Require-Command 'node' 'Install Node.js 18+ and re-run npm install.'
|
|
235
|
+
Require-Command 'npm' 'Install npm and re-run npm install.'
|
|
236
|
+
}
|
|
237
|
+
|
|
207
238
|
$pyBin = Choose-Python
|
|
208
239
|
if (-not $pyBin) {
|
|
209
240
|
Print-Message 'error' 'Python 3.12+ is required.'
|
|
210
241
|
Print-Message 'info' 'Install Python 3.12 and re-run this installer.'
|
|
211
242
|
exit 1
|
|
212
243
|
}
|
|
244
|
+
Validate-PythonRuntime -PyBin $pyBin
|
|
245
|
+
Print-Message 'success' '✓ Preflight checks passed'
|
|
213
246
|
|
|
214
247
|
Print-Message 'info' "Installing Esprit (source mode)"
|
|
215
248
|
Print-Message 'info' "Runtime source: $REPO_URL@$REPO_REF"
|
package/scripts/install.sh
CHANGED
|
@@ -48,6 +48,61 @@ require_command() {
|
|
|
48
48
|
fi
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
+
validate_python_runtime() {
|
|
52
|
+
local py_bin="$1"
|
|
53
|
+
local missing_modules
|
|
54
|
+
|
|
55
|
+
if ! missing_modules=$("$py_bin" - <<'PY'
|
|
56
|
+
import importlib.util
|
|
57
|
+
required = ("venv", "ensurepip", "ssl")
|
|
58
|
+
missing = [name for name in required if importlib.util.find_spec(name) is None]
|
|
59
|
+
if missing:
|
|
60
|
+
print(",".join(missing))
|
|
61
|
+
raise SystemExit(1)
|
|
62
|
+
print("")
|
|
63
|
+
PY
|
|
64
|
+
); then
|
|
65
|
+
print_message error "Python runtime is missing required stdlib modules: ${missing_modules:-unknown}."
|
|
66
|
+
print_message info "Install a full Python 3.12+ build (with venv + ensurepip) and retry."
|
|
67
|
+
exit 1
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
if ! "$py_bin" -m pip --version >/dev/null 2>&1; then
|
|
71
|
+
print_message error "pip is unavailable for ${py_bin}."
|
|
72
|
+
print_message info "Install pip/ensurepip for your Python distribution and retry."
|
|
73
|
+
exit 1
|
|
74
|
+
fi
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
warn_if_musl_build_toolchain_missing() {
|
|
78
|
+
if [ "$(uname -s)" != "Linux" ]; then
|
|
79
|
+
return
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
if ! command -v ldd >/dev/null 2>&1; then
|
|
83
|
+
return
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
if ! ldd --version 2>&1 | grep -qi "musl"; then
|
|
87
|
+
return
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
local missing=()
|
|
91
|
+
local cmd
|
|
92
|
+
for cmd in gcc g++ make cargo rustc; do
|
|
93
|
+
if ! command -v "$cmd" >/dev/null 2>&1; then
|
|
94
|
+
missing+=("$cmd")
|
|
95
|
+
fi
|
|
96
|
+
done
|
|
97
|
+
|
|
98
|
+
if [ "${#missing[@]}" -gt 0 ]; then
|
|
99
|
+
print_message warning "Detected musl-based Linux (for example Alpine)."
|
|
100
|
+
print_message warning "Some Python dependencies may compile from source."
|
|
101
|
+
print_message info "Missing build tools: ${missing[*]}"
|
|
102
|
+
print_message info "Recommended: apk add --no-cache build-base linux-headers rust cargo"
|
|
103
|
+
fi
|
|
104
|
+
}
|
|
105
|
+
|
|
51
106
|
verify_signature() {
|
|
52
107
|
if ! command -v gpg &> /dev/null; then
|
|
53
108
|
echo "⚠ gpg not found — skipping signature verification"
|
|
@@ -259,9 +314,16 @@ warm_docker_image() {
|
|
|
259
314
|
}
|
|
260
315
|
|
|
261
316
|
main() {
|
|
317
|
+
local install_channel="${ESPRIT_INSTALL_CHANNEL:-curl}"
|
|
318
|
+
print_message info "${MUTED}Running install preflight checks...${NC}"
|
|
262
319
|
require_command git "Install git and re-run the installer."
|
|
263
320
|
require_command curl "Install curl and re-run the installer."
|
|
264
321
|
|
|
322
|
+
if [ "$install_channel" = "npm" ]; then
|
|
323
|
+
require_command node "Install Node.js 18+ and re-run npm install."
|
|
324
|
+
require_command npm "Install npm and re-run npm install."
|
|
325
|
+
fi
|
|
326
|
+
|
|
265
327
|
local py_bin
|
|
266
328
|
py_bin=$(choose_python || true)
|
|
267
329
|
if [ -z "$py_bin" ]; then
|
|
@@ -269,6 +331,9 @@ main() {
|
|
|
269
331
|
print_message info "Install Python 3.12 and re-run this installer."
|
|
270
332
|
exit 1
|
|
271
333
|
fi
|
|
334
|
+
validate_python_runtime "$py_bin"
|
|
335
|
+
warn_if_musl_build_toolchain_missing
|
|
336
|
+
print_message success "✓ Preflight checks passed"
|
|
272
337
|
|
|
273
338
|
print_message info "${CYAN}Installing Esprit${NC} ${MUTED}(source mode)${NC}"
|
|
274
339
|
print_message info "${MUTED}Runtime source:${NC} $REPO_URL@$REPO_REF"
|