35 lines
1.8 KiB
JavaScript
35 lines
1.8 KiB
JavaScript
import {existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync} from 'node:fs';
|
|
import path from 'node:path';
|
|
import {sha256} from './images.mjs';
|
|
import {redact} from '../providers/http.mjs';
|
|
|
|
export function jsonFile(file, value, secret = '') {
|
|
writeFileSync(file, `${redact(JSON.stringify(value, null, 2), secret)}\n`, 'utf8');
|
|
}
|
|
|
|
export function prepareRun(outDir, fingerprint, resume) {
|
|
const out = path.resolve(outDir);
|
|
const manifestPath = path.join(out, 'manifest.json');
|
|
if (existsSync(out) && readdirSync(out).length) {
|
|
if (!resume) throw new Error(`输出目录非空,请使用新目录或 --resume:${out}`);
|
|
if (!existsSync(manifestPath)) throw new Error('无法复用:目录没有 manifest.json');
|
|
const previous = JSON.parse(readFileSync(manifestPath, 'utf8'));
|
|
if (previous.fingerprint !== fingerprint) throw new Error('无法复用:模型、配置、输入或代码版本变化,请使用新的输出目录');
|
|
if (previous.status !== 'completed') throw new Error('上次任务没有完整结束,请保留诊断文件并使用新目录重跑');
|
|
for (const [name, hash] of Object.entries(previous.artifact_hashes || {})) {
|
|
const file = path.join(out, name);
|
|
if (!existsSync(file) || sha256(readFileSync(file)) !== hash) throw new Error(`缓存产物缺失或被修改:${name}`);
|
|
}
|
|
if (!Object.keys(previous.artifact_hashes || {}).length) throw new Error('缓存缺少产物校验记录');
|
|
return {out, manifestPath, reused: true};
|
|
}
|
|
mkdirSync(out, {recursive: true});
|
|
return {out, manifestPath, reused: false};
|
|
}
|
|
|
|
export function finishRun(run, manifest, artifacts, secret) {
|
|
manifest.artifact_hashes = Object.fromEntries(artifacts.map((name) => [name, sha256(readFileSync(path.join(run.out, name)))]));
|
|
manifest.status = 'completed';
|
|
jsonFile(run.manifestPath, manifest, secret);
|
|
}
|