feat(installer): migrate shims to runtime-managed targets
This commit is contained in:
parent
205f9500ec
commit
7945ee8d3c
6 changed files with 271 additions and 1 deletions
64
install/install.ps1
Normal file
64
install/install.ps1
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||||
|
$RepoRoot = Split-Path -Parent $ScriptDir
|
||||||
|
$InstallHome = if ($env:BB_INSTALL_HOME) { $env:BB_INSTALL_HOME } else { $HOME }
|
||||||
|
$BbHome = Join-Path $InstallHome '.beadboard'
|
||||||
|
$TargetDir = Join-Path $BbHome 'bin'
|
||||||
|
$RuntimeDir = Join-Path $BbHome 'runtime'
|
||||||
|
$CurrentJson = Join-Path $RuntimeDir 'current.json'
|
||||||
|
$Version = if ($env:BB_RUNTIME_VERSION) { $env:BB_RUNTIME_VERSION } else { '0.1.0' }
|
||||||
|
|
||||||
|
New-Item -ItemType Directory -Path $TargetDir -Force | Out-Null
|
||||||
|
New-Item -ItemType Directory -Path $RuntimeDir -Force | Out-Null
|
||||||
|
|
||||||
|
$BeadboardShim = Join-Path $TargetDir 'beadboard.cmd'
|
||||||
|
$BbShim = Join-Path $TargetDir 'bb.cmd'
|
||||||
|
|
||||||
|
$runtimeMetadata = @{
|
||||||
|
version = $Version
|
||||||
|
runtimeRoot = $RepoRoot
|
||||||
|
installMode = 'repo-shim-fallback'
|
||||||
|
shimTarget = (Join-Path $RepoRoot 'install\beadboard.mjs')
|
||||||
|
} | ConvertTo-Json -Depth 4
|
||||||
|
|
||||||
|
[System.IO.File]::WriteAllText($CurrentJson, "$runtimeMetadata`n")
|
||||||
|
|
||||||
|
$beadboardContent = @"
|
||||||
|
@echo off
|
||||||
|
setlocal
|
||||||
|
set "BB_HOME=%BB_INSTALL_HOME%"
|
||||||
|
if "%BB_HOME%"=="" set "BB_HOME=%USERPROFILE%"
|
||||||
|
set "CURRENT_JSON=%BB_HOME%\.beadboard\runtime\current.json"
|
||||||
|
set "RUNTIME_ROOT="
|
||||||
|
for /f "usebackq delims=" %%I in (`powershell -NoProfile -Command "$p='%CURRENT_JSON%'; if (Test-Path $p) { try { (Get-Content -Raw $p | ConvertFrom-Json).runtimeRoot } catch {} }"`) do set "RUNTIME_ROOT=%%I"
|
||||||
|
if "%RUNTIME_ROOT%"=="" set "RUNTIME_ROOT=$RepoRoot"
|
||||||
|
node "%RUNTIME_ROOT%\install\beadboard.mjs" %*
|
||||||
|
"@
|
||||||
|
|
||||||
|
$bbContent = @"
|
||||||
|
@echo off
|
||||||
|
setlocal
|
||||||
|
set "BB_HOME=%BB_INSTALL_HOME%"
|
||||||
|
if "%BB_HOME%"=="" set "BB_HOME=%USERPROFILE%"
|
||||||
|
set "CURRENT_JSON=%BB_HOME%\.beadboard\runtime\current.json"
|
||||||
|
set "RUNTIME_ROOT="
|
||||||
|
for /f "usebackq delims=" %%I in (`powershell -NoProfile -Command "$p='%CURRENT_JSON%'; if (Test-Path $p) { try { (Get-Content -Raw $p | ConvertFrom-Json).runtimeRoot } catch {} }"`) do set "RUNTIME_ROOT=%%I"
|
||||||
|
if "%RUNTIME_ROOT%"=="" set "RUNTIME_ROOT=$RepoRoot"
|
||||||
|
npx --yes tsx "%RUNTIME_ROOT%\tools\bb.ts" %*
|
||||||
|
"@
|
||||||
|
|
||||||
|
$beadboardTemp = "$BeadboardShim.tmp"
|
||||||
|
$bbTemp = "$BbShim.tmp"
|
||||||
|
[System.IO.File]::WriteAllText($beadboardTemp, $beadboardContent)
|
||||||
|
[System.IO.File]::WriteAllText($bbTemp, $bbContent)
|
||||||
|
Move-Item -Path $beadboardTemp -Destination $BeadboardShim -Force
|
||||||
|
Move-Item -Path $bbTemp -Destination $BbShim -Force
|
||||||
|
|
||||||
|
Write-Output "Installed BeadBoard shims:"
|
||||||
|
Write-Output "- $BeadboardShim"
|
||||||
|
Write-Output "- $BbShim"
|
||||||
|
Write-Output "- $CurrentJson"
|
||||||
|
Write-Output ""
|
||||||
|
Write-Output "Add to PATH if needed:"
|
||||||
|
Write-Output " setx PATH ""$TargetDir;%PATH%"""
|
||||||
81
install/install.sh
Normal file
81
install/install.sh
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd -- "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
REPO_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
|
||||||
|
INSTALL_HOME="${BB_INSTALL_HOME:-$HOME}"
|
||||||
|
BB_HOME="${INSTALL_HOME}/.beadboard"
|
||||||
|
TARGET_DIR="${BB_HOME}/bin"
|
||||||
|
RUNTIME_DIR="${BB_HOME}/runtime"
|
||||||
|
CURRENT_JSON="${RUNTIME_DIR}/current.json"
|
||||||
|
VERSION="${BB_RUNTIME_VERSION:-0.1.0}"
|
||||||
|
|
||||||
|
write_file_atomic() {
|
||||||
|
local target="$1"
|
||||||
|
local tmp="${target}.tmp.$$"
|
||||||
|
cat > "${tmp}"
|
||||||
|
mv "${tmp}" "${target}"
|
||||||
|
}
|
||||||
|
|
||||||
|
mkdir -p "${TARGET_DIR}" "${RUNTIME_DIR}"
|
||||||
|
|
||||||
|
write_file_atomic "${CURRENT_JSON}" <<EOF
|
||||||
|
{
|
||||||
|
"version": "${VERSION}",
|
||||||
|
"runtimeRoot": "${REPO_ROOT}",
|
||||||
|
"installMode": "repo-shim-fallback",
|
||||||
|
"shimTarget": "${REPO_ROOT}/install/beadboard.mjs"
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
write_file_atomic "${TARGET_DIR}/beadboard" <<EOF
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
BB_HOME="\${BB_INSTALL_HOME:-\$HOME}/.beadboard"
|
||||||
|
CURRENT_JSON="\${BB_HOME}/runtime/current.json"
|
||||||
|
resolve_runtime_root() {
|
||||||
|
if [ -f "\${CURRENT_JSON}" ]; then
|
||||||
|
local root
|
||||||
|
root="\$(node -e "const fs=require('fs');try{const j=JSON.parse(fs.readFileSync(process.argv[1],'utf8'));if(j&&typeof j.runtimeRoot==='string')process.stdout.write(j.runtimeRoot)}catch{}" "\${CURRENT_JSON}")"
|
||||||
|
if [ -n "\${root}" ]; then
|
||||||
|
printf '%s' "\${root}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
printf '%s' "${REPO_ROOT}"
|
||||||
|
}
|
||||||
|
RUNTIME_ROOT="\$(resolve_runtime_root)"
|
||||||
|
exec node "\${RUNTIME_ROOT}/install/beadboard.mjs" "\$@"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
write_file_atomic "${TARGET_DIR}/bb" <<EOF
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
BB_HOME="\${BB_INSTALL_HOME:-\$HOME}/.beadboard"
|
||||||
|
CURRENT_JSON="\${BB_HOME}/runtime/current.json"
|
||||||
|
resolve_runtime_root() {
|
||||||
|
if [ -f "\${CURRENT_JSON}" ]; then
|
||||||
|
local root
|
||||||
|
root="\$(node -e "const fs=require('fs');try{const j=JSON.parse(fs.readFileSync(process.argv[1],'utf8'));if(j&&typeof j.runtimeRoot==='string')process.stdout.write(j.runtimeRoot)}catch{}" "\${CURRENT_JSON}")"
|
||||||
|
if [ -n "\${root}" ]; then
|
||||||
|
printf '%s' "\${root}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
printf '%s' "${REPO_ROOT}"
|
||||||
|
}
|
||||||
|
RUNTIME_ROOT="\$(resolve_runtime_root)"
|
||||||
|
exec npx --yes tsx "\${RUNTIME_ROOT}/tools/bb.ts" "\$@"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
chmod +x "${TARGET_DIR}/beadboard" "${TARGET_DIR}/bb"
|
||||||
|
|
||||||
|
cat <<MSG
|
||||||
|
Installed BeadBoard shims:
|
||||||
|
- ${TARGET_DIR}/beadboard
|
||||||
|
- ${TARGET_DIR}/bb
|
||||||
|
- ${CURRENT_JSON}
|
||||||
|
|
||||||
|
Add to PATH if needed:
|
||||||
|
export PATH="${TARGET_DIR}:\$PATH"
|
||||||
|
MSG
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"lint": "eslint .",
|
"lint": "eslint .",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"test": "node --test tests/bootstrap.test.mjs && node --import tsx --test tests/components/shared/base-card.test.tsx && node --import tsx --test tests/components/shared/agent-avatar.test.tsx && node --import tsx --test tests/components/sessions/sessions-header.test.ts && node --import tsx --test tests/components/sessions/agent-station-logic.test.ts && node --import tsx --test tests/lib/parser.test.ts && node --import tsx --test tests/lib/pathing.test.ts && node --import tsx --test tests/components/shared/left-panel.test.tsx && node --import tsx --test tests/components/shared/top-bar.test.tsx && node --import tsx --test tests/components/shared/mobile-nav.test.tsx && node --import tsx --test tests/components/swarm/swarm-card.test.tsx && node --import tsx --test tests/hooks/url-state-integration.test.ts && node --import tsx --test tests/hooks/use-graph-analysis.test.ts && node --import tsx --test tests/components/graph/smart-dag.test.tsx && node --import tsx --test tests/components/unified-shell.test.tsx && node --import tsx --test tests/components/blocked-triage-modal.test.tsx && node --import tsx --test tests/components/graph/graph-node-labels.test.tsx && node --import tsx --test tests/components/graph/graph-node-assign.test.tsx && node --import tsx --test tests/components/graph/graph-node-conversation.test.tsx && node --import tsx --test tests/lib/coord-schema.test.ts && node --import tsx --test tests/lib/install-manifest.test.ts && node --import tsx --test tests/lib/runtime-manager.test.ts && node --import tsx --test tests/lib/coord-events.test.ts && node --import tsx --test tests/api/coord-events-route.test.ts && node --import tsx --test tests/lib/coord-projections-inbox.test.ts && node --import tsx --test tests/lib/coord-projections-reservations.test.ts && node --import tsx --test tests/components/sessions/conversation-drawer-coord.test.tsx && node --import tsx --test tests/scripts/beadboard-launcher.test.ts && node --import tsx --test tests/scripts/beadboard-launcher-runtime.test.ts && node --import tsx --test tests/scripts/install-wrappers-contract.test.ts && node --import tsx --test tests/scripts/install-sh-smoke.test.ts && node --import tsx --test tests/scripts/installer-ci-contract.test.ts && node --import tsx --test tests/docs/installer-quickstart-contract.test.ts && node --import tsx --test tests/docs/runtime-manager-adr-contract.test.ts && node --import tsx --test tests/skills/beadboard-driver/resolve-bb.test.ts && node --import tsx --test tests/skills/beadboard-driver/session-preflight.test.ts && node --import tsx --test tests/skills/beadboard-driver/generate-agent-name.test.ts && node --import tsx --test tests/skills/beadboard-driver/readiness-report.test.ts && node --import tsx --test tests/skills/beadboard-driver/skill-local-runner.test.ts && node --import tsx --test tests/skills/beadboard-driver/diagnose-env.test.ts && node --import tsx --test tests/skills/beadboard-driver/heal-common-issues.test.ts && node --import tsx --test tests/lib/epic-graph.test.ts && node --import tsx --test tests/components/shared/left-panel-filtering.test.ts && node --import tsx --test tests/hooks/use-beads-subscription-contract.test.ts && node --import tsx --test tests/components/graph/dependency-graph-hide-closed-contract.test.ts && node --import tsx --test tests/components/shared/unified-shell-hide-closed-contract.test.ts",
|
"test": "node --test tests/bootstrap.test.mjs && node --import tsx --test tests/components/shared/base-card.test.tsx && node --import tsx --test tests/components/shared/agent-avatar.test.tsx && node --import tsx --test tests/components/sessions/sessions-header.test.ts && node --import tsx --test tests/components/sessions/agent-station-logic.test.ts && node --import tsx --test tests/lib/parser.test.ts && node --import tsx --test tests/lib/pathing.test.ts && node --import tsx --test tests/components/shared/left-panel.test.tsx && node --import tsx --test tests/components/shared/top-bar.test.tsx && node --import tsx --test tests/components/shared/mobile-nav.test.tsx && node --import tsx --test tests/components/swarm/swarm-card.test.tsx && node --import tsx --test tests/hooks/url-state-integration.test.ts && node --import tsx --test tests/hooks/use-graph-analysis.test.ts && node --import tsx --test tests/components/graph/smart-dag.test.tsx && node --import tsx --test tests/components/unified-shell.test.tsx && node --import tsx --test tests/components/blocked-triage-modal.test.tsx && node --import tsx --test tests/components/graph/graph-node-labels.test.tsx && node --import tsx --test tests/components/graph/graph-node-assign.test.tsx && node --import tsx --test tests/components/graph/graph-node-conversation.test.tsx && node --import tsx --test tests/lib/coord-schema.test.ts && node --import tsx --test tests/lib/install-manifest.test.ts && node --import tsx --test tests/lib/runtime-manager.test.ts && node --import tsx --test tests/lib/coord-events.test.ts && node --import tsx --test tests/api/coord-events-route.test.ts && node --import tsx --test tests/lib/coord-projections-inbox.test.ts && node --import tsx --test tests/lib/coord-projections-reservations.test.ts && node --import tsx --test tests/components/sessions/conversation-drawer-coord.test.tsx && node --import tsx --test tests/scripts/beadboard-launcher.test.ts && node --import tsx --test tests/scripts/beadboard-launcher-runtime.test.ts && node --import tsx --test tests/scripts/install-wrappers-contract.test.ts && node --import tsx --test tests/scripts/install-sh-smoke.test.ts && node --import tsx --test tests/scripts/install-legacy-migration.test.ts && node --import tsx --test tests/scripts/installer-ci-contract.test.ts && node --import tsx --test tests/docs/installer-quickstart-contract.test.ts && node --import tsx --test tests/docs/runtime-manager-adr-contract.test.ts && node --import tsx --test tests/skills/beadboard-driver/resolve-bb.test.ts && node --import tsx --test tests/skills/beadboard-driver/session-preflight.test.ts && node --import tsx --test tests/skills/beadboard-driver/generate-agent-name.test.ts && node --import tsx --test tests/skills/beadboard-driver/readiness-report.test.ts && node --import tsx --test tests/skills/beadboard-driver/skill-local-runner.test.ts && node --import tsx --test tests/skills/beadboard-driver/diagnose-env.test.ts && node --import tsx --test tests/skills/beadboard-driver/heal-common-issues.test.ts && node --import tsx --test tests/lib/epic-graph.test.ts && node --import tsx --test tests/components/shared/left-panel-filtering.test.ts && node --import tsx --test tests/hooks/use-beads-subscription-contract.test.ts && node --import tsx --test tests/components/graph/dependency-graph-hide-closed-contract.test.ts && node --import tsx --test tests/components/shared/unified-shell-hide-closed-contract.test.ts",
|
||||||
"video": "remotion preview src/video/index.ts",
|
"video": "remotion preview src/video/index.ts",
|
||||||
"video:render": "remotion render src/video/index.ts Main out/video.mp4",
|
"video:render": "remotion render src/video/index.ts Main out/video.mp4",
|
||||||
"video:thumbnail": "remotion still src/video/index.ts Main out/thumbnail.png --frame=60"
|
"video:thumbnail": "remotion still src/video/index.ts Main out/thumbnail.png --frame=60"
|
||||||
|
|
|
||||||
45
tests/scripts/install-legacy-migration.test.ts
Normal file
45
tests/scripts/install-legacy-migration.test.ts
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import fs from 'node:fs/promises';
|
||||||
|
import os from 'node:os';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { execFile } from 'node:child_process';
|
||||||
|
import { promisify } from 'node:util';
|
||||||
|
|
||||||
|
const execFileAsync = promisify(execFile);
|
||||||
|
|
||||||
|
test('installer migrates legacy repo-bound shim to runtime-managed shim', async () => {
|
||||||
|
if (process.platform === 'win32') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'bb-install-migrate-'));
|
||||||
|
const installHome = path.join(root, 'home').replace(/\\/g, '/');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const shimDir = path.join(installHome, '.beadboard', 'bin');
|
||||||
|
await fs.mkdir(shimDir, { recursive: true });
|
||||||
|
await fs.writeFile(
|
||||||
|
path.join(shimDir, 'beadboard'),
|
||||||
|
'#!/usr/bin/env bash\nexec node "/legacy/repo/install/beadboard.mjs" "$@"\n',
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
|
|
||||||
|
await execFileAsync('bash', ['install/install.sh'], {
|
||||||
|
env: { ...process.env, BB_INSTALL_HOME: installHome },
|
||||||
|
});
|
||||||
|
|
||||||
|
const shimRaw = await fs.readFile(path.join(shimDir, 'beadboard'), 'utf8');
|
||||||
|
const metadataRaw = await fs.readFile(
|
||||||
|
path.join(installHome, '.beadboard', 'runtime', 'current.json'),
|
||||||
|
'utf8',
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.doesNotMatch(shimRaw, /\/legacy\/repo\/install\/beadboard\.mjs/);
|
||||||
|
assert.match(shimRaw, /runtime\/current\.json/);
|
||||||
|
assert.match(shimRaw, /RUNTIME_ROOT/);
|
||||||
|
assert.match(metadataRaw, /"runtimeRoot"/);
|
||||||
|
} finally {
|
||||||
|
await fs.rm(root, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
41
tests/scripts/install-sh-smoke.test.ts
Normal file
41
tests/scripts/install-sh-smoke.test.ts
Normal file
|
|
@ -0,0 +1,41 @@
|
||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import fs from 'node:fs/promises';
|
||||||
|
import os from 'node:os';
|
||||||
|
import path from 'node:path';
|
||||||
|
import { execFile } from 'node:child_process';
|
||||||
|
import { promisify } from 'node:util';
|
||||||
|
|
||||||
|
const execFileAsync = promisify(execFile);
|
||||||
|
const scriptPath = 'install/install.sh';
|
||||||
|
|
||||||
|
test('install.sh supports install and reinstall into BB_INSTALL_HOME', { skip: os.platform() === 'win32' ? 'Bash pathing issues on Windows' : false }, async () => {
|
||||||
|
const root = await fs.mkdtemp(path.join(os.tmpdir(), 'bb-install-smoke-'));
|
||||||
|
const installHome = path.join(root, 'home').replace(/\\/g, '/');
|
||||||
|
|
||||||
|
try {
|
||||||
|
await execFileAsync('bash', [scriptPath], {
|
||||||
|
env: { ...process.env, BB_INSTALL_HOME: installHome },
|
||||||
|
});
|
||||||
|
await execFileAsync('bash', [scriptPath], {
|
||||||
|
env: { ...process.env, BB_INSTALL_HOME: installHome },
|
||||||
|
});
|
||||||
|
|
||||||
|
const beadboardShim = path.join(installHome, '.beadboard', 'bin', 'beadboard');
|
||||||
|
const bbShim = path.join(installHome, '.beadboard', 'bin', 'bb');
|
||||||
|
const runtimeMetadata = path.join(installHome, '.beadboard', 'runtime', 'current.json');
|
||||||
|
|
||||||
|
const [beadboardRaw, bbRaw, metadataRaw] = await Promise.all([
|
||||||
|
fs.readFile(beadboardShim, 'utf8'),
|
||||||
|
fs.readFile(bbShim, 'utf8'),
|
||||||
|
fs.readFile(runtimeMetadata, 'utf8'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert.match(beadboardRaw, /runtime\/current\.json/);
|
||||||
|
assert.match(bbRaw, /runtime\/current\.json/);
|
||||||
|
assert.match(metadataRaw, /"runtimeRoot"/);
|
||||||
|
assert.match(metadataRaw, /"installMode"/);
|
||||||
|
} finally {
|
||||||
|
await fs.rm(root, { recursive: true, force: true });
|
||||||
|
}
|
||||||
|
});
|
||||||
39
tests/scripts/install-wrappers-contract.test.ts
Normal file
39
tests/scripts/install-wrappers-contract.test.ts
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import fs from 'node:fs/promises';
|
||||||
|
import path from 'node:path';
|
||||||
|
|
||||||
|
async function read(relativePath: string): Promise<string> {
|
||||||
|
return fs.readFile(path.resolve(relativePath), 'utf8');
|
||||||
|
}
|
||||||
|
|
||||||
|
test('install wrapper scripts exist with canonical filenames', async () => {
|
||||||
|
const [ps1, sh] = await Promise.all([
|
||||||
|
read('install/install.ps1'),
|
||||||
|
read('install/install.sh'),
|
||||||
|
]);
|
||||||
|
assert.match(ps1, /beadboard/i);
|
||||||
|
assert.match(sh, /beadboard/i);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('install wrappers provision both bb and beadboard shims', async () => {
|
||||||
|
const [ps1, sh] = await Promise.all([
|
||||||
|
read('install/install.ps1'),
|
||||||
|
read('install/install.sh'),
|
||||||
|
]);
|
||||||
|
assert.match(ps1, /\bbb\b/i);
|
||||||
|
assert.match(ps1, /\bbeadboard\b/i);
|
||||||
|
assert.match(sh, /\bbb\b/i);
|
||||||
|
assert.match(sh, /\bbeadboard\b/i);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('install wrappers write runtime metadata and resolve runtime targets first', async () => {
|
||||||
|
const [ps1, sh] = await Promise.all([
|
||||||
|
read('install/install.ps1'),
|
||||||
|
read('install/install.sh'),
|
||||||
|
]);
|
||||||
|
assert.match(ps1, /runtime\\current\.json/i);
|
||||||
|
assert.match(ps1, /RUNTIME_ROOT/i);
|
||||||
|
assert.match(sh, /runtime\/current\.json/i);
|
||||||
|
assert.match(sh, /RUNTIME_ROOT/i);
|
||||||
|
});
|
||||||
Loading…
Add table
Add a link
Reference in a new issue