@diff-review-system/drs 1.0.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.opencode/agent/github-reviewer.md +22 -7
- package/.opencode/agent/gitlab-reviewer.md +22 -7
- package/.opencode/agent/local-reviewer.md +21 -29
- package/.opencode/agent/review/performance.md +22 -13
- package/.opencode/agent/review/quality.md +22 -13
- package/.opencode/agent/review/security.md +22 -19
- package/.opencode/agent/review/style.md +22 -10
- package/.opencode/opencode.jsonc +7 -19
- package/README.md +175 -69
- package/dist/ci/runner.d.ts.map +1 -1
- package/dist/ci/runner.js +2 -4
- package/dist/ci/runner.js.map +1 -1
- package/dist/cli/index.js +14 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +112 -23
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/review-local.d.ts.map +1 -1
- package/dist/cli/review-local.js +27 -70
- package/dist/cli/review-local.js.map +1 -1
- package/dist/cli/review-mr.d.ts +1 -0
- package/dist/cli/review-mr.d.ts.map +1 -1
- package/dist/cli/review-mr.js +34 -119
- package/dist/cli/review-mr.js.map +1 -1
- package/dist/cli/review-pr.d.ts.map +1 -1
- package/dist/cli/review-pr.js +74 -114
- package/dist/cli/review-pr.js.map +1 -1
- package/dist/github/client.d.ts +199 -4
- package/dist/github/client.d.ts.map +1 -1
- package/dist/github/client.js +37 -2
- package/dist/github/client.js.map +1 -1
- package/dist/github/client.test.d.ts +2 -0
- package/dist/github/client.test.d.ts.map +1 -0
- package/dist/github/client.test.js +206 -0
- package/dist/github/client.test.js.map +1 -0
- package/dist/github/platform-adapter.d.ts +31 -0
- package/dist/github/platform-adapter.d.ts.map +1 -0
- package/dist/github/platform-adapter.js +127 -0
- package/dist/github/platform-adapter.js.map +1 -0
- package/dist/github/platform-adapter.test.d.ts +2 -0
- package/dist/github/platform-adapter.test.d.ts.map +1 -0
- package/dist/github/platform-adapter.test.js +40 -0
- package/dist/github/platform-adapter.test.js.map +1 -0
- package/dist/gitlab/client.d.ts +12 -0
- package/dist/gitlab/client.d.ts.map +1 -1
- package/dist/gitlab/client.js +18 -0
- package/dist/gitlab/client.js.map +1 -1
- package/dist/gitlab/diff-parser.test.d.ts +2 -0
- package/dist/gitlab/diff-parser.test.d.ts.map +1 -0
- package/dist/gitlab/diff-parser.test.js +315 -0
- package/dist/gitlab/diff-parser.test.js.map +1 -0
- package/dist/gitlab/platform-adapter.d.ts +27 -0
- package/dist/gitlab/platform-adapter.d.ts.map +1 -0
- package/dist/gitlab/platform-adapter.js +120 -0
- package/dist/gitlab/platform-adapter.js.map +1 -0
- package/dist/gitlab/platform-adapter.test.d.ts +2 -0
- package/dist/gitlab/platform-adapter.test.d.ts.map +1 -0
- package/dist/gitlab/platform-adapter.test.js +21 -0
- package/dist/gitlab/platform-adapter.test.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +7 -0
- package/dist/index.test.js.map +1 -0
- package/dist/lib/code-quality-report.d.ts +44 -0
- package/dist/lib/code-quality-report.d.ts.map +1 -0
- package/dist/lib/code-quality-report.js +62 -0
- package/dist/lib/code-quality-report.js.map +1 -0
- package/dist/lib/code-quality-report.test.d.ts +2 -0
- package/dist/lib/code-quality-report.test.d.ts.map +1 -0
- package/dist/lib/code-quality-report.test.js +327 -0
- package/dist/lib/code-quality-report.test.js.map +1 -0
- package/dist/{gitlab → lib}/comment-formatter.d.ts +4 -2
- package/dist/lib/comment-formatter.d.ts.map +1 -0
- package/dist/{gitlab → lib}/comment-formatter.js +48 -15
- package/dist/lib/comment-formatter.js.map +1 -0
- package/dist/lib/comment-manager.d.ts +61 -0
- package/dist/lib/comment-manager.d.ts.map +1 -0
- package/dist/lib/comment-manager.js +91 -0
- package/dist/lib/comment-manager.js.map +1 -0
- package/dist/lib/config-model-overrides.test.d.ts +12 -0
- package/dist/lib/config-model-overrides.test.d.ts.map +1 -0
- package/dist/lib/config-model-overrides.test.js +224 -0
- package/dist/lib/config-model-overrides.test.js.map +1 -0
- package/dist/lib/config.d.ts +30 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +70 -11
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/config.test.d.ts +2 -0
- package/dist/lib/config.test.d.ts.map +1 -0
- package/dist/lib/config.test.js +28 -0
- package/dist/lib/config.test.js.map +1 -0
- package/dist/lib/context-loader.d.ts +29 -0
- package/dist/lib/context-loader.d.ts.map +1 -0
- package/dist/lib/context-loader.js +68 -0
- package/dist/lib/context-loader.js.map +1 -0
- package/dist/lib/diff-parser.d.ts.map +1 -0
- package/dist/{gitlab → lib}/diff-parser.js +3 -3
- package/dist/lib/diff-parser.js.map +1 -0
- package/dist/lib/issue-parser.d.ts +29 -0
- package/dist/lib/issue-parser.d.ts.map +1 -0
- package/dist/lib/issue-parser.js +151 -0
- package/dist/lib/issue-parser.js.map +1 -0
- package/dist/lib/issue-parser.test.d.ts +2 -0
- package/dist/lib/issue-parser.test.d.ts.map +1 -0
- package/dist/lib/issue-parser.test.js +281 -0
- package/dist/lib/issue-parser.test.js.map +1 -0
- package/dist/lib/platform-client.d.ts +130 -0
- package/dist/lib/platform-client.d.ts.map +1 -0
- package/dist/lib/platform-client.js +8 -0
- package/dist/lib/platform-client.js.map +1 -0
- package/dist/lib/position-validator.d.ts +36 -0
- package/dist/lib/position-validator.d.ts.map +1 -0
- package/dist/lib/position-validator.js +43 -0
- package/dist/lib/position-validator.js.map +1 -0
- package/dist/lib/review-orchestrator.d.ts +60 -0
- package/dist/lib/review-orchestrator.d.ts.map +1 -0
- package/dist/lib/review-orchestrator.js +183 -0
- package/dist/lib/review-orchestrator.js.map +1 -0
- package/dist/lib/unified-review-executor.d.ts +32 -0
- package/dist/lib/unified-review-executor.d.ts.map +1 -0
- package/dist/lib/unified-review-executor.js +228 -0
- package/dist/lib/unified-review-executor.js.map +1 -0
- package/dist/opencode/agent-loader.d.ts.map +1 -1
- package/dist/opencode/agent-loader.js +5 -10
- package/dist/opencode/agent-loader.js.map +1 -1
- package/dist/opencode/client.d.ts +3 -2
- package/dist/opencode/client.d.ts.map +1 -1
- package/dist/opencode/client.js +141 -28
- package/dist/opencode/client.js.map +1 -1
- package/package.json +28 -19
- package/dist/gitlab/comment-formatter.d.ts.map +0 -1
- package/dist/gitlab/comment-formatter.js.map +0 -1
- package/dist/gitlab/diff-parser.d.ts.map +0 -1
- package/dist/gitlab/diff-parser.js.map +0 -1
- /package/dist/{gitlab → lib}/diff-parser.d.ts +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-quality-report.test.d.ts","sourceRoot":"","sources":["../../src/lib/code-quality-report.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { convertToCodeQualityIssue, generateCodeQualityReport, formatCodeQualityReport, } from './code-quality-report.js';
|
|
3
|
+
describe('code-quality-report', () => {
|
|
4
|
+
describe('convertToCodeQualityIssue', () => {
|
|
5
|
+
it('should convert a DRS issue to GitLab code quality format', () => {
|
|
6
|
+
const drsIssue = {
|
|
7
|
+
category: 'SECURITY',
|
|
8
|
+
severity: 'CRITICAL',
|
|
9
|
+
title: 'SQL Injection',
|
|
10
|
+
file: 'src/api/users.ts',
|
|
11
|
+
line: 42,
|
|
12
|
+
problem: 'Query uses string concatenation.',
|
|
13
|
+
solution: 'Use parameterized queries instead.',
|
|
14
|
+
agent: 'security',
|
|
15
|
+
};
|
|
16
|
+
const result = convertToCodeQualityIssue(drsIssue);
|
|
17
|
+
expect(result).toMatchObject({
|
|
18
|
+
description: 'Query uses string concatenation. Use parameterized queries instead.',
|
|
19
|
+
check_name: 'drs-security',
|
|
20
|
+
severity: 'blocker',
|
|
21
|
+
location: {
|
|
22
|
+
path: 'src/api/users.ts',
|
|
23
|
+
lines: {
|
|
24
|
+
begin: 42,
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
expect(result.fingerprint).toBeDefined();
|
|
29
|
+
expect(result.fingerprint.length).toBeGreaterThan(0);
|
|
30
|
+
});
|
|
31
|
+
it('should map CRITICAL severity to blocker', () => {
|
|
32
|
+
const issue = {
|
|
33
|
+
category: 'SECURITY',
|
|
34
|
+
severity: 'CRITICAL',
|
|
35
|
+
title: 'Test',
|
|
36
|
+
file: 'test.ts',
|
|
37
|
+
line: 1,
|
|
38
|
+
problem: 'Problem',
|
|
39
|
+
solution: 'Solution',
|
|
40
|
+
agent: 'test',
|
|
41
|
+
};
|
|
42
|
+
const result = convertToCodeQualityIssue(issue);
|
|
43
|
+
expect(result.severity).toBe('blocker');
|
|
44
|
+
});
|
|
45
|
+
it('should map HIGH severity to critical', () => {
|
|
46
|
+
const issue = {
|
|
47
|
+
category: 'QUALITY',
|
|
48
|
+
severity: 'HIGH',
|
|
49
|
+
title: 'Test',
|
|
50
|
+
file: 'test.ts',
|
|
51
|
+
line: 1,
|
|
52
|
+
problem: 'Problem',
|
|
53
|
+
solution: 'Solution',
|
|
54
|
+
agent: 'test',
|
|
55
|
+
};
|
|
56
|
+
const result = convertToCodeQualityIssue(issue);
|
|
57
|
+
expect(result.severity).toBe('critical');
|
|
58
|
+
});
|
|
59
|
+
it('should map MEDIUM severity to major', () => {
|
|
60
|
+
const issue = {
|
|
61
|
+
category: 'QUALITY',
|
|
62
|
+
severity: 'MEDIUM',
|
|
63
|
+
title: 'Test',
|
|
64
|
+
file: 'test.ts',
|
|
65
|
+
line: 1,
|
|
66
|
+
problem: 'Problem',
|
|
67
|
+
solution: 'Solution',
|
|
68
|
+
agent: 'test',
|
|
69
|
+
};
|
|
70
|
+
const result = convertToCodeQualityIssue(issue);
|
|
71
|
+
expect(result.severity).toBe('major');
|
|
72
|
+
});
|
|
73
|
+
it('should map LOW severity to minor', () => {
|
|
74
|
+
const issue = {
|
|
75
|
+
category: 'STYLE',
|
|
76
|
+
severity: 'LOW',
|
|
77
|
+
title: 'Test',
|
|
78
|
+
file: 'test.ts',
|
|
79
|
+
line: 1,
|
|
80
|
+
problem: 'Problem',
|
|
81
|
+
solution: 'Solution',
|
|
82
|
+
agent: 'test',
|
|
83
|
+
};
|
|
84
|
+
const result = convertToCodeQualityIssue(issue);
|
|
85
|
+
expect(result.severity).toBe('minor');
|
|
86
|
+
});
|
|
87
|
+
it('should generate check_name from category', () => {
|
|
88
|
+
const issue = {
|
|
89
|
+
category: 'QUALITY',
|
|
90
|
+
severity: 'MEDIUM',
|
|
91
|
+
title: 'Test',
|
|
92
|
+
file: 'test.ts',
|
|
93
|
+
line: 1,
|
|
94
|
+
problem: 'Problem',
|
|
95
|
+
solution: 'Solution',
|
|
96
|
+
agent: 'test',
|
|
97
|
+
};
|
|
98
|
+
const result = convertToCodeQualityIssue(issue);
|
|
99
|
+
expect(result.check_name).toBe('drs-quality');
|
|
100
|
+
});
|
|
101
|
+
it('should handle issues with empty solution', () => {
|
|
102
|
+
const issue = {
|
|
103
|
+
category: 'SECURITY',
|
|
104
|
+
severity: 'HIGH',
|
|
105
|
+
title: 'Test',
|
|
106
|
+
file: 'test.ts',
|
|
107
|
+
line: 1,
|
|
108
|
+
problem: 'This is a problem',
|
|
109
|
+
solution: '',
|
|
110
|
+
agent: 'test',
|
|
111
|
+
};
|
|
112
|
+
const result = convertToCodeQualityIssue(issue);
|
|
113
|
+
expect(result.description).toBe('This is a problem');
|
|
114
|
+
});
|
|
115
|
+
it('should default to line 1 if no line number provided', () => {
|
|
116
|
+
const issue = {
|
|
117
|
+
category: 'STYLE',
|
|
118
|
+
severity: 'LOW',
|
|
119
|
+
title: 'Missing header',
|
|
120
|
+
file: 'src/main.ts',
|
|
121
|
+
problem: 'No copyright header',
|
|
122
|
+
solution: 'Add standard file header',
|
|
123
|
+
agent: 'test',
|
|
124
|
+
};
|
|
125
|
+
const result = convertToCodeQualityIssue(issue);
|
|
126
|
+
expect(result.location.lines.begin).toBe(1);
|
|
127
|
+
});
|
|
128
|
+
it('should create consistent fingerprints for identical issues', () => {
|
|
129
|
+
const issue1 = {
|
|
130
|
+
category: 'SECURITY',
|
|
131
|
+
severity: 'CRITICAL',
|
|
132
|
+
title: 'Test',
|
|
133
|
+
file: 'test.ts',
|
|
134
|
+
line: 42,
|
|
135
|
+
problem: 'Problem',
|
|
136
|
+
solution: 'Solution',
|
|
137
|
+
agent: 'test',
|
|
138
|
+
};
|
|
139
|
+
const issue2 = {
|
|
140
|
+
category: 'SECURITY',
|
|
141
|
+
severity: 'CRITICAL',
|
|
142
|
+
title: 'Test',
|
|
143
|
+
file: 'test.ts',
|
|
144
|
+
line: 42,
|
|
145
|
+
problem: 'Problem',
|
|
146
|
+
solution: 'Solution',
|
|
147
|
+
agent: 'test',
|
|
148
|
+
};
|
|
149
|
+
const result1 = convertToCodeQualityIssue(issue1);
|
|
150
|
+
const result2 = convertToCodeQualityIssue(issue2);
|
|
151
|
+
expect(result1.fingerprint).toBe(result2.fingerprint);
|
|
152
|
+
});
|
|
153
|
+
it('should create different fingerprints for different issues', () => {
|
|
154
|
+
const issue1 = {
|
|
155
|
+
category: 'SECURITY',
|
|
156
|
+
severity: 'CRITICAL',
|
|
157
|
+
title: 'Test',
|
|
158
|
+
file: 'test.ts',
|
|
159
|
+
line: 42,
|
|
160
|
+
problem: 'Problem',
|
|
161
|
+
solution: 'Solution',
|
|
162
|
+
agent: 'test',
|
|
163
|
+
};
|
|
164
|
+
const issue2 = {
|
|
165
|
+
category: 'SECURITY',
|
|
166
|
+
severity: 'CRITICAL',
|
|
167
|
+
title: 'Test',
|
|
168
|
+
file: 'test.ts',
|
|
169
|
+
line: 43, // Different line
|
|
170
|
+
problem: 'Problem',
|
|
171
|
+
solution: 'Solution',
|
|
172
|
+
agent: 'test',
|
|
173
|
+
};
|
|
174
|
+
const result1 = convertToCodeQualityIssue(issue1);
|
|
175
|
+
const result2 = convertToCodeQualityIssue(issue2);
|
|
176
|
+
expect(result1.fingerprint).not.toBe(result2.fingerprint);
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
describe('generateCodeQualityReport', () => {
|
|
180
|
+
it('should convert multiple DRS issues to code quality format', () => {
|
|
181
|
+
const issues = [
|
|
182
|
+
{
|
|
183
|
+
category: 'SECURITY',
|
|
184
|
+
severity: 'CRITICAL',
|
|
185
|
+
title: 'SQL Injection',
|
|
186
|
+
file: 'src/api/users.ts',
|
|
187
|
+
line: 42,
|
|
188
|
+
problem: 'Query uses string concatenation',
|
|
189
|
+
solution: 'Use parameterized queries',
|
|
190
|
+
agent: 'security',
|
|
191
|
+
},
|
|
192
|
+
{
|
|
193
|
+
category: 'QUALITY',
|
|
194
|
+
severity: 'HIGH',
|
|
195
|
+
title: 'High complexity',
|
|
196
|
+
file: 'src/utils/helper.ts',
|
|
197
|
+
line: 10,
|
|
198
|
+
problem: 'Function has cyclomatic complexity of 15',
|
|
199
|
+
solution: 'Break into smaller functions',
|
|
200
|
+
agent: 'quality',
|
|
201
|
+
},
|
|
202
|
+
];
|
|
203
|
+
const report = generateCodeQualityReport(issues);
|
|
204
|
+
expect(report).toHaveLength(2);
|
|
205
|
+
expect(report[0].severity).toBe('blocker');
|
|
206
|
+
expect(report[0].check_name).toBe('drs-security');
|
|
207
|
+
expect(report[1].severity).toBe('critical');
|
|
208
|
+
expect(report[1].check_name).toBe('drs-quality');
|
|
209
|
+
});
|
|
210
|
+
it('should handle empty issues array', () => {
|
|
211
|
+
const report = generateCodeQualityReport([]);
|
|
212
|
+
expect(report).toEqual([]);
|
|
213
|
+
});
|
|
214
|
+
it('should preserve all issues in order', () => {
|
|
215
|
+
const issues = [
|
|
216
|
+
{
|
|
217
|
+
category: 'SECURITY',
|
|
218
|
+
severity: 'CRITICAL',
|
|
219
|
+
title: 'First',
|
|
220
|
+
file: 'a.ts',
|
|
221
|
+
line: 1,
|
|
222
|
+
problem: 'Problem 1',
|
|
223
|
+
solution: 'Solution 1',
|
|
224
|
+
agent: 'test',
|
|
225
|
+
},
|
|
226
|
+
{
|
|
227
|
+
category: 'QUALITY',
|
|
228
|
+
severity: 'MEDIUM',
|
|
229
|
+
title: 'Second',
|
|
230
|
+
file: 'b.ts',
|
|
231
|
+
line: 2,
|
|
232
|
+
problem: 'Problem 2',
|
|
233
|
+
solution: 'Solution 2',
|
|
234
|
+
agent: 'test',
|
|
235
|
+
},
|
|
236
|
+
{
|
|
237
|
+
category: 'STYLE',
|
|
238
|
+
severity: 'LOW',
|
|
239
|
+
title: 'Third',
|
|
240
|
+
file: 'c.ts',
|
|
241
|
+
line: 3,
|
|
242
|
+
problem: 'Problem 3',
|
|
243
|
+
solution: 'Solution 3',
|
|
244
|
+
agent: 'test',
|
|
245
|
+
},
|
|
246
|
+
];
|
|
247
|
+
const report = generateCodeQualityReport(issues);
|
|
248
|
+
expect(report).toHaveLength(3);
|
|
249
|
+
expect(report[0].location.path).toBe('a.ts');
|
|
250
|
+
expect(report[1].location.path).toBe('b.ts');
|
|
251
|
+
expect(report[2].location.path).toBe('c.ts');
|
|
252
|
+
});
|
|
253
|
+
});
|
|
254
|
+
describe('formatCodeQualityReport', () => {
|
|
255
|
+
it('should format report as valid JSON', () => {
|
|
256
|
+
const report = [
|
|
257
|
+
{
|
|
258
|
+
description: 'Query uses string concatenation',
|
|
259
|
+
check_name: 'drs-security',
|
|
260
|
+
fingerprint: 'abc123',
|
|
261
|
+
severity: 'blocker',
|
|
262
|
+
location: {
|
|
263
|
+
path: 'src/api/users.ts',
|
|
264
|
+
lines: {
|
|
265
|
+
begin: 42,
|
|
266
|
+
},
|
|
267
|
+
},
|
|
268
|
+
},
|
|
269
|
+
];
|
|
270
|
+
const json = formatCodeQualityReport(report);
|
|
271
|
+
expect(() => JSON.parse(json)).not.toThrow();
|
|
272
|
+
const parsed = JSON.parse(json);
|
|
273
|
+
expect(parsed).toHaveLength(1);
|
|
274
|
+
expect(parsed[0].description).toBe('Query uses string concatenation');
|
|
275
|
+
});
|
|
276
|
+
it('should format with pretty printing', () => {
|
|
277
|
+
const report = [
|
|
278
|
+
{
|
|
279
|
+
description: 'Test issue',
|
|
280
|
+
check_name: 'drs-test',
|
|
281
|
+
fingerprint: 'test123',
|
|
282
|
+
severity: 'minor',
|
|
283
|
+
location: {
|
|
284
|
+
path: 'test.ts',
|
|
285
|
+
lines: {
|
|
286
|
+
begin: 1,
|
|
287
|
+
},
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
];
|
|
291
|
+
const json = formatCodeQualityReport(report);
|
|
292
|
+
// Should have indentation (pretty printed)
|
|
293
|
+
expect(json).toContain('\n');
|
|
294
|
+
expect(json).toContain(' ');
|
|
295
|
+
});
|
|
296
|
+
it('should handle empty report', () => {
|
|
297
|
+
const json = formatCodeQualityReport([]);
|
|
298
|
+
expect(json).toBe('[]');
|
|
299
|
+
});
|
|
300
|
+
it('should produce valid GitLab code quality format', () => {
|
|
301
|
+
const report = [
|
|
302
|
+
{
|
|
303
|
+
description: "'unused' is assigned a value but never used.",
|
|
304
|
+
check_name: 'no-unused-vars',
|
|
305
|
+
fingerprint: '7815696ecbf1c96e6894b779456d330e',
|
|
306
|
+
severity: 'minor',
|
|
307
|
+
location: {
|
|
308
|
+
path: 'lib/index.js',
|
|
309
|
+
lines: {
|
|
310
|
+
begin: 42,
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
},
|
|
314
|
+
];
|
|
315
|
+
const json = formatCodeQualityReport(report);
|
|
316
|
+
const parsed = JSON.parse(json);
|
|
317
|
+
// Verify all required fields are present
|
|
318
|
+
expect(parsed[0]).toHaveProperty('description');
|
|
319
|
+
expect(parsed[0]).toHaveProperty('fingerprint');
|
|
320
|
+
expect(parsed[0]).toHaveProperty('location');
|
|
321
|
+
expect(parsed[0].location).toHaveProperty('path');
|
|
322
|
+
expect(parsed[0].location).toHaveProperty('lines');
|
|
323
|
+
expect(parsed[0].location.lines).toHaveProperty('begin');
|
|
324
|
+
});
|
|
325
|
+
});
|
|
326
|
+
});
|
|
327
|
+
//# sourceMappingURL=code-quality-report.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-quality-report.test.js","sourceRoot":"","sources":["../../src/lib/code-quality-report.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,12 +19,14 @@ export interface ReviewSummary {
|
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
21
|
* Format a single review issue as a GitLab comment
|
|
22
|
+
* @param fingerprint Optional fingerprint to embed in comment for deduplication
|
|
22
23
|
*/
|
|
23
|
-
export declare function formatIssueComment(issue: ReviewIssue): string;
|
|
24
|
+
export declare function formatIssueComment(issue: ReviewIssue, fingerprint?: string): string;
|
|
24
25
|
/**
|
|
25
26
|
* Format a review summary as a GitLab comment
|
|
27
|
+
* @param commentId Optional comment ID to embed for update identification
|
|
26
28
|
*/
|
|
27
|
-
export declare function formatSummaryComment(summary: ReviewSummary, issues: ReviewIssue[]): string;
|
|
29
|
+
export declare function formatSummaryComment(summary: ReviewSummary, issues: ReviewIssue[], commentId?: string): string;
|
|
28
30
|
/**
|
|
29
31
|
* Format issue for terminal output with colors
|
|
30
32
|
*/
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-formatter.d.ts","sourceRoot":"","sources":["../../src/lib/comment-formatter.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AACnE,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,SAAS,GAAG,OAAO,GAAG,aAAa,CAAC;AAE7E,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,EAAE,aAAa,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;CAC3C;AAgBD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,WAAW,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CA0BnF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,WAAW,EAAE,EACrB,SAAS,CAAC,EAAE,MAAM,GACjB,MAAM,CA8ER;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAY9D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,aAAa,CAwB5F"}
|
|
@@ -12,14 +12,20 @@ const CATEGORY_EMOJI = {
|
|
|
12
12
|
};
|
|
13
13
|
/**
|
|
14
14
|
* Format a single review issue as a GitLab comment
|
|
15
|
+
* @param fingerprint Optional fingerprint to embed in comment for deduplication
|
|
15
16
|
*/
|
|
16
|
-
export function formatIssueComment(issue) {
|
|
17
|
+
export function formatIssueComment(issue, fingerprint) {
|
|
17
18
|
const emoji = CATEGORY_EMOJI[issue.category];
|
|
18
19
|
const severityEmoji = SEVERITY_EMOJI[issue.severity];
|
|
19
|
-
|
|
20
|
+
// Add hidden fingerprint for deduplication
|
|
21
|
+
let comment = '';
|
|
22
|
+
if (fingerprint) {
|
|
23
|
+
comment += `<!-- issue-fp: ${fingerprint} -->\n`;
|
|
24
|
+
}
|
|
25
|
+
comment += `## ${emoji} ${issue.category} - ${issue.title}\n\n`;
|
|
20
26
|
comment += `**File**: \`${issue.file}${issue.line ? `:${issue.line}` : ''}\`\n`;
|
|
21
27
|
comment += `**Severity**: ${severityEmoji} ${issue.severity}\n`;
|
|
22
|
-
comment += `**
|
|
28
|
+
comment += `**Analysis by**: ${issue.agent}\n\n`;
|
|
23
29
|
comment += `### Problem\n${issue.problem}\n\n`;
|
|
24
30
|
comment += `### Solution\n${issue.solution}\n`;
|
|
25
31
|
if (issue.references && issue.references.length > 0) {
|
|
@@ -32,9 +38,15 @@ export function formatIssueComment(issue) {
|
|
|
32
38
|
}
|
|
33
39
|
/**
|
|
34
40
|
* Format a review summary as a GitLab comment
|
|
41
|
+
* @param commentId Optional comment ID to embed for update identification
|
|
35
42
|
*/
|
|
36
|
-
export function formatSummaryComment(summary, issues) {
|
|
37
|
-
|
|
43
|
+
export function formatSummaryComment(summary, issues, commentId) {
|
|
44
|
+
// Add hidden identifier for update-or-create logic
|
|
45
|
+
let comment = '';
|
|
46
|
+
if (commentId) {
|
|
47
|
+
comment += `<!-- drs-comment-id: ${commentId} -->\n`;
|
|
48
|
+
}
|
|
49
|
+
comment += `# 📋 Code Review Analysis\n\n`;
|
|
38
50
|
comment += `## 📊 Statistics\n\n`;
|
|
39
51
|
comment += `- **Files Reviewed**: ${summary.filesReviewed}\n`;
|
|
40
52
|
comment += `- **Total Issues**: ${summary.issuesFound}\n\n`;
|
|
@@ -49,30 +61,51 @@ export function formatSummaryComment(summary, issues) {
|
|
|
49
61
|
comment += `- ${CATEGORY_EMOJI.QUALITY} **Quality**: ${summary.byCategory.QUALITY}\n`;
|
|
50
62
|
comment += `- ${CATEGORY_EMOJI.STYLE} **Style**: ${summary.byCategory.STYLE}\n`;
|
|
51
63
|
comment += `- ${CATEGORY_EMOJI.PERFORMANCE} **Performance**: ${summary.byCategory.PERFORMANCE}\n\n`;
|
|
52
|
-
//
|
|
53
|
-
const criticalIssues = issues.filter(i => i.severity === 'CRITICAL');
|
|
54
|
-
const highIssues = issues.filter(i => i.severity === 'HIGH');
|
|
64
|
+
// Group issues by severity
|
|
65
|
+
const criticalIssues = issues.filter((i) => i.severity === 'CRITICAL');
|
|
66
|
+
const highIssues = issues.filter((i) => i.severity === 'HIGH');
|
|
67
|
+
const mediumIssues = issues.filter((i) => i.severity === 'MEDIUM');
|
|
68
|
+
const lowIssues = issues.filter((i) => i.severity === 'LOW');
|
|
69
|
+
// Helper function to format issue details
|
|
70
|
+
const formatIssueDetails = (issue) => {
|
|
71
|
+
let details = `### ${CATEGORY_EMOJI[issue.category]} ${issue.title}\n\n`;
|
|
72
|
+
details += `**File**: \`${issue.file}${issue.line ? `:${issue.line}` : ''}\` | **Category**: ${issue.category}\n\n`;
|
|
73
|
+
details += `**Problem**: ${issue.problem}\n\n`;
|
|
74
|
+
details += `**Solution**: ${issue.solution}\n`;
|
|
75
|
+
if (issue.references && issue.references.length > 0) {
|
|
76
|
+
details += `\n**References**: ${issue.references.join(', ')}\n`;
|
|
77
|
+
}
|
|
78
|
+
return details + '\n';
|
|
79
|
+
};
|
|
55
80
|
if (criticalIssues.length > 0) {
|
|
56
81
|
comment += `## 🔴 Critical Issues\n\n`;
|
|
57
82
|
for (const issue of criticalIssues) {
|
|
58
|
-
comment +=
|
|
83
|
+
comment += formatIssueDetails(issue);
|
|
59
84
|
}
|
|
60
|
-
comment += `\n`;
|
|
61
85
|
}
|
|
62
86
|
if (highIssues.length > 0) {
|
|
63
87
|
comment += `## 🟡 High Priority Issues\n\n`;
|
|
64
88
|
for (const issue of highIssues) {
|
|
65
|
-
comment +=
|
|
89
|
+
comment += formatIssueDetails(issue);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (mediumIssues.length > 0) {
|
|
93
|
+
comment += `## 🟠 Medium Priority Issues\n\n`;
|
|
94
|
+
for (const issue of mediumIssues) {
|
|
95
|
+
comment += formatIssueDetails(issue);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (lowIssues.length > 0) {
|
|
99
|
+
comment += `## ⚪ Low Priority Issues\n\n`;
|
|
100
|
+
for (const issue of lowIssues) {
|
|
101
|
+
comment += formatIssueDetails(issue);
|
|
66
102
|
}
|
|
67
|
-
comment += `\n`;
|
|
68
103
|
}
|
|
69
|
-
comment += `\n---\n`;
|
|
70
|
-
comment += `*Detailed findings have been posted as individual discussion threads on the affected lines.*\n`;
|
|
71
104
|
}
|
|
72
105
|
else {
|
|
73
106
|
comment += `✅ **No issues found!** The code looks good.\n`;
|
|
74
107
|
}
|
|
75
|
-
comment += `\n*
|
|
108
|
+
comment += `\n---\n\n*Analyzed by **DRS** | Diff Review System*\n`;
|
|
76
109
|
return comment;
|
|
77
110
|
}
|
|
78
111
|
/**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-formatter.js","sourceRoot":"","sources":["../../src/lib/comment-formatter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { ReviewIssue } from './comment-formatter.js';
|
|
2
|
+
/**
|
|
3
|
+
* Platform-agnostic comment management for deduplication and updates
|
|
4
|
+
*/
|
|
5
|
+
export declare const BOT_COMMENT_ID = "drs-review-summary";
|
|
6
|
+
/**
|
|
7
|
+
* Create a unique fingerprint for an issue to detect duplicates
|
|
8
|
+
*/
|
|
9
|
+
export declare function createIssueFingerprint(issue: ReviewIssue): string;
|
|
10
|
+
/**
|
|
11
|
+
* Extract bot comment ID from comment body
|
|
12
|
+
*/
|
|
13
|
+
export declare function extractCommentId(body: string): string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Extract issue fingerprints from comment body
|
|
16
|
+
*/
|
|
17
|
+
export declare function extractIssueFingerprints(body: string): Set<string>;
|
|
18
|
+
/**
|
|
19
|
+
* Filter issues to only include CRITICAL and HIGH severity
|
|
20
|
+
* (for inline comments - reduces noise and API calls)
|
|
21
|
+
*/
|
|
22
|
+
export declare function filterCriticalAndHigh(issues: ReviewIssue[]): ReviewIssue[];
|
|
23
|
+
/**
|
|
24
|
+
* Filter out duplicate issues based on existing fingerprints
|
|
25
|
+
*/
|
|
26
|
+
export declare function filterDuplicateIssues(issues: ReviewIssue[], existingFingerprints: Set<string>): ReviewIssue[];
|
|
27
|
+
/**
|
|
28
|
+
* Represents a comment from any platform
|
|
29
|
+
*/
|
|
30
|
+
export interface PlatformComment {
|
|
31
|
+
id: number | string;
|
|
32
|
+
body: string;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Find existing summary comment using bot marker
|
|
36
|
+
*/
|
|
37
|
+
export declare function findExistingSummaryComment(comments: PlatformComment[]): PlatformComment | null;
|
|
38
|
+
/**
|
|
39
|
+
* Collect all existing issue fingerprints from comments
|
|
40
|
+
*/
|
|
41
|
+
export declare function collectExistingFingerprints(comments: PlatformComment[]): Set<string>;
|
|
42
|
+
/**
|
|
43
|
+
* Result of preparing issues for posting
|
|
44
|
+
*/
|
|
45
|
+
export interface PreparedIssues {
|
|
46
|
+
/** Issues to post as inline comments (CRITICAL/HIGH, new, with valid lines) */
|
|
47
|
+
inlineIssues: ReviewIssue[];
|
|
48
|
+
/** Number of issues that were deduplicated */
|
|
49
|
+
deduplicatedCount: number;
|
|
50
|
+
/** Number of medium/low severity issues (not posted inline) */
|
|
51
|
+
nonInlineCount: number;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Prepare issues for posting, applying all filters:
|
|
55
|
+
* 1. Filter to CRITICAL/HIGH severity only
|
|
56
|
+
* 2. Filter out duplicates based on existing comments
|
|
57
|
+
* 3. Filter to only issues with line numbers
|
|
58
|
+
* 4. Optionally filter to valid line numbers (platform-specific)
|
|
59
|
+
*/
|
|
60
|
+
export declare function prepareIssuesForPosting(allIssues: ReviewIssue[], existingComments: PlatformComment[], validLinesChecker?: (issue: ReviewIssue) => boolean): PreparedIssues;
|
|
61
|
+
//# sourceMappingURL=comment-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-manager.d.ts","sourceRoot":"","sources":["../../src/lib/comment-manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D;;GAEG;AAGH,eAAO,MAAM,cAAc,uBAAuB,CAAC;AAEnD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAEjE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAG5D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAQlE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAE1E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,WAAW,EAAE,EACrB,oBAAoB,EAAE,GAAG,CAAC,MAAM,CAAC,GAChC,WAAW,EAAE,CAKf;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,eAAe,GAAG,IAAI,CAE9F;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,eAAe,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAOpF;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,+EAA+E;IAC/E,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,8CAA8C;IAC9C,iBAAiB,EAAE,MAAM,CAAC;IAC1B,+DAA+D;IAC/D,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,WAAW,EAAE,EACxB,gBAAgB,EAAE,eAAe,EAAE,EACnC,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,GAClD,cAAc,CAuBhB"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Platform-agnostic comment management for deduplication and updates
|
|
3
|
+
*/
|
|
4
|
+
// Bot identifier for tracking our comments
|
|
5
|
+
export const BOT_COMMENT_ID = 'drs-review-summary';
|
|
6
|
+
/**
|
|
7
|
+
* Create a unique fingerprint for an issue to detect duplicates
|
|
8
|
+
*/
|
|
9
|
+
export function createIssueFingerprint(issue) {
|
|
10
|
+
return `${issue.file}:${issue.line || 'general'}:${issue.category}:${issue.title}`;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Extract bot comment ID from comment body
|
|
14
|
+
*/
|
|
15
|
+
export function extractCommentId(body) {
|
|
16
|
+
const match = body.match(/<!-- drs-comment-id: (.*?) -->/);
|
|
17
|
+
return match ? match[1] : null;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Extract issue fingerprints from comment body
|
|
21
|
+
*/
|
|
22
|
+
export function extractIssueFingerprints(body) {
|
|
23
|
+
const fingerprints = new Set();
|
|
24
|
+
const regex = /<!-- issue-fp: (.*?) -->/g;
|
|
25
|
+
let match;
|
|
26
|
+
while ((match = regex.exec(body)) !== null) {
|
|
27
|
+
fingerprints.add(match[1]);
|
|
28
|
+
}
|
|
29
|
+
return fingerprints;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Filter issues to only include CRITICAL and HIGH severity
|
|
33
|
+
* (for inline comments - reduces noise and API calls)
|
|
34
|
+
*/
|
|
35
|
+
export function filterCriticalAndHigh(issues) {
|
|
36
|
+
return issues.filter((i) => i.severity === 'CRITICAL' || i.severity === 'HIGH');
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Filter out duplicate issues based on existing fingerprints
|
|
40
|
+
*/
|
|
41
|
+
export function filterDuplicateIssues(issues, existingFingerprints) {
|
|
42
|
+
return issues.filter((issue) => {
|
|
43
|
+
const fingerprint = createIssueFingerprint(issue);
|
|
44
|
+
return !existingFingerprints.has(fingerprint);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Find existing summary comment using bot marker
|
|
49
|
+
*/
|
|
50
|
+
export function findExistingSummaryComment(comments) {
|
|
51
|
+
return comments.find((c) => extractCommentId(c.body) === BOT_COMMENT_ID) || null;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Collect all existing issue fingerprints from comments
|
|
55
|
+
*/
|
|
56
|
+
export function collectExistingFingerprints(comments) {
|
|
57
|
+
const allFingerprints = new Set();
|
|
58
|
+
for (const comment of comments) {
|
|
59
|
+
const fingerprints = extractIssueFingerprints(comment.body);
|
|
60
|
+
fingerprints.forEach((fp) => allFingerprints.add(fp));
|
|
61
|
+
}
|
|
62
|
+
return allFingerprints;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Prepare issues for posting, applying all filters:
|
|
66
|
+
* 1. Filter to CRITICAL/HIGH severity only
|
|
67
|
+
* 2. Filter out duplicates based on existing comments
|
|
68
|
+
* 3. Filter to only issues with line numbers
|
|
69
|
+
* 4. Optionally filter to valid line numbers (platform-specific)
|
|
70
|
+
*/
|
|
71
|
+
export function prepareIssuesForPosting(allIssues, existingComments, validLinesChecker) {
|
|
72
|
+
// Step 1: Filter to CRITICAL/HIGH only
|
|
73
|
+
const criticalAndHigh = filterCriticalAndHigh(allIssues);
|
|
74
|
+
const nonInlineCount = allIssues.length - criticalAndHigh.length;
|
|
75
|
+
// Step 2: Filter out duplicates
|
|
76
|
+
const existingFingerprints = collectExistingFingerprints(existingComments);
|
|
77
|
+
const newIssues = filterDuplicateIssues(criticalAndHigh, existingFingerprints);
|
|
78
|
+
const deduplicatedCount = criticalAndHigh.length - newIssues.length;
|
|
79
|
+
// Step 3: Filter to only issues with line numbers
|
|
80
|
+
let inlineIssues = newIssues.filter((issue) => issue.line !== undefined && issue.line !== null);
|
|
81
|
+
// Step 4: Optionally filter based on valid lines (platform-specific)
|
|
82
|
+
if (validLinesChecker) {
|
|
83
|
+
inlineIssues = inlineIssues.filter(validLinesChecker);
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
inlineIssues,
|
|
87
|
+
deduplicatedCount,
|
|
88
|
+
nonInlineCount,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=comment-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-manager.js","sourceRoot":"","sources":["../../src/lib/comment-manager.ts"],"names":[],"mappings":"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"}
|