Makelore 2.0 initial clean snapshot

This commit is contained in:
inman
2026-07-29 17:22:35 +08:00
commit b8ca3f8eea
694 changed files with 139782 additions and 0 deletions

View File

@@ -0,0 +1,137 @@
#!/usr/bin/env node
import { createHash } from 'node:crypto';
import { chmod, mkdir, mkdtemp, readFile, rename, rm, writeFile } from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
import * as tar from 'tar';
import {
getPythonTarget,
PYTHON_RELEASE,
PYTHON_TARGETS,
PYTHON_VERSION,
} from './bundled-python-manifest.mjs';
const SCRIPT_DIR = path.dirname(fileURLToPath(import.meta.url));
const DEFAULT_RESOURCES_ROOT = path.resolve(SCRIPT_DIR, '..', 'resources');
const PLATFORM_TARGETS = Object.freeze({
win: ['win32-x64'],
mac: ['darwin-x64', 'darwin-arm64'],
linux: ['linux-x64', 'linux-arm64'],
});
async function defaultExtractArchive(archivePath, destination) {
await tar.x({ file: archivePath, cwd: destination, gzip: true });
}
function markerFor(targetId, target) {
return {
release: PYTHON_RELEASE,
sha256: target.sha256,
target: targetId,
version: `${PYTHON_VERSION}+${PYTHON_RELEASE}`,
};
}
async function hasValidStaging(destination, targetId, target) {
try {
const marker = JSON.parse(await readFile(path.join(destination, '.niancode-python.json'), 'utf8'));
await readFile(path.join(destination, target.executable));
return JSON.stringify(marker) === JSON.stringify(markerFor(targetId, target));
} catch {
return false;
}
}
async function downloadArchive(targetId, target, fetchImpl) {
const urls = [target.url, target.mirrorUrl].filter(Boolean);
const failures = [];
for (const url of urls) {
try {
const response = await fetchImpl(url);
if (!response?.ok) {
failures.push(`${url}: HTTP ${response?.status ?? 'unknown'}`);
continue;
}
return Buffer.from(await response.arrayBuffer());
} catch (error) {
const cause = error?.cause?.code ?? error?.code ?? error?.cause?.message ?? error?.message ?? String(error);
failures.push(`${url}: ${cause}`);
}
}
throw new Error(`Failed to download bundled Python for ${targetId}: ${failures.join('; ')}`);
}
export async function stagePythonTarget(targetId, options = {}) {
const pinnedTarget = getPythonTarget(targetId);
const target = options.targetOverride ?? pinnedTarget;
const resourcesRoot = path.resolve(options.resourcesRoot ?? DEFAULT_RESOURCES_ROOT);
const pythonRoot = path.join(resourcesRoot, 'python');
const destination = path.join(pythonRoot, targetId);
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
const extractArchive = options.extractArchive ?? defaultExtractArchive;
if (!options.targetOverride && await hasValidStaging(destination, targetId, target)) {
return destination;
}
await mkdir(pythonRoot, { recursive: true });
const temporary = await mkdtemp(path.join(pythonRoot, `.${targetId}-`));
const archivePath = path.join(temporary, target.archiveName);
const extracted = path.join(temporary, 'extracted');
try {
const archive = await downloadArchive(targetId, target, fetchImpl);
const actualSha256 = createHash('sha256').update(archive).digest('hex');
if (actualSha256 !== target.sha256) {
throw new Error(`SHA-256 mismatch for ${targetId}: expected ${target.sha256}, received ${actualSha256}`);
}
await writeFile(archivePath, archive);
await mkdir(extracted, { recursive: true });
await extractArchive(archivePath, extracted);
const executable = path.join(extracted, target.executable);
await readFile(executable);
if (targetId !== 'win32-x64') await chmod(executable, 0o755);
await writeFile(
path.join(extracted, '.niancode-python.json'),
`${JSON.stringify(markerFor(targetId, target), null, 2)}\n`,
'utf8',
);
await rm(destination, { recursive: true, force: true });
await rename(extracted, destination);
return destination;
} finally {
await rm(temporary, { recursive: true, force: true });
}
}
function selectedTargets(argv) {
if (argv.includes('--all')) return Object.keys(PYTHON_TARGETS);
const platformArg = argv.find((value) => value.startsWith('--platform='));
if (platformArg) {
const platform = platformArg.slice('--platform='.length);
const targets = PLATFORM_TARGETS[platform];
if (!targets) throw new Error(`Unsupported bundled Python platform: ${platform}`);
return targets;
}
const targetArg = argv.find((value) => value.startsWith('--target='));
if (targetArg) return [targetArg.slice('--target='.length)];
return [`${os.platform()}-${os.arch()}`];
}
async function main() {
for (const targetId of selectedTargets(process.argv.slice(2))) {
const destination = await stagePythonTarget(targetId);
process.stdout.write(`[python] staged ${targetId} at ${destination}\n`);
}
}
if (process.argv[1] && import.meta.url === pathToFileURL(path.resolve(process.argv[1])).href) {
main().catch((error) => {
process.stderr.write(`[python] ${error instanceof Error ? error.message : String(error)}\n`);
process.exitCode = 1;
});
}