Files
drawlogo/_design-test/audit-color-only.js
T

96 lines
4.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 基座影响审计:逐行验证本次换肤的改动是否「只改颜色」
// 做法:解析 git diff -U0,把每段 hunk 的「删除行」与「新增行」都做颜色归一化
// (#RRGGBB / rgb() / rgba() → 占位符),再比对两侧是否等价。
// 等价 = 纯换色;不等价 = 有非颜色改动,单独列出待人工判断。
// 用法: node _design-test/audit-color-only.js
const { execSync } = require('child_process');
const ZF = 'e:/KF_7/ZhenOS-ZF';
const raw = execSync('git -c core.quotepath=false diff -U0 --no-color', {
cwd: ZF, maxBuffer: 1 << 28, encoding: 'utf8'
});
const CO = /#[0-9a-fA-F]{3,8}\b|rgba?\([^)]*\)|\bhsl\([^)]*\)/g;
const norm = s => s.replace(CO, '@C@').replace(/\s+/g, ' ').trim();
const isComment = s => {
const t = s.trim();
return t.startsWith('//') || t.startsWith('/*') || t.startsWith('*') ||
t.startsWith('<!--') || t.startsWith('{#') || t === '' ;
};
let curFile = '';
const offenders = [];
let hunks = 0, colorOnly = 0, commentOnly = 0, removed = 0, added = 0;
const lines = raw.split('\n');
let bucket = null;
const flush = () => {
if (!bucket) return;
const { file, oldL, newL } = bucket;
hunks++;
removed += oldL.length; added += newL.length;
const a = oldL.map(norm).sort().join('\n');
const b = newL.map(norm).sort().join('\n');
if (a === b) { colorOnly++; return; }
// 只有注释行不同 → 视为注释改动(不影响行为)
const o = oldL.filter(l => !isComment(l)), n2 = newL.filter(l => !isComment(l));
if (o.map(norm).sort().join('\n') === n2.map(norm).sort().join('\n')) { commentOnly++; return; }
offenders.push({ file, oldL, newL });
bucket = null;
};
for (const ln of lines) {
if (ln.startsWith('diff --git ')) { flush(); bucket = null; curFile = ln.split(' b/').pop(); continue; }
if (ln.startsWith('+++ ') || ln.startsWith('--- ') || ln.startsWith('index ') ||
ln.startsWith('new file') || ln.startsWith('deleted file') || ln.startsWith('similarity')) continue;
if (ln.startsWith('@@')) { flush(); bucket = { file: curFile, oldL: [], newL: [] }; continue; }
if (!bucket) continue;
if (ln.startsWith('-')) bucket.oldL.push(ln.slice(1));
else if (ln.startsWith('+')) bucket.newL.push(ln.slice(1));
}
flush();
console.log('=== 换肤改动审计(git diff -U0 逐段比对)===');
console.log(' 变更行数 新增 ' + added + ' / 删除 ' + removed);
console.log(' 代码段(hunk) 共 ' + hunks);
console.log(' · 纯颜色替换 ' + colorOnly);
console.log(' · 仅注释差异 ' + commentOnly);
console.log(' · 需要人工复核 ' + offenders.length);
// 本次「整文件重写」的样式文件 —— 它们的差异里必然含注释/结构变化,属已知改动,单列
const REWRITTEN = new Set([
'ruoyi-ui/src/assets/styles/element-variables.scss',
'ruoyi-ui/src/assets/styles/theme.scss',
'ruoyi-ui/src/assets/styles/element-ui.scss',
'ruoyi-ui/src/assets/styles/variables.scss',
'ruoyi-ui/src/assets/styles/ruoyi.scss',
'ruoyi-ui/src/assets/styles/sidebar.scss',
'ruoyi-ui/src/assets/styles/btn.scss',
'ruoyi-ui/src/assets/styles/mixin.scss',
'zhenfang-uni/src/uni.scss'
]);
const byFile = {};
offenders.forEach(o => { (byFile[o.file] = byFile[o.file] || []).push(o); });
const keys = Object.keys(byFile);
const rewritten = keys.filter(k => REWRITTEN.has(k));
const others = keys.filter(k => !REWRITTEN.has(k));
console.log('\n ── 重写类文件(已知改动,含注释/结构重排):' + rewritten.length + ' 个');
rewritten.forEach(k => console.log(' ' + String(byFile[k].length).padStart(3) + ' 段 ' + k));
console.log('\n ── 其它文件的疑似非颜色改动:' + others.length + ' 个文件');
if (!others.length) {
console.log(' 无 —— 业务页面/组件/后端相关文件全部只改了颜色');
} else {
others.forEach(k => {
console.log('\n ' + k + ' (' + byFile[k].length + ' 段)');
byFile[k].slice(0, 4).forEach(o => {
o.oldL.slice(0, 3).forEach(l => console.log(' - ' + l.trim()));
o.newL.slice(0, 3).forEach(l => console.log(' + ' + l.trim()));
console.log(' ---');
});
});
}