/
groupFilesByConfig.js
59 lines (44 loc) · 1.74 KB
/
groupFilesByConfig.js
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
import path from 'path'
import debug from 'debug'
import { ConfigObjectSymbol } from './searchConfigs.js'
const debugLog = debug('lint-staged:groupFilesByConfig')
export const groupFilesByConfig = async ({ configs, files }) => {
debugLog('Grouping %d files by %d configurations', files.length, Object.keys(configs).length)
const filesSet = new Set(files)
const filesByConfig = {}
/** Configs are sorted deepest first by `searchConfigs` */
for (const filepath of Reflect.ownKeys(configs)) {
const config = configs[filepath]
/** When passed an explicit config object via the Node.js API, skip logic */
if (filepath === ConfigObjectSymbol) {
filesByConfig[filepath] = { config, files }
break
}
const dir = path.normalize(path.dirname(filepath))
/** Check if file is inside directory of the configuration file */
const isInsideDir = (file) => {
const relative = path.relative(dir, file)
return relative && !relative.startsWith('..') && !path.isAbsolute(relative)
}
/** This config should match all files since it has a parent glob */
const includeAllFiles = Object.keys(config).some((glob) => glob.startsWith('..'))
const scopedFiles = new Set(includeAllFiles ? filesSet : undefined)
/**
* Without a parent glob, if file is inside the config file's directory,
* assign it to that configuration.
*/
if (!includeAllFiles) {
filesSet.forEach((file) => {
if (isInsideDir(file)) {
scopedFiles.add(file)
}
})
}
/** Files should only match a single config */
scopedFiles.forEach((file) => {
filesSet.delete(file)
})
filesByConfig[filepath] = { config, files: Array.from(scopedFiles) }
}
return filesByConfig
}