40 lines
3.0 KiB
JavaScript
40 lines
3.0 KiB
JavaScript
// Offline, isolated native smoke. Never call this a Windows pass on another OS.
|
|
import fs from 'node:fs/promises'
|
|
import path from 'node:path'
|
|
import os from 'node:os'
|
|
import { spawnSync } from 'node:child_process'
|
|
import { runtimeRoot, verifyRuntimeBundle } from './runtime-bundle.mjs'
|
|
if (process.platform !== 'win32' || process.arch !== 'x64') {
|
|
console.log('SKIP: native toolchain smoke requires Windows x64; no Windows binaries executed.')
|
|
process.exit(0)
|
|
}
|
|
const root = path.resolve(process.argv[2] || path.join(runtimeRoot, 'win32-x64'))
|
|
await verifyRuntimeBundle(root)
|
|
const temp = await fs.mkdtemp(path.join(os.tmpdir(), 'YCode runtime 中文 '))
|
|
try {
|
|
const inherited = Object.fromEntries(Object.entries(process.env).filter(([key]) => !/^(?:path|home|userprofile|temp|tmp|python.*|pip_.*|npm_config_.*|node_options|git_.*)$/i.test(key)))
|
|
const env = { ...inherited, HOME: temp, USERPROFILE: temp, TEMP: temp, TMP: temp,
|
|
npm_config_userconfig: path.join(temp, 'npmrc'), npm_config_globalconfig: path.join(temp, 'npm-globalrc'),
|
|
npm_config_cache: path.join(temp, 'npm-cache'), npm_config_prefix: path.join(temp, 'npm-prefix'),
|
|
PYTHONUSERBASE: path.join(temp, 'python-user'), PIP_CACHE_DIR: path.join(temp, 'pip-cache'),
|
|
PYTHONNOUSERSITE: '1', PYTHONDONTWRITEBYTECODE: '1', GIT_CONFIG_NOSYSTEM: '1', GIT_CONFIG_GLOBAL: path.join(temp, 'gitconfig'),
|
|
PATH: [path.join(root, 'node'), path.join(root, 'python'), path.join(root, 'git/cmd'), path.join(root, 'git/bin'), path.join(process.env.SystemRoot || 'C:\\Windows', 'System32')].join(';') }
|
|
const run = (exe, args, options = {}) => {
|
|
const r = spawnSync(exe, args, { cwd: temp, env, encoding: 'utf8', timeout: 60_000, windowsHide: true, ...options })
|
|
if (r.error || r.status !== 0) throw new Error(`${exe} ${args.join(' ')} failed: ${r.error || r.stderr || r.stdout}`)
|
|
console.log(r.stdout.trim())
|
|
}
|
|
const node = path.join(root, 'node/node.exe'), python = path.join(root, 'python/python.exe')
|
|
run(node, ['--version'])
|
|
// Explicit cmd.exe, fixed arguments only; downloaded npm/npx scripts never use shell interpolation from user input.
|
|
for (const command of ['npm', 'npx']) run(process.env.ComSpec || 'cmd.exe', ['/d', '/s', '/c', `""${path.join(root, `node/${command}.cmd`)}" --version"`], { windowsVerbatimArguments: true })
|
|
run(python, ['--version']); run(python, ['-m', 'pip', '--version'])
|
|
run(python, ['-m', 'venv', path.join(temp, 'venv')])
|
|
run(path.join(temp, 'venv/Scripts/python.exe'), ['-m', 'pip', '--version'])
|
|
const git = path.join(root, 'git/cmd/git.exe'), bash = path.join(root, 'git/bin/bash.exe')
|
|
run(git, ['--version']); run(git, ['init', '--quiet', path.join(temp, 'repo')])
|
|
run(bash, ['--version']); run(bash, ['--noprofile', '--norc', '-c', 'printf "ycode-bash-ok\\n"'])
|
|
await verifyRuntimeBundle(root)
|
|
console.log('PASS: offline Windows x64 runtime smoke; resources unchanged. Network package installs and HTTPS Git remain untested.')
|
|
} finally { await fs.rm(temp, { recursive: true, force: true }) }
|