1
1
const { join } = require ( 'path' )
2
- const { defaultsDeep } = require ( 'lodash' )
3
- const merge = require ( './merge.js' )
2
+ const { defaultsDeep, omit } = require ( 'lodash' )
4
3
const deepMapValues = require ( 'just-deep-map-values' )
5
4
const { glob } = require ( 'glob' )
5
+ const { mergeWithCustomizers, customizers } = require ( './merge.js' )
6
6
const Parser = require ( './parser.js' )
7
7
const template = require ( './template.js' )
8
8
9
+ const ADD_KEY = 'add'
10
+ const RM_KEY = 'rm'
9
11
const FILE_KEYS = [ 'rootRepo' , 'rootModule' , 'workspaceRepo' , 'workspaceModule' ]
10
12
11
13
const globify = pattern => pattern . split ( '\\' ) . join ( '/' )
12
14
13
- const fileEntries = ( dir , files , options ) => Object . entries ( files )
14
- // remove any false values
15
- . filter ( ( [ _ , v ] ) => v !== false )
16
- // target paths need to be joinsed with dir and templated
17
- . map ( ( [ k , source ] ) => {
18
- const target = join ( dir , template ( k , options ) )
19
- return [ target , source ]
20
- } )
15
+ const mergeFiles = mergeWithCustomizers ( ( value , srcValue , key , target , source , stack ) => {
16
+ // This will merge all files except if the src file has overwrite:false. Then
17
+ // the files will be turned into an array so they can be applied on top of
18
+ // each other in the parser.
19
+ if (
20
+ stack [ 0 ] === ADD_KEY &&
21
+ FILE_KEYS . includes ( stack [ 1 ] ) &&
22
+ value ?. file &&
23
+ srcValue ?. overwrite === false
24
+ ) {
25
+ return [ value , omit ( srcValue , 'overwrite' ) ]
26
+ }
27
+ } , customizers . overwriteArrays )
28
+
29
+ const fileEntries = ( dir , files , options , { allowMultipleSources = true } = { } ) => {
30
+ const results = [ ]
31
+
32
+ for ( const [ key , source ] of Object . entries ( files ) ) {
33
+ // remove any false values first since that means those targets are skipped
34
+ if ( source === false ) {
35
+ continue
36
+ }
37
+
38
+ // target paths need to be joinsed with dir and templated
39
+ const target = join ( dir , template ( key , options ) )
40
+
41
+ if ( Array . isArray ( source ) ) {
42
+ // When turning an object of files into all its entries, we allow
43
+ // multiples when applying changes, but not when checking for changes
44
+ // since earlier files would always return as needing an update. So we
45
+ // either allow multiples and return the array or only return the last
46
+ // source file in the array.
47
+ const sources = allowMultipleSources ? source : source . slice ( - 1 )
48
+ results . push ( ...sources . map ( s => [ target , s ] ) )
49
+ } else {
50
+ results . push ( [ target , source ] )
51
+ }
52
+ }
53
+
54
+ return results
55
+ }
21
56
22
57
// given an obj of files, return the full target/source paths and associated parser
23
- const getParsers = ( dir , files , options ) => {
24
- const parsers = fileEntries ( dir , files , options ) . map ( ( [ target , source ] ) => {
58
+ const getParsers = ( dir , files , options , parseOptions ) => {
59
+ const parsers = fileEntries ( dir , files , options , parseOptions ) . map ( ( [ target , source ] ) => {
25
60
const { file, parser, filter, clean : shouldClean } = source
26
61
27
62
if ( typeof filter === 'function' && ! filter ( options ) ) {
@@ -62,17 +97,17 @@ const rmEach = async (dir, files, options, fn) => {
62
97
return res . filter ( Boolean )
63
98
}
64
99
65
- const parseEach = async ( dir , files , options , fn ) => {
100
+ const parseEach = async ( dir , files , options , parseOptions , fn ) => {
66
101
const res = [ ]
67
- for ( const parser of getParsers ( dir , files , options ) ) {
102
+ for ( const parser of getParsers ( dir , files , options , parseOptions ) ) {
68
103
res . push ( await fn ( parser ) )
69
104
}
70
105
return res . filter ( Boolean )
71
106
}
72
107
73
108
const parseConfig = ( files , dir , overrides ) => {
74
109
const normalizeFiles = ( v ) => deepMapValues ( v , ( value , key ) => {
75
- if ( key === 'rm' && Array . isArray ( value ) ) {
110
+ if ( key === RM_KEY && Array . isArray ( value ) ) {
76
111
return value . reduce ( ( acc , k ) => {
77
112
acc [ k ] = true
78
113
return acc
@@ -88,21 +123,22 @@ const parseConfig = (files, dir, overrides) => {
88
123
return value
89
124
} )
90
125
91
- const merged = merge ( normalizeFiles ( files ) , normalizeFiles ( overrides ) )
126
+ const merged = mergeFiles ( normalizeFiles ( files ) , normalizeFiles ( overrides ) )
92
127
const withDefaults = defaultsDeep ( merged , FILE_KEYS . reduce ( ( acc , k ) => {
93
- acc [ k ] = { add : { } , rm : { } }
128
+ acc [ k ] = { [ ADD_KEY ] : { } , [ RM_KEY ] : { } }
94
129
return acc
95
130
} , { } ) )
96
131
97
132
return withDefaults
98
133
}
99
134
100
- const getAddedFiles = ( files ) => files ? Object . keys ( files . add || { } ) : [ ]
135
+ const getAddedFiles = ( files ) => files ? Object . keys ( files [ ADD_KEY ] || { } ) : [ ]
101
136
102
137
module . exports = {
103
138
rmEach,
104
139
parseEach,
105
140
FILE_KEYS ,
106
141
parseConfig,
107
142
getAddedFiles,
143
+ mergeFiles,
108
144
}
0 commit comments