Consolidate the repository into clearer apps, tools, and layered docs areas so contributors can navigate and maintain it more reliably. Align validation, metadata sync, and CI around the same canonical workflow to reduce drift across local checks and GitHub Actions.
91 lines
2.0 KiB
JavaScript
91 lines
2.0 KiB
JavaScript
#!/usr/bin/env node
|
|
|
|
'use strict';
|
|
|
|
const { spawn, spawnSync } = require('node:child_process');
|
|
|
|
const args = process.argv.slice(2);
|
|
|
|
if (args.length === 0) {
|
|
console.error('Usage: node tools/scripts/run-python.js <script.py> [args...]');
|
|
process.exit(1);
|
|
}
|
|
|
|
function uniqueCandidates(candidates) {
|
|
const seen = new Set();
|
|
const unique = [];
|
|
|
|
for (const candidate of candidates) {
|
|
const key = candidate.join('\u0000');
|
|
if (!seen.has(key)) {
|
|
seen.add(key);
|
|
unique.push(candidate);
|
|
}
|
|
}
|
|
|
|
return unique;
|
|
}
|
|
|
|
function getPythonCandidates() {
|
|
// Optional override for CI/local pinning without editing scripts.
|
|
const configuredPython =
|
|
process.env.ANTIGRAVITY_PYTHON || process.env.npm_config_python;
|
|
const candidates = [
|
|
configuredPython ? [configuredPython] : null,
|
|
// Keep this ordered list easy to update if project requirements change.
|
|
['python3'],
|
|
['python'],
|
|
['py', '-3'],
|
|
].filter(Boolean);
|
|
|
|
return uniqueCandidates(candidates);
|
|
}
|
|
|
|
function canRun(candidate) {
|
|
const [command, ...baseArgs] = candidate;
|
|
const probe = spawnSync(
|
|
command,
|
|
[...baseArgs, '-c', 'import sys; raise SystemExit(0 if sys.version_info[0] == 3 else 1)'],
|
|
{
|
|
stdio: 'ignore',
|
|
shell: false,
|
|
},
|
|
);
|
|
|
|
return probe.error == null && probe.status === 0;
|
|
}
|
|
|
|
const pythonCandidates = getPythonCandidates();
|
|
const selected = pythonCandidates.find(canRun);
|
|
|
|
if (!selected) {
|
|
console.error(
|
|
'Unable to find a Python 3 interpreter. Tried: python3, python, py -3',
|
|
);
|
|
process.exit(1);
|
|
}
|
|
|
|
const [command, ...baseArgs] = selected;
|
|
const child = spawn(command, [...baseArgs, ...args], {
|
|
stdio: 'inherit',
|
|
shell: false,
|
|
});
|
|
|
|
child.on('error', (error) => {
|
|
console.error(`Failed to start Python interpreter "${command}": ${error.message}`);
|
|
process.exit(1);
|
|
});
|
|
|
|
child.on('exit', (code, signal) => {
|
|
if (signal) {
|
|
try {
|
|
process.kill(process.pid, signal);
|
|
} catch {
|
|
process.exit(1);
|
|
}
|
|
return;
|
|
}
|
|
|
|
process.exit(code ?? 1);
|
|
});
|