/
searchConfigs.js
74 lines (60 loc) · 2.41 KB
/
searchConfigs.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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/** @typedef {import('./index').Logger} Logger */
import { basename, join } from 'path'
import normalize from 'normalize-path'
import { execGit } from './execGit.js'
import { loadConfig, searchPlaces } from './loadConfig.js'
import { validateConfig } from './validateConfig.js'
const EXEC_GIT = ['ls-files', '-z', '--full-name']
const filterPossibleConfigFiles = (file) => searchPlaces.includes(basename(file))
const numberOfLevels = (file) => file.split('/').length
const sortDeepestParth = (a, b) => (numberOfLevels(a) > numberOfLevels(b) ? -1 : 1)
/**
* Search all config files from the git repository
*
* @param {string} gitDir
* @param {Logger} logger
* @returns {Promise<{ [key: string]: * }>} found configs with filepath as key, and config as value
*/
export const searchConfigs = async (gitDir = process.cwd(), logger) => {
/** Get all possible config files known to git */
const cachedFiles = (await execGit(EXEC_GIT, { cwd: gitDir }))
// eslint-disable-next-line no-control-regex
.replace(/\u0000$/, '')
.split('\u0000')
.filter(filterPossibleConfigFiles)
/** Get all possible config files from uncommitted files */
const otherFiles = (
await execGit([...EXEC_GIT, '--others', '--exclude-standard'], { cwd: gitDir })
)
// eslint-disable-next-line no-control-regex
.replace(/\u0000$/, '')
.split('\u0000')
.filter(filterPossibleConfigFiles)
/** Sort possible config files so that deepest is first */
const possibleConfigFiles = [...cachedFiles, ...otherFiles]
.map((file) => join(gitDir, file))
.map((file) => normalize(file))
.sort(sortDeepestParth)
/** Create object with key as config file, and value as null */
const configs = possibleConfigFiles.reduce(
(acc, configPath) => Object.assign(acc, { [configPath]: null }),
{}
)
/** Load and validate all configs to the above object */
await Promise.all(
possibleConfigFiles
.map((configPath) => loadConfig({ configPath }, logger))
.map((promise) =>
promise.then(({ config, filepath }) => {
if (config) {
configs[filepath] = validateConfig(config, filepath, logger)
}
})
)
)
/** Get validated configs from the above object, without any `null` values (not found) */
const foundConfigs = Object.entries(configs)
.filter(([, value]) => !!value)
.reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {})
return foundConfigs
}