-
-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathconfigs.ts
101 lines (86 loc) · 2.74 KB
/
configs.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import type { Linter } from 'eslint'
import type { MinimatchOptions } from 'minimatch'
import type { FlatConfigItem, MatchedFile } from './types'
import { ConfigArray } from '@eslint/config-array'
import { Minimatch } from 'minimatch'
const minimatchOpts: MinimatchOptions = { dot: true, flipNegate: true }
const _matchInstances = new Map<string, Minimatch>()
function minimatch(file: string, pattern: string) {
let m = _matchInstances.get(pattern)
if (!m) {
m = new Minimatch(pattern, minimatchOpts)
_matchInstances.set(pattern, m)
}
return m.match(file)
}
export function getMatchedGlobs(file: string, glob: (string | string[])[]) {
const globs = (Array.isArray(glob) ? glob : [glob]).flat()
return globs.filter(glob => minimatch(file, glob)).flat()
}
const META_KEYS = new Set(['name', 'index'])
/**
* Config with only `ignores` property
*/
export function isIgnoreOnlyConfig(config: FlatConfigItem) {
const keys = Object.keys(config).filter(i => !META_KEYS.has(i))
return keys.length === 1 && keys[0] === 'ignores'
}
/**
* Config without `files` and `ignores` properties or with only `ignores` property
*/
export function isGeneralConfig(config: FlatConfigItem) {
return (!config.files && !config.ignores) || isIgnoreOnlyConfig(config)
}
export function matchFile(
filepath: string,
configs: FlatConfigItem[],
basePath: string,
): MatchedFile {
const result: MatchedFile = {
filepath,
globs: [],
configs: [],
}
const {
config: globalMatchedConfig = {},
status: globalMatchStatus,
} = buildConfigArray(configs, basePath).getConfigWithStatus(filepath)
configs.forEach((config) => {
const positive = getMatchedGlobs(filepath, config.files || [])
const negative = getMatchedGlobs(filepath, config.ignores || [])
if (globalMatchStatus === 'matched' && globalMatchedConfig.index?.includes(config.index) && positive.length > 0) {
result.configs.push(config.index)
// push positive globs only when there are configs matched
result.globs.push(...positive)
}
result.globs.push(...negative)
})
result.globs = [...new Set(result.globs)]
return result
}
const NOOP_SCHEMA = {
merge: 'replace',
validate() {},
}
const FLAT_CONFIG_NOOP_SCHEMA = {
settings: NOOP_SCHEMA,
linterOptions: NOOP_SCHEMA,
language: NOOP_SCHEMA,
languageOptions: NOOP_SCHEMA,
processor: NOOP_SCHEMA,
plugins: NOOP_SCHEMA,
index: {
...NOOP_SCHEMA,
// accumulate the matched config index to an array
merge(v1: number, v2: number) {
return [v1].concat(v2).flat()
},
},
rules: NOOP_SCHEMA,
}
export function buildConfigArray(configs: Linter.Config[], basePath: string) {
return new ConfigArray(configs, {
basePath,
schema: FLAT_CONFIG_NOOP_SCHEMA,
}).normalizeSync()
}