data: switch to recovered game DB and refresh cards and charts
Publish GitHub Pages output / publish (push) Successful in 44s
Publish GitHub Pages output / publish (push) Successful in 44s
This commit is contained in:
@@ -1,86 +1,2 @@
|
||||
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { prepareHolodoriDbSource, holodoriGit as git } from './holodoridb-source.mjs';
|
||||
import { jsonChanges } from './holodoridb-diff.mjs';
|
||||
|
||||
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const output = path.join(root, 'data/holodoridb-review');
|
||||
const baselineIndex = process.argv.indexOf('--baseline-ref');
|
||||
const baselineRef = baselineIndex < 0 ? null : process.argv[baselineIndex + 1];
|
||||
if (baselineIndex >= 0 && (!baselineRef || baselineRef.startsWith('-'))) throw new Error('--baseline-ref requires a git revision.');
|
||||
const manifest = JSON.parse(baselineRef
|
||||
? git(root, ['show', `${baselineRef}:data/holodoridb/manifest.json`])
|
||||
: await readFile(path.join(root, 'data/holodoridb/manifest.json'), 'utf8'));
|
||||
const report = { generatedAt: new Date().toISOString(), baselineCollectedAt: manifest.generatedAt, sources: {} };
|
||||
const lines = ['# HolodoriDB 전체 변경 검토', '', `마지막 수집: ${manifest.generatedAt}`, `검토 시각: ${report.generatedAt}`, '',
|
||||
'계산기 필요 여부로 필터링하지 않은 전체 원격 변경입니다. 검토는 수집 기준 커밋이나 계산기 데이터를 갱신하지 않습니다.', ''];
|
||||
const patches = [];
|
||||
for (const locale of ['eng', 'kor', 'jpn']) {
|
||||
const source = prepareHolodoriDbSource(locale, { review: true });
|
||||
const from = manifest.sources[locale].commit;
|
||||
const to = source.commit;
|
||||
// Full history is necessary: endpoint diffs alone miss changes later reverted.
|
||||
if (from !== to) {
|
||||
const shallow = git(source.repositoryPath, ['rev-parse', '--is-shallow-repository']) === 'true';
|
||||
git(source.repositoryPath, ['fetch', ...(shallow ? ['--unshallow'] : []), '--no-tags', source.repository, 'refs/heads/main']);
|
||||
try {
|
||||
git(source.repositoryPath, ['merge-base', '--is-ancestor', from, to]);
|
||||
} catch (error) {
|
||||
throw new Error(`${locale}: previous collection is not an ancestor of remote main; cannot certify a complete change report.`, { cause: error });
|
||||
}
|
||||
}
|
||||
const commits = from === to ? [] : git(source.repositoryPath, ['rev-list', '--reverse', '--topo-order', `${from}..${to}`]).split('\n').filter(Boolean);
|
||||
const entry = { from, to, repository: source.repository, commitDate: source.commitDate, commits: [], netDiff: '' };
|
||||
lines.push(`## ${locale}`, '', `기준: ${from}`, `최신: ${to}`, '');
|
||||
if (!commits.length) lines.push('변경 없음.', '');
|
||||
for (const commit of commits) {
|
||||
const title = git(source.repositoryPath, ['show', '-s', '--format=%s', commit]);
|
||||
const date = git(source.repositoryPath, ['show', '-s', '--format=%cI', commit]);
|
||||
const files = git(source.repositoryPath, ['diff-tree', '--root', '-m', '--no-commit-id', '--name-status', '-r', '--no-renames', commit]);
|
||||
const numstat = git(source.repositoryPath, ['show', '--format=', '--numstat', '--no-renames', '-m', commit]);
|
||||
const patch = git(source.repositoryPath, ['show', '--format=fuller', '--binary', '--no-ext-diff', '--no-renames', '-m', commit]);
|
||||
const parents = git(source.repositoryPath, ['show', '-s', '--format=%P', commit]).split(' ').filter(Boolean);
|
||||
const details = [];
|
||||
for (const parent of parents.length ? parents : [null]) {
|
||||
const changed = parent
|
||||
? git(source.repositoryPath, ['diff', '--name-status', '--no-renames', parent, commit])
|
||||
: files;
|
||||
for (const line of changed.split('\n').filter(Boolean)) {
|
||||
const [status, filename] = line.split('\t');
|
||||
if (!filename.endsWith('.json')) continue;
|
||||
const before = status === 'A' ? undefined : JSON.parse(git(source.repositoryPath, ['show', `${parent}:${filename}`]));
|
||||
const after = status === 'D' ? undefined : JSON.parse(git(source.repositoryPath, ['show', `${commit}:${filename}`]));
|
||||
details.push({ parent, filename, changes: jsonChanges(before, after) });
|
||||
}
|
||||
}
|
||||
entry.commits.push({ commit, title, date, files, numstat, details });
|
||||
patches.push(`Repository: ${source.repository}\n${patch}\n`);
|
||||
const fileLines = files.split('\n').filter(Boolean);
|
||||
const strings = fileLines.filter(line => /\tLang[^\t]*\.json$/.test(line));
|
||||
const masters = fileLines.filter(line => /\.json$/.test(line) && !strings.includes(line));
|
||||
const other = fileLines.filter(line => !strings.includes(line) && !masters.includes(line));
|
||||
lines.push(`### ${commit.slice(0, 8)} — ${title}`, '', `시각: ${date}`, '',
|
||||
`문자열 ${strings.length}건 · 마스터 JSON ${masters.length}건 · 기타 ${other.length}건`, '');
|
||||
for (const [label, group] of [['문자열', strings], ['마스터 JSON', masters], ['기타', other]]) {
|
||||
if (group.length) lines.push(`**${label}** (A 추가 / M 수정 / D 삭제)`, '', '```text', ...group, '```', '');
|
||||
}
|
||||
lines.push('파일별 추가·삭제 줄 수:', '', '```text', numstat, '```', '');
|
||||
for (const detail of details) {
|
||||
const counts = Object.fromEntries(['added', 'deleted', 'modified'].map(type => [type, detail.changes.filter(change => change.type === type).length]));
|
||||
lines.push(`- ${detail.filename}: 항목/필드 추가 ${counts.added}, 삭제 ${counts.deleted}, 수정 ${counts.modified}`);
|
||||
}
|
||||
lines.push('', '전체 변경 항목의 ID·필드 경로·변경 전후 값은 latest.json의 details에 기록했습니다.', '');
|
||||
}
|
||||
entry.netDiff = from === to ? '' : git(source.repositoryPath, ['diff', '--stat', from, to]);
|
||||
report.sources[locale] = entry;
|
||||
}
|
||||
lines.push('## 후속 작업', '', 'changes.patch의 전체 필드·문자열 변경을 읽고 사용자에게 의미와 영향을 요약해 먼저 제공합니다. 그 다음 계산기 데이터 확보를 진행합니다.', '',
|
||||
'계산기 반영: `npm run data:apply`. 원격 커밋이 검토 이후 바뀌면 다시 검토해야 합니다.', '');
|
||||
await mkdir(output, { recursive: true });
|
||||
await writeFile(path.join(output, 'changes.patch'), patches.join('\n'), 'utf8');
|
||||
await writeFile(path.join(output, 'latest.md'), lines.join('\n'), 'utf8');
|
||||
// Publish the machine-readable review marker only after all three locales succeed.
|
||||
await writeFile(path.join(output, 'latest.json'), `${JSON.stringify(report, null, 2)}\n`, 'utf8');
|
||||
console.log(lines.join('\n'));
|
||||
console.log(`Full changes: ${path.join(output, 'changes.patch')}`);
|
||||
// Compatibility command: no network fetch or legacy fallback.
|
||||
import './review-game-db.mjs';
|
||||
|
||||
Reference in New Issue
Block a user