forked from conventional-changelog/commitlint
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathload.js
128 lines (110 loc) · 3.16 KB
/
load.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
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import path from 'path';
import {entries, merge, mergeWith, pick} from 'lodash';
import rc from 'rc';
import cosmiconfig from 'cosmiconfig';
import resolveFrom from 'resolve-from';
import up from 'find-up';
import resolveExtends from './library/resolve-extends';
import executeRule from './library/execute-rule';
const w = (a, b) => (Array.isArray(b) ? b : undefined);
const valid = input => pick(input, 'extends', 'rules', 'parserPreset');
export default async (seed = {}) => {
// Obtain config from .rc files
const raw = await file();
// Merge passed config with file based options
const config = valid(merge(raw, seed));
const opts = merge({extends: [], rules: {}}, pick(config, 'extends'));
// Resolve parserPreset key
if (typeof config.parserPreset === 'string') {
const resolvedParserPreset = resolveFrom(
process.cwd(),
config.parserPreset
);
config.parserPreset = {
name: config.parserPreset,
path: `./${path.posix.relative(process.cwd(), resolvedParserPreset)}`
.split(path.sep)
.join('/'),
opts: require(resolvedParserPreset)
};
}
// Resolve extends key
const extended = resolveExtends(opts, {
prefix: 'commitlint-config',
cwd: raw.config ? path.dirname(raw.config) : process.cwd(),
parserPreset: config.parserPreset
});
const preset = valid(mergeWith(extended, config, w));
// Await parser-preset if applicable
if (
typeof preset.parserPreset === 'object' &&
typeof preset.parserPreset.opts === 'object'
) {
preset.parserPreset.opts = await preset.parserPreset.opts;
}
// Execute rule config functions if needed
const executed = await Promise.all(
['rules']
.map(key => {
return [key, preset[key]];
})
.map(async item => {
const [key, value] = item;
const executedValue = await Promise.all(
entries(value || {}).map(entry => executeRule(entry))
);
return [
key,
executedValue.reduce((registry, item) => {
const [key, value] = item;
registry[key] = value;
return registry;
}, {})
];
})
);
// Merge executed config keys into preset
return executed.reduce((registry, item) => {
const [key, value] = item;
registry[key] = value;
return registry;
}, preset);
};
async function file() {
const legacy = rc('conventional-changelog-lint');
const legacyFound = typeof legacy.config === 'string';
const explorer = cosmiconfig('commitlint', {
rcExtensions: true,
stopDir: await toplevel()
});
const config = await explorer.load('.');
if (legacyFound && !config) {
console.warn(
`Using legacy ${path.relative(
process.cwd(),
legacy.config
)}. Rename to commitlint.config.js to silence this warning.`
);
}
if (legacyFound && config) {
console.warn(
`Ignored legacy ${path.relative(
process.cwd(),
legacy.config
)} as commitlint.config.js superseeds it. Remove .conventional-changelog-lintrc to silence this warning.`
);
}
if (config) {
return config.config;
}
return legacy;
}
// Find the next git root
// (start: string) => Promise<string | null>
async function toplevel(cwd = process.cwd()) {
const found = await up('.git', {cwd});
if (typeof found !== 'string') {
return found;
}
return path.join(found, '..');
}