fix: persist repaired exclusions
This commit is contained in:
+6
-1
@@ -272,7 +272,7 @@ export async function deduplicateWithAI(findings) {
|
||||
/**
|
||||
* 讀取排除問題檔案(從來源分支的 cloned repoDir 中的 EXCLUSIONS_PATH)
|
||||
*/
|
||||
export function loadExclusions(workspace, repoState = null) {
|
||||
export function loadExclusions(workspace, repoState = null, mirrorWorkspace = null) {
|
||||
const fullPath = path.join(workspace, EXCLUSIONS_PATH);
|
||||
if (!fs.existsSync(fullPath)) {
|
||||
warn(`排除問題檔案不存在,視為空: ${fullPath}`);
|
||||
@@ -302,6 +302,11 @@ export function loadExclusions(workspace, repoState = null) {
|
||||
line(`檔案資訊: bytes=${stat.size} mtime=${formatFileTime(stat.mtimeMs)} raw=${rawCount} normalized=${exclusions.length} path=${path.relative(workspace, fullPath) || fullPath}`);
|
||||
if (sourceFormat !== 'array') {
|
||||
writeCanonicalExclusions(fullPath, normalizedSource);
|
||||
if (mirrorWorkspace && path.resolve(mirrorWorkspace) !== path.resolve(workspace)) {
|
||||
const mirrorPath = path.join(mirrorWorkspace, EXCLUSIONS_PATH);
|
||||
fs.mkdirSync(path.dirname(mirrorPath), { recursive: true });
|
||||
writeCanonicalExclusions(mirrorPath, normalizedSource);
|
||||
}
|
||||
line(`排除問題格式已修正為頂層陣列: source=${sourceFormat} -> array`);
|
||||
}
|
||||
} catch (e) {
|
||||
|
||||
@@ -60,6 +60,28 @@ describe('findings exclusions', () => {
|
||||
assert.ok(logs.some(line => line.includes('排除問題格式已修正為頂層陣列: source=exclusions -> array')));
|
||||
});
|
||||
|
||||
it('mirrors repaired exclusions into the workspace root when requested', () => {
|
||||
const repoRoot = path.join(workspace, 'repo');
|
||||
const mirrorRoot = path.join(workspace, 'workspace');
|
||||
const repoFullPath = path.join(repoRoot, EXCLUSIONS_PATH);
|
||||
const mirrorFullPath = path.join(mirrorRoot, EXCLUSIONS_PATH);
|
||||
fs.mkdirSync(path.dirname(repoFullPath), { recursive: true });
|
||||
fs.mkdirSync(path.dirname(mirrorFullPath), { recursive: true });
|
||||
fs.writeFileSync(repoFullPath, JSON.stringify({
|
||||
exclusions: [
|
||||
{ location: 'README.md:12', suggestion: 'keep' },
|
||||
],
|
||||
}, null, 2));
|
||||
|
||||
const exclusions = loadExclusions(repoRoot, null, mirrorRoot);
|
||||
const mirror = JSON.parse(fs.readFileSync(mirrorFullPath, 'utf8'));
|
||||
|
||||
assert.equal(exclusions.length, 1);
|
||||
assert.ok(Array.isArray(mirror));
|
||||
assert.equal(mirror[0].location, 'README.md:12');
|
||||
assert.equal(mirror[0].suggestion, 'keep');
|
||||
});
|
||||
|
||||
it('applies exclusions loaded from wrapper format', () => {
|
||||
const findings = [
|
||||
{ location: 'entrypoint.sh:180', role: 'Maya', suggestion: 'keep' },
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ async function main() {
|
||||
ok(`Step3 去重完成: ${mergedFindings.length} -> ${sorted.length} 筆 (critical=${sorted.filter(f=>f.level==='critical').length} warning=${sorted.filter(f=>f.level==='warning').length} info=${sorted.filter(f=>f.level==='info').length})`);
|
||||
|
||||
step('Step4', 'AI 排除問題過濾');
|
||||
const exclusions = loadExclusions(repoDir || WORKSPACE, repoState);
|
||||
const exclusions = loadExclusions(repoDir || WORKSPACE, repoState, WORKSPACE);
|
||||
const ruleFiltered = applyExclusions(sorted, exclusions);
|
||||
const filtered = await filterFalsePositivesWithAI(ruleFiltered, exclusions);
|
||||
ok(`Step4 完成: findings total=${filtered.length}`);
|
||||
|
||||
Reference in New Issue
Block a user