@@ -279,6 +279,20 @@ fn merge_vec_field<T>(dest: &mut Option<Vec<T>>, src: &mut Option<Vec<T>>) {
279
279
}
280
280
}
281
281
282
+ /// Merge a map field similarly to Python's `dict.update()`. In case of
283
+ /// duplicate keys, `dest` wins (`src` is the "included" config).
284
+ fn merge_map_field < T > (
285
+ dest : & mut Option < HashMap < String , T > > ,
286
+ src : & mut Option < HashMap < String , T > > )
287
+ {
288
+ if let Some ( mut srcv) = src. take ( ) {
289
+ if let Some ( mut destv) = dest. take ( ) {
290
+ srcv. extend ( destv. drain ( ) ) ;
291
+ }
292
+ * dest = Some ( srcv) ;
293
+ }
294
+ }
295
+
282
296
/// Given two configs, merge them.
283
297
fn treefile_merge ( dest : & mut TreeComposeConfig , src : & mut TreeComposeConfig ) {
284
298
macro_rules! merge_basics {
@@ -291,6 +305,11 @@ fn treefile_merge(dest: &mut TreeComposeConfig, src: &mut TreeComposeConfig) {
291
305
$( merge_vec_field( & mut dest. $field, & mut src. $field) ; ) *
292
306
} } ;
293
307
} ;
308
+ macro_rules! merge_maps {
309
+ ( $( $field: ident) ,* ) => { {
310
+ $( merge_map_field( & mut dest. $field, & mut src. $field) ; ) *
311
+ } } ;
312
+ } ;
294
313
295
314
merge_basics ! (
296
315
treeref,
@@ -328,6 +347,9 @@ fn treefile_merge(dest: &mut TreeComposeConfig, src: &mut TreeComposeConfig) {
328
347
remove_files,
329
348
remove_from_packages
330
349
) ;
350
+ merge_maps ! (
351
+ add_commit_metadata
352
+ ) ;
331
353
}
332
354
333
355
/// Merge the treefile externals. There are currently only two keys that
@@ -663,6 +685,9 @@ struct TreeComposeConfig {
663
685
#[ serde( skip_serializing_if = "Option::is_none" ) ]
664
686
#[ serde( rename = "remove-from-packages" ) ]
665
687
remove_from_packages : Option < Vec < Vec < String > > > ,
688
+ #[ serde( skip_serializing_if = "Option::is_none" ) ]
689
+ #[ serde( rename = "add-commit-metadata" ) ]
690
+ add_commit_metadata : Option < HashMap < String , serde_json:: Value > > ,
666
691
667
692
#[ serde( flatten) ]
668
693
legacy_fields : LegacyTreeComposeConfigFields ,
@@ -1011,24 +1036,40 @@ rojig:
1011
1036
#[ test]
1012
1037
fn test_treefile_merge ( ) {
1013
1038
let basearch = Some ( ARCH_X86_64 ) ;
1014
- let mut base_input = io:: BufReader :: new ( VALID_PRELUDE . as_bytes ( ) ) ;
1015
- let mut base = treefile_parse_stream ( InputFormat :: YAML , & mut base_input, basearch) . unwrap ( ) ;
1039
+ let mut base = append_and_parse (
1040
+ r###"
1041
+ add-commit-metadata:
1042
+ my-first-key: "please don't override me"
1043
+ my-second-key: "override me"
1044
+ "### ,
1045
+ ) ;
1016
1046
let mut mid_input = io:: BufReader :: new (
1017
1047
r###"
1018
1048
packages:
1019
1049
- some layered packages
1050
+ add-commit-metadata:
1051
+ my-second-key: "something better"
1052
+ my-third-key: 1000
1053
+ my-fourth-key:
1054
+ nested: table
1020
1055
"###
1021
1056
. as_bytes ( ) ,
1022
1057
) ;
1023
1058
let mut mid = treefile_parse_stream ( InputFormat :: YAML , & mut mid_input, basearch) . unwrap ( ) ;
1024
1059
let mut top_input = io:: BufReader :: new ( ROJIG_YAML . as_bytes ( ) ) ;
1025
1060
let mut top = treefile_parse_stream ( InputFormat :: YAML , & mut top_input, basearch) . unwrap ( ) ;
1061
+ assert ! ( top. add_commit_metadata. is_none( ) ) ;
1026
1062
treefile_merge ( & mut mid, & mut base) ;
1027
1063
treefile_merge ( & mut top, & mut mid) ;
1028
1064
let tf = & top;
1029
1065
assert ! ( tf. packages. as_ref( ) . unwrap( ) . len( ) == 8 ) ;
1030
1066
let rojig = tf. rojig . as_ref ( ) . unwrap ( ) ;
1031
1067
assert ! ( rojig. name == "exampleos" ) ;
1068
+ let data = tf. add_commit_metadata . as_ref ( ) . unwrap ( ) ;
1069
+ assert ! ( data. get( "my-first-key" ) . unwrap( ) . as_str( ) . unwrap( ) == "please don't override me" ) ;
1070
+ assert ! ( data. get( "my-second-key" ) . unwrap( ) . as_str( ) . unwrap( ) == "something better" ) ;
1071
+ assert ! ( data. get( "my-third-key" ) . unwrap( ) . as_i64( ) . unwrap( ) == 1000 ) ;
1072
+ assert ! ( data. get( "my-fourth-key" ) . unwrap( ) . as_object( ) . unwrap( ) . get( "nested" ) . unwrap( ) . as_str( ) . unwrap( ) == "table" ) ;
1032
1073
}
1033
1074
1034
1075
#[ test]
0 commit comments