#!/usr/bin/env -S deno run -A /** * 生成 scripts/mp-sync/ledger.json 与 docs/porting/mp-sync-ledger.md 中的对照总表。 * * deno run -A scripts/mp-sync/build-ledger.mjs [--mp /opt/moviepilot-plus/upstream/MoviePilot] [--commit e6820a8] * * 数据来源:源码文件头 `@mp-source <上游路径> @ <提交>` 标签 + ledger.manual.json(未打标签的既有移植)。 * 每条记录保存移植时的上游提交与该文件内容 sha256,供 check.mjs 比较。 * 增量移植完成后:把对应源码文件头的提交号改为新提交,再重跑本脚本。 */ import { readFileSync, writeFileSync } from "node:fs"; import { biomeFormat, DEFAULT_MP_REPO, DOC_PATH, LEDGER_PATH, MANUAL_PATH, parseArgs, resolveCommit, scanTags, upstreamHash, WATCH_DIRS, } from "./lib.mjs"; const args = parseArgs(process.argv.slice(2)); const repo = args.mp ?? DEFAULT_MP_REPO; const defaultCommit = resolveCommit(repo, args.commit ?? "e6820a8"); const byUpstream = new Map(); function add(upstream, commitRef, ours, source) { const commit = resolveCommit(repo, commitRef); const key = upstream; const e = byUpstream.get(key) ?? { upstream, commit, sha256: null, ours: [], sources: new Set() }; if (e.commit !== commit) throw new Error(`${upstream} 在不同文件中登记了不同提交:${e.commit.slice(0, 7)} / ${commit.slice(0, 7)}`); for (const o of ours) if (!e.ours.includes(o)) e.ours.push(o); e.sources.add(source); byUpstream.set(key, e); } for (const t of scanTags()) add(t.upstream, t.commit, [t.ours], "tag"); const manual = JSON.parse(readFileSync(MANUAL_PATH, "utf8")); for (const m of manual.moviepilot ?? []) add(m.upstream, m.commit ?? defaultCommit, m.ours, "manual"); const entries = [...byUpstream.values()] .map((e) => { const h = upstreamHash(repo, e.commit, e.upstream); if (!h) throw new Error(`上游 ${e.commit.slice(0, 7)}:${e.upstream} 不存在`); return { upstream: e.upstream, commit: e.commit, sha256: h, ours: e.ours.sort(), source: [...e.sources].sort().join("+"), }; }) .sort((a, b) => a.upstream.localeCompare(b.upstream)); const ledger = { $comment: "由 scripts/mp-sync/build-ledger.mjs 生成;不要手改(改源码文件头 @mp-source 标签或 ledger.manual.json)。", upstream: { name: "MoviePilot", url: "https://github.com/jxxghp/MoviePilot", branch: "v3", license: "GPL-3.0" }, watchDirs: WATCH_DIRS, entries, }; writeFileSync(LEDGER_PATH, biomeFormat(`${JSON.stringify(ledger, null, 2)}\n`, "scripts/mp-sync/ledger.json")); // 更新文档对照总表(标记之间的内容) const BEGIN = ""; const END = ""; const rows = entries.map( (e) => `| \`${e.upstream}\` | ${e.ours.map((o) => `\`${o.replace(/^packages\/adapters\/src\//, "adapters/").replace(/^packages\/testkit\/src\//, "testkit/")}\``).join("
")} | \`${e.commit.slice(0, 7)}\` | \`${e.sha256.slice(0, 12)}\` | ${e.source} |`, ); const table = [ BEGIN, `共 ${entries.length} 个上游文件(\`adapters/\` = \`packages/adapters/src/\`)。`, "", "| 上游文件 | 本项目文件 | 移植提交 | sha256(前 12 位) | 来源 |", "| --- | --- | --- | --- | --- |", ...rows, END, ].join("\n"); const doc = readFileSync(DOC_PATH, "utf8"); const i = doc.indexOf(BEGIN); const j = doc.indexOf(END); if (i < 0 || j < 0) throw new Error(`${DOC_PATH} 缺少表格标记`); writeFileSync(DOC_PATH, doc.slice(0, i) + table + doc.slice(j + END.length)); console.log(`ledger.json:${entries.length} 个上游文件(${defaultCommit.slice(0, 7)});文档表格已更新`);