rhine-lint 1.4.1 → 1.4.3
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/README.md +71 -19
- package/dist/assets/eslint.config.js +0 -8
- package/dist/cli.js +9 -1
- package/dist/config.d.ts +15 -0
- package/dist/core/config.d.ts +1 -1
- package/dist/core/config.js +95 -61
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -151,8 +151,9 @@ CLI 参数优先级高于配置文件:
|
|
|
151
151
|
- `--level <level>`: 强制指定项目类型(`js`, `ts`, `frontend`, `nextjs`)。
|
|
152
152
|
- `--no-project-type-check`: 禁用基于项目的类型检查 (可加快单文件处理速度)。
|
|
153
153
|
- `--tsconfig <path>`: 指定 tsconfig 文件路径 (用于类型检查和 import 解析)。
|
|
154
|
+
- `--ignore-file <path>`: 指定类似 `.gitignore` 的忽略文件 (支持多次使用, e.g. `--ignore-file .gitignore --ignore-file .eslintignore`)。
|
|
154
155
|
- `--ignore <pattern>`: 添加忽略模式 (支持多次使用, e.g. `--ignore dist --ignore coverage`)。
|
|
155
|
-
- `--no-ignore`: 强制禁用所有忽略规则 (包括
|
|
156
|
+
- `--no-ignore`: 强制禁用所有忽略规则 (包括 ignoreFiles 和 ignores)。
|
|
156
157
|
- `--debug`: 打印调试信息(包括生成的配置、忽略列表等)。
|
|
157
158
|
- `--cache-dir <dir>`: 指定缓存目录(默认使用 `node_modules/.cache/rhine-lint`)。
|
|
158
159
|
|
|
@@ -202,37 +203,66 @@ Rhine Lint 提供了灵活的文件忽略机制,支持多种配置方式。
|
|
|
202
203
|
以下目录始终被忽略(无需配置):
|
|
203
204
|
- `node_modules`, `dist`, `.next`, `.git`, `.output`, `.nuxt`, `coverage`, `.cache`
|
|
204
205
|
|
|
205
|
-
|
|
206
|
+
以下文件默认被忽略(可通过配置覆盖):
|
|
207
|
+
- `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `bun.lock`
|
|
206
208
|
|
|
207
|
-
|
|
209
|
+
#### 忽略文件 ignoreFiles
|
|
208
210
|
|
|
209
|
-
|
|
211
|
+
Rhine Lint 会自动解析 `.gitignore` 风格的文件,将其中的模式转换为 ESLint 忽略规则。
|
|
212
|
+
|
|
213
|
+
**默认值**: `['./.gitignore']`
|
|
210
214
|
|
|
211
215
|
```bash
|
|
212
|
-
#
|
|
213
|
-
rl --ignore
|
|
216
|
+
# CLI: 指定忽略文件 (覆盖默认值,支持多次使用)
|
|
217
|
+
rl --ignore-file .gitignore --ignore-file .eslintignore
|
|
218
|
+
```
|
|
214
219
|
|
|
215
|
-
|
|
216
|
-
|
|
220
|
+
```typescript
|
|
221
|
+
// rhine-lint.config.ts
|
|
222
|
+
export default {
|
|
223
|
+
// 指定要读取的忽略文件列表
|
|
224
|
+
ignoreFiles: ['./.gitignore', './.eslintignore']
|
|
225
|
+
}
|
|
217
226
|
```
|
|
218
227
|
|
|
219
|
-
####
|
|
228
|
+
#### 忽略模式 ignores
|
|
229
|
+
|
|
230
|
+
直接指定要忽略的文件或目录模式。
|
|
231
|
+
|
|
232
|
+
**默认值**: `['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lock']`
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
# CLI: 添加忽略模式 (与配置文件合并,支持多次使用)
|
|
236
|
+
rl --ignore temp --ignore generated --ignore "*.test.ts"
|
|
237
|
+
```
|
|
220
238
|
|
|
221
239
|
```typescript
|
|
222
240
|
// rhine-lint.config.ts
|
|
223
241
|
export default {
|
|
224
|
-
|
|
242
|
+
// 指定要忽略的文件/目录模式
|
|
243
|
+
ignores: ['temp', 'generated', '*.test.ts']
|
|
225
244
|
}
|
|
226
245
|
```
|
|
227
246
|
|
|
247
|
+
#### 禁用忽略 --no-ignore
|
|
248
|
+
|
|
249
|
+
```bash
|
|
250
|
+
# 禁用所有忽略规则 (包括 ignoreFiles 和 ignores)
|
|
251
|
+
rl --no-ignore
|
|
252
|
+
```
|
|
253
|
+
|
|
228
254
|
#### 忽略模式优先级
|
|
229
255
|
|
|
230
256
|
1. `--no-ignore` 会禁用所有忽略处理
|
|
231
|
-
2.
|
|
232
|
-
-
|
|
233
|
-
-
|
|
234
|
-
-
|
|
235
|
-
|
|
257
|
+
2. 否则,按以下顺序合并:
|
|
258
|
+
- 默认忽略目录(始终生效)
|
|
259
|
+
- `ignoreFiles` 中各文件的解析结果
|
|
260
|
+
- `ignores` 模式列表
|
|
261
|
+
|
|
262
|
+
**优先级规则**:
|
|
263
|
+
- `--ignore-file`: CLI 指定时覆盖配置文件中的 `ignoreFiles`
|
|
264
|
+
- `--ignore`: CLI 指定时覆盖配置文件中的 `ignores`
|
|
265
|
+
- 最终 `ignoreFiles` 和 `ignores` 的结果都会生效(合并)
|
|
236
266
|
|
|
237
267
|
### 缓存目录 Cache Directory
|
|
238
268
|
|
|
@@ -303,6 +333,7 @@ cli
|
|
|
303
333
|
.option("--level <level>", "Project level (js, ts, frontend, nextjs)")
|
|
304
334
|
.option("--no-project-type-check", "Disable project-based type checking")
|
|
305
335
|
.option("--tsconfig <path>", "Path to tsconfig file")
|
|
336
|
+
.option("--ignore-file [path]", "Add gitignore-style file (can be used multiple times)")
|
|
306
337
|
.option("--ignore [pattern]", "Add ignore pattern (can be used multiple times)")
|
|
307
338
|
.option("--no-ignore", "Disable all ignore rules")
|
|
308
339
|
.option("--cache-dir <dir>", "Custom cache directory")
|
|
@@ -322,6 +353,13 @@ if (!noIgnore && options.ignore && options.ignore !== true) {
|
|
|
322
353
|
? options.ignore.filter((p: unknown) => typeof p === 'string')
|
|
323
354
|
: [options.ignore];
|
|
324
355
|
}
|
|
356
|
+
// --ignore-file 参数处理
|
|
357
|
+
let ignoreFiles: string[] = [];
|
|
358
|
+
if (!noIgnore && options.ignoreFile && options.ignoreFile !== true) {
|
|
359
|
+
ignoreFiles = Array.isArray(options.ignoreFile)
|
|
360
|
+
? options.ignoreFile.filter((p: unknown) => typeof p === 'string')
|
|
361
|
+
: [options.ignoreFile];
|
|
362
|
+
}
|
|
325
363
|
```
|
|
326
364
|
|
|
327
365
|
- **逻辑**:
|
|
@@ -345,7 +383,8 @@ export async function generateTempConfig(
|
|
|
345
383
|
cliProjectTypeCheck?: boolean, // --no-project-type-check
|
|
346
384
|
cliTsconfig?: string, // --tsconfig 参数
|
|
347
385
|
cliIgnorePatterns: string[] = [], // --ignore 参数 (数组)
|
|
348
|
-
noIgnore: boolean = false
|
|
386
|
+
noIgnore: boolean = false, // --no-ignore 参数
|
|
387
|
+
cliIgnoreFiles: string[] = [] // --ignore-file 参数 (数组)
|
|
349
388
|
): Promise<{ eslintPath: string; prettierPath: string; cachePath: string }>
|
|
350
389
|
```
|
|
351
390
|
|
|
@@ -355,6 +394,15 @@ export async function generateTempConfig(
|
|
|
355
394
|
```typescript
|
|
356
395
|
const projectTypeCheck = cliProjectTypeCheck ?? userConfigResult.config.projectTypeCheck ?? true;
|
|
357
396
|
const tsconfigPath = cliTsconfig ?? userConfigResult.config.tsconfig;
|
|
397
|
+
// ignoreFiles: CLI 覆盖 config 覆盖默认值
|
|
398
|
+
const resolvedIgnoreFiles = cliIgnoreFiles.length > 0
|
|
399
|
+
? cliIgnoreFiles
|
|
400
|
+
: (userConfigResult.config.ignoreFiles ?? DEFAULT_IGNORE_FILES);
|
|
401
|
+
// ignores: CLI 覆盖 config 覆盖默认值
|
|
402
|
+
const resolvedIgnores = cliIgnorePatterns.length > 0
|
|
403
|
+
? cliIgnorePatterns
|
|
404
|
+
: (configIgnores.length > 0 ? configIgnores : DEFAULT_IGNORES);
|
|
405
|
+
// 最终 ignoreFiles 和 ignores 都会生效
|
|
358
406
|
```
|
|
359
407
|
|
|
360
408
|
2. **智能缓存 (SHA-256 指纹)**:
|
|
@@ -364,14 +412,18 @@ export async function generateTempConfig(
|
|
|
364
412
|
hash.update(cliLevel || "default");
|
|
365
413
|
hash.update(projectTypeCheck ? "ptc-on" : "ptc-off");
|
|
366
414
|
hash.update(tsconfigPath || "default-tsconfig");
|
|
367
|
-
hash.update(
|
|
415
|
+
hash.update(resolvedIgnoreFiles.join(",") || "no-ignore-files");
|
|
416
|
+
hash.update(resolvedIgnores.join(",") || "no-ignores");
|
|
368
417
|
hash.update(noIgnore ? "no-ignore" : "with-ignore");
|
|
369
|
-
// + 用户配置文件内容 +
|
|
418
|
+
// + 用户配置文件内容 + 各忽略文件内容
|
|
370
419
|
```
|
|
371
420
|
|
|
372
421
|
3. **忽略模式处理**:
|
|
373
422
|
- 若 `--no-ignore`,跳过所有忽略处理
|
|
374
|
-
-
|
|
423
|
+
- 否则:
|
|
424
|
+
1. 添加默认始终忽略的目录
|
|
425
|
+
2. 解析所有 `ignoreFiles` 中的文件
|
|
426
|
+
3. 添加 `ignores` 模式列表
|
|
375
427
|
- 模式规范化:自动添加 `**/` 前缀和 `/**` 后缀
|
|
376
428
|
|
|
377
429
|
4. **生成虚拟配置**: 动态生成 `eslint.config.mjs` 内容,包含:
|
|
@@ -6,14 +6,6 @@ import reactPlugin from 'eslint-plugin-react';
|
|
|
6
6
|
import reactHooksPlugin from 'eslint-plugin-react-hooks';
|
|
7
7
|
|
|
8
8
|
import css from '@eslint/css'
|
|
9
|
-
|
|
10
|
-
// ... skipped standard imports ...
|
|
11
|
-
|
|
12
|
-
// Removed Patch Mock - No longer needed as we don't use eslint-config-next
|
|
13
|
-
|
|
14
|
-
// ...
|
|
15
|
-
|
|
16
|
-
|
|
17
9
|
import js from '@eslint/js'
|
|
18
10
|
import json from '@eslint/json'
|
|
19
11
|
import markdown from '@eslint/markdown'
|
package/dist/cli.js
CHANGED
|
@@ -17,6 +17,7 @@ cli
|
|
|
17
17
|
.option("--level <level>", "Project level (js, ts, frontend, nextjs)")
|
|
18
18
|
.option("--no-project-type-check", "Disable project-based type checking (faster for single files)")
|
|
19
19
|
.option("--tsconfig <path>", "Path to tsconfig file for type checking and import resolution")
|
|
20
|
+
.option("--ignore-file [path]", "Add gitignore-style file for ignore patterns (can be used multiple times)")
|
|
20
21
|
.option("--ignore [pattern]", "Add ignore pattern (can be used multiple times)")
|
|
21
22
|
.option("--no-ignore", "Disable all ignore rules (including .gitignore)")
|
|
22
23
|
.option("--cache-dir <dir>", "Custom temporary cache directory")
|
|
@@ -59,7 +60,14 @@ cli
|
|
|
59
60
|
? options.ignore.filter((p) => typeof p === 'string')
|
|
60
61
|
: [options.ignore];
|
|
61
62
|
}
|
|
62
|
-
|
|
63
|
+
// Normalize ignore-file option to array
|
|
64
|
+
let ignoreFiles = [];
|
|
65
|
+
if (!noIgnore && options.ignoreFile && options.ignoreFile !== true) {
|
|
66
|
+
ignoreFiles = Array.isArray(options.ignoreFile)
|
|
67
|
+
? options.ignoreFile.filter((p) => typeof p === 'string')
|
|
68
|
+
: [options.ignoreFile];
|
|
69
|
+
}
|
|
70
|
+
const temps = await generateTempConfig(cwd, userConfigResult, options.level, options.cacheDir, options.debug, options.projectTypeCheck, options.tsconfig, ignorePatterns, noIgnore, ignoreFiles);
|
|
63
71
|
usedCachePath = temps.cachePath; // Save for cleanup
|
|
64
72
|
// 计时:第一阶段(准备阶段)
|
|
65
73
|
if (showTime) {
|
package/dist/config.d.ts
CHANGED
|
@@ -23,6 +23,21 @@ export type Config = {
|
|
|
23
23
|
*/
|
|
24
24
|
tsconfig?: string;
|
|
25
25
|
/**
|
|
26
|
+
* List of gitignore-style files to read ignore patterns from.
|
|
27
|
+
* Each file should follow .gitignore syntax.
|
|
28
|
+
* @default ['./.gitignore']
|
|
29
|
+
* @example ['./.gitignore', './.eslintignore']
|
|
30
|
+
*/
|
|
31
|
+
ignoreFiles?: string[];
|
|
32
|
+
/**
|
|
33
|
+
* List of specific files or patterns to ignore.
|
|
34
|
+
* Patterns follow glob syntax.
|
|
35
|
+
* @default ['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lock']
|
|
36
|
+
* @example ['temp', 'generated', '*.test.ts']
|
|
37
|
+
*/
|
|
38
|
+
ignores?: string[];
|
|
39
|
+
/**
|
|
40
|
+
* @deprecated Use `ignores` instead. This field will be removed in a future version.
|
|
26
41
|
* Additional ignore patterns to exclude files from linting.
|
|
27
42
|
* Patterns follow glob syntax.
|
|
28
43
|
* @example ['temp', 'generated', '*.test.ts']
|
package/dist/core/config.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export declare function loadUserConfig(cwd: string): Promise<{
|
|
|
6
6
|
export declare function generateTempConfig(cwd: string, userConfigResult: {
|
|
7
7
|
config: Config;
|
|
8
8
|
path?: string;
|
|
9
|
-
}, cliLevel?: string, cliCacheDir?: string, debug?: boolean, cliProjectTypeCheck?: boolean, cliTsconfig?: string, cliIgnorePatterns?: string[], noIgnore?: boolean): Promise<{
|
|
9
|
+
}, cliLevel?: string, cliCacheDir?: string, debug?: boolean, cliProjectTypeCheck?: boolean, cliTsconfig?: string, cliIgnorePatterns?: string[], noIgnore?: boolean, cliIgnoreFiles?: string[]): Promise<{
|
|
10
10
|
eslintPath: string;
|
|
11
11
|
prettierPath: string;
|
|
12
12
|
cachePath: string;
|
package/dist/core/config.js
CHANGED
|
@@ -50,18 +50,40 @@ export async function loadUserConfig(cwd) {
|
|
|
50
50
|
}
|
|
51
51
|
return { config: {} };
|
|
52
52
|
}
|
|
53
|
-
|
|
53
|
+
// 默认的忽略文件列表
|
|
54
|
+
const DEFAULT_IGNORE_FILES = ['./.gitignore'];
|
|
55
|
+
// 默认的忽略模式列表
|
|
56
|
+
const DEFAULT_IGNORES = ['package-lock.json', 'yarn.lock', 'pnpm-lock.yaml', 'bun.lock'];
|
|
57
|
+
// 默认始终忽略的目录
|
|
58
|
+
const DEFAULT_IGNORE_DIRS = [
|
|
59
|
+
'node_modules', 'dist', '.next', '.git', '.output', '.nuxt', 'coverage', '.cache'
|
|
60
|
+
];
|
|
61
|
+
export async function generateTempConfig(cwd, userConfigResult, cliLevel, cliCacheDir, debug, cliProjectTypeCheck, cliTsconfig, cliIgnorePatterns = [], noIgnore = false, cliIgnoreFiles = []) {
|
|
54
62
|
const cachePath = getCacheDir(cwd, userConfigResult.config, cliCacheDir);
|
|
55
63
|
await fs.ensureDir(cachePath);
|
|
56
64
|
const eslintTempPath = path.join(cachePath, "eslint.config.mjs");
|
|
57
65
|
const prettierTempPath = path.join(cachePath, "prettier.config.mjs");
|
|
58
66
|
const metaPath = path.join(cachePath, "metadata.json");
|
|
59
|
-
const gitignorePath = path.join(cwd, ".gitignore");
|
|
60
67
|
// Determine projectTypeCheck: CLI flag takes precedence over config file, default is true
|
|
61
68
|
// When --no-project-type-check is used, options.projectTypeCheck will be false
|
|
62
69
|
const projectTypeCheck = cliProjectTypeCheck ?? userConfigResult.config.projectTypeCheck ?? true;
|
|
63
70
|
// Determine tsconfig path: CLI flag takes precedence over config file
|
|
64
71
|
const tsconfigPath = cliTsconfig ?? userConfigResult.config.tsconfig;
|
|
72
|
+
// 解析忽略文件列表:CLI 覆盖 config,否则使用 config 或默认值
|
|
73
|
+
// CLI 优先级最高,如果 CLI 有值则完全使用 CLI 的值
|
|
74
|
+
const resolvedIgnoreFiles = cliIgnoreFiles.length > 0
|
|
75
|
+
? cliIgnoreFiles
|
|
76
|
+
: (userConfigResult.config.ignoreFiles !== undefined
|
|
77
|
+
? userConfigResult.config.ignoreFiles
|
|
78
|
+
: DEFAULT_IGNORE_FILES);
|
|
79
|
+
// 解析忽略模式列表:CLI 覆盖 config,否则使用 config 或默认值
|
|
80
|
+
// 同时兼容旧的 ignore 字段
|
|
81
|
+
const configIgnores = userConfigResult.config.ignores ?? userConfigResult.config.ignore ?? [];
|
|
82
|
+
const resolvedIgnores = cliIgnorePatterns.length > 0
|
|
83
|
+
? cliIgnorePatterns
|
|
84
|
+
: (configIgnores.length > 0
|
|
85
|
+
? configIgnores
|
|
86
|
+
: DEFAULT_IGNORES);
|
|
65
87
|
let calculatedHash = "";
|
|
66
88
|
try {
|
|
67
89
|
const hash = createHash("sha256");
|
|
@@ -69,18 +91,23 @@ export async function generateTempConfig(cwd, userConfigResult, cliLevel, cliCac
|
|
|
69
91
|
hash.update(cliLevel || "default");
|
|
70
92
|
hash.update(projectTypeCheck ? "ptc-on" : "ptc-off");
|
|
71
93
|
hash.update(tsconfigPath || "default-tsconfig");
|
|
72
|
-
hash.update(
|
|
94
|
+
hash.update(resolvedIgnoreFiles.join(",") || "no-ignore-files");
|
|
95
|
+
hash.update(resolvedIgnores.join(",") || "no-ignores");
|
|
73
96
|
hash.update(noIgnore ? "no-ignore" : "with-ignore");
|
|
74
97
|
if (userConfigResult.path && await fs.pathExists(userConfigResult.path)) {
|
|
75
98
|
const content = await fs.readFile(userConfigResult.path);
|
|
76
99
|
hash.update(content);
|
|
77
100
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
101
|
+
// 为每个忽略文件计算 hash
|
|
102
|
+
for (const ignoreFile of resolvedIgnoreFiles) {
|
|
103
|
+
const ignoreFilePath = path.resolve(cwd, ignoreFile);
|
|
104
|
+
if (await fs.pathExists(ignoreFilePath)) {
|
|
105
|
+
const content = await fs.readFile(ignoreFilePath);
|
|
106
|
+
hash.update(content);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
hash.update(`no-file:${ignoreFile}`);
|
|
110
|
+
}
|
|
84
111
|
}
|
|
85
112
|
calculatedHash = hash.digest("hex");
|
|
86
113
|
if (await fs.pathExists(metaPath)) {
|
|
@@ -97,7 +124,7 @@ export async function generateTempConfig(cwd, userConfigResult, cliLevel, cliCac
|
|
|
97
124
|
let ignoredPatterns = [];
|
|
98
125
|
// If --no-ignore is set, skip all ignore processing
|
|
99
126
|
if (!noIgnore) {
|
|
100
|
-
// Parse
|
|
127
|
+
// Parse gitignore-style file and convert to ESLint ignore patterns
|
|
101
128
|
// ESLint ignores are relative to the cwd where ESLint runs (which is the project root)
|
|
102
129
|
// NOT relative to the config file location
|
|
103
130
|
const parseGitignore = (content) => {
|
|
@@ -159,62 +186,65 @@ export async function generateTempConfig(cwd, userConfigResult, cliLevel, cliCac
|
|
|
159
186
|
}
|
|
160
187
|
return patterns;
|
|
161
188
|
};
|
|
162
|
-
//
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
189
|
+
// 规范化忽略模式(添加 **/ 前缀和 /** 后缀)
|
|
190
|
+
const normalizePattern = (pattern) => {
|
|
191
|
+
// If pattern doesn't start with ** or !, add **/ prefix
|
|
192
|
+
if (!pattern.startsWith('**') && !pattern.startsWith('!')) {
|
|
193
|
+
pattern = `**/${pattern}`;
|
|
194
|
+
}
|
|
195
|
+
// If pattern doesn't end with /** and doesn't contain *, add /** suffix
|
|
196
|
+
if (!pattern.endsWith('/**') && !pattern.includes('*')) {
|
|
197
|
+
pattern = `${pattern}/**`;
|
|
198
|
+
}
|
|
199
|
+
return pattern;
|
|
200
|
+
};
|
|
201
|
+
// 1. 添加默认始终忽略的目录
|
|
202
|
+
const defaultDirPatterns = DEFAULT_IGNORE_DIRS.map(dir => `**/${dir}/**`);
|
|
203
|
+
ignoredPatterns.push(...defaultDirPatterns);
|
|
204
|
+
// 2. 解析所有忽略文件
|
|
205
|
+
for (const ignoreFile of resolvedIgnoreFiles) {
|
|
206
|
+
const ignoreFilePath = path.resolve(cwd, ignoreFile);
|
|
207
|
+
if (await fs.pathExists(ignoreFilePath)) {
|
|
208
|
+
try {
|
|
209
|
+
const content = await fs.readFile(ignoreFilePath, 'utf-8');
|
|
210
|
+
if (debug) {
|
|
211
|
+
console.log("-----------------------------------------");
|
|
212
|
+
console.log(`DEBUG: ${ignoreFile} content preview:`);
|
|
213
|
+
console.log(content.substring(0, 500));
|
|
214
|
+
console.log("-----------------------------------------");
|
|
215
|
+
}
|
|
216
|
+
const parsedPatterns = parseGitignore(content);
|
|
217
|
+
if (debug) {
|
|
218
|
+
console.log("-----------------------------------------");
|
|
219
|
+
console.log(`DEBUG: Parsed patterns from ${ignoreFile}:`);
|
|
220
|
+
parsedPatterns.forEach((p, i) => console.log(` [${i}] "${p}"`));
|
|
221
|
+
console.log("-----------------------------------------");
|
|
222
|
+
}
|
|
223
|
+
ignoredPatterns.push(...parsedPatterns);
|
|
174
224
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
console.log("-----------------------------------------");
|
|
178
|
-
console.log("DEBUG: Parsed gitignore patterns:");
|
|
179
|
-
parsedPatterns.forEach((p, i) => console.log(` [${i}] "${p}"`));
|
|
180
|
-
console.log("-----------------------------------------");
|
|
225
|
+
catch (e) {
|
|
226
|
+
logger.debug(`Failed to parse ignore file: ${ignoreFile}`, e);
|
|
181
227
|
}
|
|
182
|
-
// Merge defaults with parsed patterns, removing duplicates
|
|
183
|
-
const allPatterns = [...defaultIgnores, ...parsedPatterns];
|
|
184
|
-
ignoredPatterns = [...new Set(allPatterns)];
|
|
185
228
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
ignoredPatterns = defaultIgnores;
|
|
229
|
+
else if (debug) {
|
|
230
|
+
console.log(`DEBUG: Ignore file not found: ${ignoreFile}`);
|
|
189
231
|
}
|
|
190
232
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
if (allCliPatterns.length > 0) {
|
|
198
|
-
// Normalize CLI patterns (add **/ prefix and /** suffix if needed)
|
|
199
|
-
const normalizedCliPatterns = allCliPatterns.map(pattern => {
|
|
200
|
-
// If pattern doesn't start with ** or !, add **/ prefix
|
|
201
|
-
if (!pattern.startsWith('**') && !pattern.startsWith('!')) {
|
|
202
|
-
pattern = `**/${pattern}`;
|
|
203
|
-
}
|
|
204
|
-
// If pattern doesn't end with /** and doesn't contain *, add /** suffix
|
|
205
|
-
if (!pattern.endsWith('/**') && !pattern.includes('*')) {
|
|
206
|
-
pattern = `${pattern}/**`;
|
|
207
|
-
}
|
|
208
|
-
return pattern;
|
|
209
|
-
});
|
|
210
|
-
ignoredPatterns = [...new Set([...ignoredPatterns, ...normalizedCliPatterns])];
|
|
233
|
+
// 3. 添加解析后的忽略模式
|
|
234
|
+
if (resolvedIgnores.length > 0) {
|
|
235
|
+
const normalizedPatterns = resolvedIgnores
|
|
236
|
+
.filter((p) => typeof p === 'string')
|
|
237
|
+
.map(normalizePattern);
|
|
238
|
+
ignoredPatterns.push(...normalizedPatterns);
|
|
211
239
|
if (debug) {
|
|
212
240
|
console.log("-----------------------------------------");
|
|
213
|
-
console.log("DEBUG:
|
|
214
|
-
|
|
241
|
+
console.log("DEBUG: Resolved ignore patterns:");
|
|
242
|
+
normalizedPatterns.forEach((p, i) => console.log(` [${i}] "${p}"`));
|
|
215
243
|
console.log("-----------------------------------------");
|
|
216
244
|
}
|
|
217
245
|
}
|
|
246
|
+
// 去重
|
|
247
|
+
ignoredPatterns = [...new Set(ignoredPatterns)];
|
|
218
248
|
}
|
|
219
249
|
else if (debug) {
|
|
220
250
|
console.log("-----------------------------------------");
|
|
@@ -295,13 +325,15 @@ prefixConfig.push({ ignores: ${JSON.stringify(ignoredPatterns)} });
|
|
|
295
325
|
` : ''}
|
|
296
326
|
|
|
297
327
|
if (${isEslintOverlay} || userEslint.overlay) {
|
|
298
|
-
|
|
299
|
-
|
|
328
|
+
// overlay=true: 用户配置完全覆盖内置配置
|
|
329
|
+
const userConf = userEslint.config || [];
|
|
330
|
+
if (Array.isArray(userConf)) {
|
|
331
|
+
finalConfig = [...prefixConfig, ...userConf];
|
|
300
332
|
} else {
|
|
301
|
-
finalConfig =
|
|
302
|
-
if (!Array.isArray(finalConfig)) finalConfig = [...prefixConfig, finalConfig];
|
|
333
|
+
finalConfig = [...prefixConfig, userConf];
|
|
303
334
|
}
|
|
304
335
|
} else {
|
|
336
|
+
// overlay=false: 内置配置 + 用户配置追加
|
|
305
337
|
const userConf = userEslint.config || [];
|
|
306
338
|
const defaultConf = Array.isArray(defaultEslint) ? defaultEslint : [defaultEslint];
|
|
307
339
|
finalConfig = [...prefixConfig, ...defaultConf, ...userConf];
|
|
@@ -326,8 +358,10 @@ const defaultPrettier = defaultOne;
|
|
|
326
358
|
|
|
327
359
|
let finalConfig;
|
|
328
360
|
if (${isPrettierOverlay} || userPrettier.overlay) {
|
|
329
|
-
|
|
361
|
+
// overlay=true: 用户配置完全覆盖内置配置
|
|
362
|
+
finalConfig = userPrettier.config || {};
|
|
330
363
|
} else {
|
|
364
|
+
// overlay=false: 内置配置为基础,用户配置补充
|
|
331
365
|
finalConfig = defu(userPrettier.config || {}, defaultPrettier);
|
|
332
366
|
}
|
|
333
367
|
|