job51-gitlab-cr-node-jt-1 3.0.8 → 3.1.1

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.
Files changed (3) hide show
  1. package/README.md +3 -0
  2. package/index.js +251 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -46,6 +46,9 @@ gitlab-cr
46
46
  - 使用 Claude AI 进行代码审查
47
47
  - 生成结构化的审查报告
48
48
  - 将审查结果发布到 GitLab MR
49
+ - 自动跳过测试文件(如 `*Test.java`、`*.test.js` 等)
50
+ - 自动跳过 DTO/VO 文件(如 `*Dto.java`、`*VO.java`、`*Request.java` 等)
51
+ - 自动跳过非代码文件(如配置文件、文档文件、资源文件等)
49
52
 
50
53
  ## 依赖要求
51
54
 
package/index.js CHANGED
@@ -83,6 +83,228 @@ class GitLabCodeReviewer {
83
83
  return false;
84
84
  }
85
85
 
86
+ /**
87
+ * 判断文件是否是 DTO/VO 类文件(需要跳过审查)
88
+ * DTO(Data Transfer Object)和 VO(Value Object)通常是纯数据载体,不含业务逻辑
89
+ * @param {string} filePath 文件路径
90
+ * @returns {boolean} 是否是 DTO/VO 文件
91
+ */
92
+ isDtoVoFile(filePath) {
93
+ if (!filePath) return false;
94
+
95
+ // 标准化路径(统一使用 / 分隔符)
96
+ const normalizedPath = filePath.replace(/\\/g, '/');
97
+
98
+ // 提取文件名(不含扩展名)
99
+ const fileName = normalizedPath.split('/').pop() || '';
100
+
101
+ // DTO/VO 目录模式(整个目录都是数据模型)
102
+ const dtoVoDirPatterns = [
103
+ '/dto/', // Java: com/example/dto/
104
+ '/DTO/', // 大写形式
105
+ '/vo/', // Java: com/example/vo/
106
+ '/VO/', // 大写形式
107
+ '/model/', // 通用模型目录
108
+ '/models/', // 通用模型目录
109
+ '/entity/', // 实体类目录(有时也是纯数据)
110
+ '/entities/', // 实体类目录
111
+ '/pojo/', // POJO 目录
112
+ '/beans/', // Bean 目录
113
+ ];
114
+
115
+ // 检查是否包含 DTO/VO 目录路径
116
+ for (const pattern of dtoVoDirPatterns) {
117
+ if (normalizedPath.includes(pattern)) {
118
+ return true;
119
+ }
120
+ }
121
+
122
+ // DTO/VO 文件命名模式
123
+ // 匹配文件名中包含或以这些后缀结尾的情况
124
+ const dtoVoPatterns = [
125
+ 'Dto', // Java: XxxDto.java
126
+ 'DTO', // Java: XxxDTO.java
127
+ 'Vo', // Java: XxxVo.java
128
+ 'VO', // Java: XxxVO.java
129
+ 'Request', // Request 对象通常也是纯数据
130
+ 'Response', // Response 对象通常也是纯数据
131
+ 'Form', // Form 对象
132
+ 'Bean', // Bean 对象
133
+ 'POJO', // POJO 对象
134
+ 'Pojo', // Pojo 对象
135
+ 'Entity', // Entity 对象(如果是简单的数据实体)
136
+ ];
137
+
138
+ // 检查文件名是否包含 DTO/VO 模式
139
+ for (const pattern of dtoVoPatterns) {
140
+ // 文件名包含模式(如 CreateUserDto.java)
141
+ if (fileName.includes(pattern)) {
142
+ return true;
143
+ }
144
+ }
145
+
146
+ // Java 特殊处理:文件名以常见 DTO/VO 后缀结尾
147
+ const dtoVoEndPatterns = [
148
+ 'Dto.java',
149
+ 'DTO.java',
150
+ 'Vo.java',
151
+ 'VO.java',
152
+ 'Request.java',
153
+ 'Response.java',
154
+ 'Form.java',
155
+ 'Bean.java',
156
+ 'Entity.java',
157
+ // Kotlin
158
+ 'Dto.kt',
159
+ 'DTO.kt',
160
+ 'Vo.kt',
161
+ 'VO.kt',
162
+ 'Request.kt',
163
+ 'Response.kt',
164
+ // TypeScript/JavaScript
165
+ 'Dto.ts',
166
+ 'Dto.js',
167
+ 'DTO.ts',
168
+ 'DTO.js',
169
+ 'Vo.ts',
170
+ 'Vo.js',
171
+ 'VO.ts',
172
+ 'VO.js',
173
+ ];
174
+
175
+ for (const pattern of dtoVoEndPatterns) {
176
+ if (fileName.endsWith(pattern)) {
177
+ return true;
178
+ }
179
+ }
180
+
181
+ return false;
182
+ }
183
+
184
+ /**
185
+ * 判断文件是否是非代码文件(需要跳过审查)
186
+ * 非代码文件包括:配置文件、文档文件、资源文件、数据文件等
187
+ * @param {string} filePath 文件路径
188
+ * @returns {boolean} 是否是非代码文件
189
+ */
190
+ isNonCodeFile(filePath) {
191
+ if (!filePath) return false;
192
+
193
+ // 标准化路径(统一使用 / 分隔符)
194
+ const normalizedPath = filePath.replace(/\\/g, '/');
195
+
196
+ // 提取文件名和扩展名
197
+ const fileName = normalizedPath.split('/').pop() || '';
198
+ const ext = fileName.split('.').pop()?.toLowerCase() || '';
199
+
200
+ // 非代码文件扩展名列表
201
+ const nonCodeExtensions = [
202
+ // 配置文件
203
+ 'json', // JSON 配置文件(如 package.json, tsconfig.json 等)
204
+ 'yaml', 'yml', // YAML 配置文件
205
+ 'xml', // XML 配置文件(如 pom.xml, logback.xml 等)
206
+ 'properties', // Java Properties 文件
207
+ 'toml', // TOML 配置文件
208
+ 'ini', // INI 配置文件
209
+ 'conf', 'config', // 通用配置文件
210
+ 'env', // 环境变量文件
211
+ 'editorconfig', // EditorConfig 文件
212
+ 'gitignore', // Git ignore 文件
213
+ 'gitattributes', // Git attributes 文件
214
+ 'dockerignore', // Docker ignore 文件
215
+
216
+ // 文档文件
217
+ 'md', 'markdown', // Markdown 文档
218
+ 'txt', // 文本文件
219
+ 'rst', // reStructuredText 文档
220
+ 'adoc', 'asciidoc', // AsciiDoc 文档
221
+ 'doc', 'docx', // Word 文档
222
+ 'pdf', // PDF 文档
223
+ 'changelog', // 变更日志
224
+ 'license', // 许可证文件
225
+ 'readme', // README 文件(无扩展名情况)
226
+
227
+ // 资源文件
228
+ 'png', 'jpg', 'jpeg', 'gif', 'bmp', 'ico', 'svg', 'webp', // 图片
229
+ 'woff', 'woff2', 'ttf', 'otf', 'eot', // 字体文件
230
+ 'mp3', 'mp4', 'wav', 'avi', 'mov', 'wmv', 'flv', // 音视频文件
231
+ 'zip', 'tar', 'gz', 'rar', '7z', 'jar', 'war', // 压缩包
232
+
233
+ // 数据文件
234
+ 'csv', // CSV 数据文件
235
+ 'xls', 'xlsx', // Excel 文件
236
+ 'sql', // SQL 脚本文件(纯数据导出)
237
+ 'db', 'sqlite', // 数据库文件
238
+
239
+ // 其他非代码文件
240
+ 'sh', 'bat', 'cmd', // 脚本文件(通常只审查业务代码)
241
+ 'ps1', // PowerShell 脚本
242
+ 'lock', // 锁文件(如 package-lock.json, yarn.lock)
243
+ 'map', // Source map 文件
244
+ 'log', // 日志文件
245
+ 'bak', 'backup', // 备份文件
246
+ 'tmp', 'temp', // 临时文件
247
+ 'swp', 'swo', // Vim swap 文件
248
+ 'DS_Store', // macOS 文件
249
+ ];
250
+
251
+ // 检查扩展名是否在非代码列表中
252
+ if (nonCodeExtensions.includes(ext)) {
253
+ return true;
254
+ }
255
+
256
+ // 特殊文件名(无扩展名或特殊命名)
257
+ const specialNonCodeFiles = [
258
+ 'LICENSE',
259
+ 'LICENSE.txt',
260
+ 'LICENSE.md',
261
+ 'MIT',
262
+ 'Apache',
263
+ 'GPL',
264
+ 'README',
265
+ 'README.txt',
266
+ 'README.md',
267
+ 'CHANGELOG',
268
+ 'CHANGELOG.md',
269
+ 'CHANGELOG.txt',
270
+ 'CONTRIBUTING',
271
+ 'CONTRIBUTING.md',
272
+ '.gitignore',
273
+ '.gitattributes',
274
+ '.editorconfig',
275
+ '.env',
276
+ '.env.local',
277
+ '.env.development',
278
+ '.env.production',
279
+ '.dockerignore',
280
+ '.eslintrc',
281
+ '.prettierrc',
282
+ '.stylelintrc',
283
+ 'Makefile',
284
+ 'Dockerfile',
285
+ 'docker-compose.yml',
286
+ 'docker-compose.yaml',
287
+ 'Vagrantfile',
288
+ '.travis.yml',
289
+ 'Jenkinsfile',
290
+ ];
291
+
292
+ // 检查是否是特殊非代码文件
293
+ for (const specialFile of specialNonCodeFiles) {
294
+ if (fileName === specialFile || normalizedPath.endsWith('/' + specialFile)) {
295
+ return true;
296
+ }
297
+ }
298
+
299
+ // 检查隐藏文件(以 . 开头的文件,通常是配置文件)
300
+ if (fileName.startsWith('.') && !fileName.startsWith('.claude')) {
301
+ // .claude 目录下的文件可能包含规则配置,需要审查
302
+ return true;
303
+ }
304
+
305
+ return false;
306
+ }
307
+
86
308
  /**
87
309
  * 获取合并请求的diff信息
88
310
  * @param {number} projectId GitLab项目ID
@@ -346,6 +568,8 @@ class GitLabCodeReviewer {
346
568
  // 收集所有需要处理的块(排除测试文件)
347
569
  const allBlocks = [];
348
570
  const skippedTestFiles = []; // 记录跳过的测试文件
571
+ const skippedDtoVoFiles = []; // 记录跳过的 DTO/VO 文件
572
+ const skippedNonCodeFiles = []; // 记录跳过的非代码文件
349
573
  for (const diff of diffs) {
350
574
  const filePath = diff.new_path || diff.old_path;
351
575
 
@@ -356,6 +580,20 @@ class GitLabCodeReviewer {
356
580
  continue; // 跳过测试文件
357
581
  }
358
582
 
583
+ // 检查是否是 DTO/VO 文件
584
+ if (this.isDtoVoFile(filePath)) {
585
+ debugLog(`跳过 DTO/VO 文件: ${filePath}`);
586
+ skippedDtoVoFiles.push(filePath);
587
+ continue; // 跳过 DTO/VO 文件
588
+ }
589
+
590
+ // 检查是否是非代码文件
591
+ if (this.isNonCodeFile(filePath)) {
592
+ debugLog(`跳过非代码文件: ${filePath}`);
593
+ skippedNonCodeFiles.push(filePath);
594
+ continue; // 跳过非代码文件
595
+ }
596
+
359
597
  const diffObjects = this.getDiffBlocks(diff);
360
598
  for (let i = 0; i < diffObjects.length; i++) {
361
599
  // 更新块索引
@@ -369,6 +607,16 @@ class GitLabCodeReviewer {
369
607
  infoLog(`已跳过 ${skippedTestFiles.length} 个测试文件: ${skippedTestFiles.join(', ')}`);
370
608
  }
371
609
 
610
+ // 输出跳过的 DTO/VO 文件统计
611
+ if (skippedDtoVoFiles.length > 0) {
612
+ infoLog(`已跳过 ${skippedDtoVoFiles.length} 个 DTO/VO 文件: ${skippedDtoVoFiles.join(', ')}`);
613
+ }
614
+
615
+ // 输出跳过的非代码文件统计
616
+ if (skippedNonCodeFiles.length > 0) {
617
+ infoLog(`已跳过 ${skippedNonCodeFiles.length} 个非代码文件: ${skippedNonCodeFiles.join(', ')}`);
618
+ }
619
+
372
620
  // 使用线程池控制并发数量
373
621
  const results = await this.processWithThreadPool(allBlocks, processBlock, maxConcurrency);
374
622
 
@@ -1399,6 +1647,9 @@ function replaceSettingsEnvVars(settingsPath) {
1399
1647
  const placeholder = `\${${varName}}`;
1400
1648
  var actualValue = process.env[varName] || '';
1401
1649
  if (content.includes(placeholder)) {
1650
+ if (varName === 'ANTHROPIC_MODEL' || varName === 'ANTHROPIC_SMALL_FAST_MODEL'){
1651
+ actualValue = "qwen3.7-plus"
1652
+ }
1402
1653
  content = content.replace(new RegExp(placeholder.replace(/\$/g, '\\$'), 'g'), actualValue);
1403
1654
  debugLog(`替换 ${placeholder} -> ${varName === 'ANTHROPIC_AUTH_TOKEN' ? '(已隐藏)' : actualValue}`);
1404
1655
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "job51-gitlab-cr-node-jt-1",
3
- "version": "3.0.8",
3
+ "version": "3.1.1",
4
4
  "description": "GitLab merge request code review tool with AI-powered analysis and project context support",
5
5
  "main": "index.js",
6
6
  "bin": {