1
1
import { cosmiconfig } from "cosmiconfig" ;
2
2
import { default as resolveFrom } from "resolve-from" ;
3
3
import { pickBy , isNil , castArray } from "lodash-es" ;
4
+ import { createRequire } from "module" ;
4
5
5
6
const CONFIG_NAME = "multi-release" ;
6
7
const CONFIG_FILES = [
@@ -15,6 +16,19 @@ const CONFIG_FILES = [
15
16
`${ CONFIG_NAME } .config.cjs` ,
16
17
] ;
17
18
19
+ const mergeConfig = ( a = { } , b = { } ) => {
20
+ return {
21
+ ...a ,
22
+ // Remove `null` and `undefined` options so they can be replaced with default ones
23
+ ...pickBy ( b , ( option ) => ! isNil ( option ) ) ,
24
+ // Treat nested objects differently as otherwise we'll loose undefined keys
25
+ deps : {
26
+ ...a . deps ,
27
+ ...pickBy ( b . deps , ( option ) => ! isNil ( option ) ) ,
28
+ } ,
29
+ } ;
30
+ } ;
31
+
18
32
/**
19
33
* Get the multi semantic release configuration options for a given directory.
20
34
*
@@ -26,42 +40,41 @@ const CONFIG_FILES = [
26
40
*/
27
41
export default async function getConfig ( cwd , cliOptions ) {
28
42
const { config } = ( await cosmiconfig ( CONFIG_NAME , { searchPlaces : CONFIG_FILES } ) . search ( cwd ) ) || { } ;
29
- const { extends : extendPaths , ...rest } = { ...config , ... cliOptions } ;
43
+ const { extends : extendPaths , ...rest } = { ...config } ;
30
44
31
45
let options = rest ;
32
46
33
47
if ( extendPaths ) {
34
- // If `extends` is defined, load and merge each shareable config with `options`
35
- options = {
36
- ...castArray ( extendPaths ) . reduce ( ( result , extendPath ) => {
37
- const extendsOptions = require ( resolveFrom . silent ( __dirname , extendPath ) ||
38
- resolveFrom ( cwd , extendPath ) ) ;
39
- return { ...result , ...extendsOptions } ;
40
- } , { } ) ,
41
- ...options ,
42
- } ;
48
+ const require = createRequire ( import . meta. url ) ;
49
+ // If `extends` is defined, load and merge each shareable config
50
+ const extendedOptions = castArray ( extendPaths ) . reduce ( ( result , extendPath ) => {
51
+ const extendsOptions = require ( resolveFrom ( cwd , extendPath ) ) ;
52
+ return mergeConfig ( result , extendsOptions ) ;
53
+ } , { } ) ;
54
+
55
+ options = mergeConfig ( options , extendedOptions ) ;
43
56
}
44
57
45
58
// Set default options values if not defined yet
46
- options = {
47
- sequentialInit : false ,
48
- sequentialPrepare : true ,
49
- firstParent : false ,
50
- debug : false ,
51
- ignorePrivate : true ,
52
- ignorePackages : "" ,
53
- tagFormat : "${name}@${version}" ,
54
- dryRun : false ,
55
- // Remove `null` and `undefined` options so they can be replaced with default ones
56
- ...pickBy ( options , ( option ) => ! isNil ( option ) ) ,
57
- // Treat nested objects differently as otherwise we'll loose undefined keys
58
- deps : {
59
- bump : "override" ,
60
- release : "patch" ,
61
- prefix : "" ,
62
- ...pickBy ( options . deps , ( option ) => ! isNil ( option ) ) ,
59
+ options = mergeConfig (
60
+ {
61
+ sequentialInit : false ,
62
+ sequentialPrepare : true ,
63
+ firstParent : false ,
64
+ debug : false ,
65
+ ignorePrivate : true ,
66
+ ignorePackages : "" ,
67
+ tagFormat : "${name}@${version}" ,
68
+ dryRun : false ,
69
+ deps : {
70
+ bump : "override" ,
71
+ release : "patch" ,
72
+ prefix : "" ,
73
+ } ,
63
74
} ,
64
- } ;
75
+ options
76
+ ) ;
65
77
66
- return options ;
78
+ // Finally merge CLI options last so they always win
79
+ return mergeConfig ( options , cliOptions ) ;
67
80
}
0 commit comments