Files
Sprinter-SDCC/toolchain/vscode-sprinter-debug/runtime.js
T

98 lines
3.5 KiB
JavaScript

const fs = require('fs');
const os = require('os');
const path = require('path');
function executable(filename) {
try {
fs.accessSync(filename, fs.constants.X_OK);
return true;
} catch (_) {
return false;
}
}
function localPythonVersion(workspace) {
if (!workspace) return null;
let directory = path.resolve(workspace);
while (directory !== path.dirname(directory)) {
try {
const version = fs.readFileSync(path.join(directory, '.python-version'),
'utf8').trim().split(/\s+/)[0];
return /^[A-Za-z0-9._-]+$/.test(version) ? version : null;
} catch (_) {}
directory = path.dirname(directory);
}
return null;
}
function installedPyenvPythons(home) {
try {
const versions = fs.readdirSync(path.join(home, '.pyenv', 'versions'));
return versions.filter(version => /^3\.12(?:\.\d+)?$/.test(version))
.sort((a, b) => Number(b.split('.')[2] || 0) -
Number(a.split('.')[2] || 0))
.map(version => path.join(home, '.pyenv', 'versions', version,
'bin', 'python'));
} catch (_) {
return [];
}
}
function resolvePython(options = {}) {
const command = String(options.command || 'auto').trim();
const args = Array.isArray(options.args) ? options.args : [];
if (command !== 'auto') {
return {command, args};
}
const home = options.home || os.homedir();
const workspace = options.workspace;
const isExecutable = options.isExecutable || executable;
const candidates = [];
const shim = path.join(home, '.pyenv', 'shims', 'python');
const version = options.localVersion === undefined ?
localPythonVersion(workspace) : options.localVersion;
const installed = options.installedPyenv === undefined ?
installedPyenvPythons(home) : options.installedPyenv;
if (version) candidates.push(shim);
candidates.push(...installed);
if (!version) candidates.push(shim);
if (workspace) {
candidates.push(path.join(workspace, '.venv', 'bin', 'python'));
}
candidates.push(
'/opt/homebrew/bin/python3.12',
'/usr/local/bin/python3.12',
'/usr/bin/python3.12',
);
const found = candidates.find(isExecutable);
if (!found) {
throw new Error(
'Не найден Python 3.12. Задайте абсолютный путь в ' +
'sprinterDebugger.pythonCommand.');
}
return {command: found, args: []};
}
function pyenvEnvironment(command, workspace, home = os.homedir()) {
const shim = path.join(home, '.pyenv', 'shims', 'python');
const version = command === shim ? localPythonVersion(workspace) : null;
return version ? {PYENV_VERSION: version} : undefined;
}
function resolveSdkRoot(configured, workspace, environment = process.env) {
const candidates = [configured, environment.SPRINTER_ROOT, workspace]
.filter(Boolean).map(value => path.resolve(value));
const found = candidates.find(root =>
fs.existsSync(path.join(root, 'toolchain', 'sdbg_dap.py')) &&
fs.existsSync(path.join(root, 'bin', 'sprinter-cc')));
if (!found) {
throw new Error('Не найден Sprinter-CC: задайте sprinterDebugger.sdkRoot ' +
'или SPRINTER_ROOT');
}
return found;
}
module.exports = {resolvePython, localPythonVersion, installedPyenvPythons,
pyenvEnvironment, resolveSdkRoot};