@@ -13,7 +13,7 @@ pub(crate) enum Node<L> {
13
13
Root { childs : Vec < Node < L > > } ,
14
14
Directory { name : PathBuf , childs : Vec < Node < L > > , license : Option < L > } ,
15
15
File { name : PathBuf , license : L } ,
16
- FileGroup { names : Vec < PathBuf > , license : L } ,
16
+ Group { files : Vec < PathBuf > , directories : Vec < PathBuf > , license : L } ,
17
17
Empty ,
18
18
}
19
19
@@ -22,7 +22,7 @@ impl Node<LicenseId> {
22
22
self . merge_directories ( ) ;
23
23
self . collapse_in_licensed_directories ( ) ;
24
24
self . merge_directory_licenses ( ) ;
25
- self . merge_file_groups ( ) ;
25
+ self . merge_groups ( ) ;
26
26
self . remove_empty ( ) ;
27
27
}
28
28
@@ -64,8 +64,8 @@ impl Node<LicenseId> {
64
64
Node :: Root { .. } => {
65
65
panic ! ( "can't have a root inside another element" ) ;
66
66
}
67
- Node :: FileGroup { .. } => {
68
- panic ! ( "FileGroup should not be present at this stage" ) ;
67
+ Node :: Group { .. } => {
68
+ panic ! ( "Group should not be present at this stage" ) ;
69
69
}
70
70
Node :: Directory { license : Some ( _) , .. } => {
71
71
panic ! ( "license should not be set at this stage" ) ;
@@ -86,8 +86,8 @@ impl Node<LicenseId> {
86
86
}
87
87
Node :: Empty => { }
88
88
Node :: File { .. } => { }
89
- Node :: FileGroup { .. } => {
90
- panic ! ( "FileGroup should not be present at this stage" ) ;
89
+ Node :: Group { .. } => {
90
+ panic ! ( "Group should not be present at this stage" ) ;
91
91
}
92
92
Node :: Directory { license : Some ( _) , .. } => {
93
93
panic ! ( "license should not be set at this stage" ) ;
@@ -132,7 +132,7 @@ impl Node<LicenseId> {
132
132
}
133
133
}
134
134
Node :: File { .. } => { }
135
- Node :: FileGroup { .. } => { }
135
+ Node :: Group { .. } => panic ! ( "group should not be present at this stage" ) ,
136
136
Node :: Empty => { }
137
137
}
138
138
}
@@ -165,8 +165,8 @@ impl Node<LicenseId> {
165
165
Node :: Root { .. } => {
166
166
panic ! ( "can't have a root inside another element" ) ;
167
167
}
168
- Node :: FileGroup { .. } => {
169
- panic ! ( "FileGroup should not be present at this stage" ) ;
168
+ Node :: Group { .. } => {
169
+ panic ! ( "Group should not be present at this stage" ) ;
170
170
}
171
171
Node :: Directory { name : child_child_name, .. } => {
172
172
* child_child_name = child_name. join ( & child_child_name) ;
@@ -185,38 +185,74 @@ impl Node<LicenseId> {
185
185
}
186
186
Node :: Empty => { }
187
187
Node :: File { .. } => { }
188
- Node :: FileGroup { .. } => { }
188
+ Node :: Group { .. } => panic ! ( "Group should not be present at this stage" ) ,
189
189
}
190
190
}
191
191
192
192
/// This pass groups multiple files in a directory with the same license into a single
193
- /// "FileGroup", so that the license of all those files can be reported as a group.
193
+ /// "Group", so that the license of all those files can be reported as a group.
194
+ ///
195
+ /// This also merges directories *without exceptions*.
194
196
///
195
197
/// Crucially this pass runs after collapse_in_licensed_directories, so the most common license
196
198
/// will already be marked as the directory's license and won't be turned into a group.
197
- fn merge_file_groups ( & mut self ) {
199
+ fn merge_groups ( & mut self ) {
200
+ #[ derive( Default ) ]
201
+ struct Grouped {
202
+ files : Vec < PathBuf > ,
203
+ directories : Vec < PathBuf > ,
204
+ }
198
205
match self {
199
206
Node :: Root { childs } | Node :: Directory { childs, .. } => {
200
- let mut grouped = BTreeMap :: new ( ) ;
207
+ let mut grouped: BTreeMap < LicenseId , Grouped > = BTreeMap :: new ( ) ;
201
208
202
209
for child in & mut * childs {
203
- child. merge_file_groups ( ) ;
204
- if let Node :: File { name, license } = child {
205
- grouped. entry ( * license) . or_insert_with ( Vec :: new) . push ( name. clone ( ) ) ;
206
- * child = Node :: Empty ;
210
+ child. merge_groups ( ) ;
211
+ match child {
212
+ Node :: Directory { name, childs, license : Some ( license) } => {
213
+ if childs. is_empty ( ) {
214
+ grouped
215
+ . entry ( * license)
216
+ . or_insert_with ( Grouped :: default)
217
+ . directories
218
+ . push ( name. clone ( ) ) ;
219
+ * child = Node :: Empty ;
220
+ }
221
+ }
222
+ Node :: File { name, license } => {
223
+ grouped
224
+ . entry ( * license)
225
+ . or_insert_with ( Grouped :: default)
226
+ . files
227
+ . push ( name. clone ( ) ) ;
228
+ * child = Node :: Empty ;
229
+ }
230
+ _ => { }
207
231
}
208
232
}
209
233
210
- for ( license, mut names) in grouped. into_iter ( ) {
211
- if names. len ( ) == 1 {
212
- childs. push ( Node :: File { license, name : names. pop ( ) . unwrap ( ) } ) ;
234
+ for ( license, mut grouped) in grouped. into_iter ( ) {
235
+ if grouped. files . len ( ) + grouped. directories . len ( ) <= 1 {
236
+ if let Some ( name) = grouped. files . pop ( ) {
237
+ childs. push ( Node :: File { license, name } ) ;
238
+ } else if let Some ( name) = grouped. directories . pop ( ) {
239
+ childs. push ( Node :: Directory {
240
+ name,
241
+ childs : Vec :: new ( ) ,
242
+ license : Some ( license) ,
243
+ } ) ;
244
+ }
213
245
} else {
214
- childs. push ( Node :: FileGroup { license, names } ) ;
246
+ childs. push ( Node :: Group {
247
+ license,
248
+ files : grouped. files ,
249
+ directories : grouped. directories ,
250
+ } ) ;
215
251
}
216
252
}
217
253
}
218
254
Node :: File { .. } => { }
219
- Node :: FileGroup { .. } => panic ! ( "FileGroup should not be present at this stage" ) ,
255
+ Node :: Group { .. } => panic ! ( "FileGroup should not be present at this stage" ) ,
220
256
Node :: Empty => { }
221
257
}
222
258
}
@@ -231,7 +267,7 @@ impl Node<LicenseId> {
231
267
}
232
268
childs. retain ( |child| !matches ! ( child, Node :: Empty ) ) ;
233
269
}
234
- Node :: FileGroup { .. } => { }
270
+ Node :: Group { .. } => { }
235
271
Node :: File { .. } => { }
236
272
Node :: Empty => { }
237
273
}
@@ -278,16 +314,22 @@ pub(crate) fn expand_interned_licenses(
278
314
) -> Node < & License > {
279
315
match node {
280
316
Node :: Root { childs } => Node :: Root {
281
- childs : childs. into_iter ( ) . map ( |child| expand_interned_licenses ( child, interner) ) . collect ( ) ,
317
+ childs : childs
318
+ . into_iter ( )
319
+ . map ( |child| expand_interned_licenses ( child, interner) )
320
+ . collect ( ) ,
282
321
} ,
283
322
Node :: Directory { name, childs, license } => Node :: Directory {
284
- childs : childs. into_iter ( ) . map ( |child| expand_interned_licenses ( child, interner) ) . collect ( ) ,
323
+ childs : childs
324
+ . into_iter ( )
325
+ . map ( |child| expand_interned_licenses ( child, interner) )
326
+ . collect ( ) ,
285
327
license : license. map ( |license| interner. resolve ( license) ) ,
286
328
name,
287
329
} ,
288
330
Node :: File { name, license } => Node :: File { name, license : interner. resolve ( license) } ,
289
- Node :: FileGroup { names , license } => {
290
- Node :: FileGroup { names , license : interner. resolve ( license) }
331
+ Node :: Group { files , directories , license } => {
332
+ Node :: Group { files , directories , license : interner. resolve ( license) }
291
333
}
292
334
Node :: Empty => Node :: Empty ,
293
335
}
0 commit comments