mirror of
https://github.com/WarrenHood/MCModpackManager.git
synced 2025-04-29 14:05:00 +01:00
Added WIP support for merging yaml files
This commit is contained in:
parent
3e56632ef0
commit
0af0d62639
20
Cargo.lock
generated
20
Cargo.lock
generated
|
@ -2075,6 +2075,7 @@ dependencies = [
|
||||||
"semver",
|
"semver",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"serde_yaml",
|
||||||
"sha1",
|
"sha1",
|
||||||
"sha2",
|
"sha2",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
|
@ -3237,6 +3238,19 @@ dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_yaml"
|
||||||
|
version = "0.9.34+deprecated"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
"unsafe-libyaml",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sha1"
|
name = "sha1"
|
||||||
version = "0.10.6"
|
version = "0.10.6"
|
||||||
|
@ -3923,6 +3937,12 @@ version = "0.2.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a"
|
checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unsafe-libyaml"
|
||||||
|
version = "0.2.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "untrusted"
|
name = "untrusted"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
|
|
@ -14,6 +14,7 @@ reqwest = { version = "0.12.5", features = ["json"] }
|
||||||
semver = { version = "1.0.23", features = ["serde"] }
|
semver = { version = "1.0.23", features = ["serde"] }
|
||||||
serde = { version = "1.0.207", features = ["derive"] }
|
serde = { version = "1.0.207", features = ["derive"] }
|
||||||
serde_json = "1.0.128"
|
serde_json = "1.0.128"
|
||||||
|
serde_yaml = "0.9.34"
|
||||||
sha1 = "0.10.6"
|
sha1 = "0.10.6"
|
||||||
sha2 = "0.10.8"
|
sha2 = "0.10.8"
|
||||||
tempfile = "3.12.0"
|
tempfile = "3.12.0"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{any::Any, default, str::FromStr};
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum FileType {
|
pub enum FileType {
|
||||||
|
@ -81,50 +81,164 @@ fn test_merge_json() {
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
merged_overwrite["b"]["y"]["test"] == "thing",
|
merged_overwrite["b"]["y"]["test"] == "thing",
|
||||||
"//b/y/test wasn't overwritten with \"thing\". src={}, dst={}",
|
"//b/y/test wasn't overwritten with \"thing\". src={:#?}, dst={:#?}",
|
||||||
src,
|
src,
|
||||||
merged_overwrite
|
merged_overwrite
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
merged_overwrite["a"] == 3,
|
merged_overwrite["a"] == 3,
|
||||||
"//a was not set to 3. src={}, dst={}",
|
"//a was not set to 3. src={:#?}, dst={:#?}",
|
||||||
src,
|
src,
|
||||||
merged_overwrite
|
merged_overwrite
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
merged_overwrite["b"]["x"].is_object(),
|
merged_overwrite["b"]["x"].is_object(),
|
||||||
"//b/x is not an object. src={}, dst={}",
|
"//b/x is not an object. src={:#?}, dst={:#?}",
|
||||||
src,
|
src,
|
||||||
merged_overwrite
|
merged_overwrite
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
merged_overwrite["c"]["foo"] == "bar",
|
merged_overwrite["c"]["foo"] == "bar",
|
||||||
"//c/foo != bar. src={}, dst={}",
|
"//c/foo != bar. src={:#?}, dst={:#?}",
|
||||||
src,
|
src,
|
||||||
merged_overwrite
|
merged_overwrite
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
merged_retained["b"]["y"]["test"] == "something",
|
merged_retained["b"]["y"]["test"] == "something",
|
||||||
"//b/y/test was overwritten. src={}, dst={}",
|
"//b/y/test was overwritten. src={:#?}, dst={:#?}",
|
||||||
src,
|
src,
|
||||||
merged_retained
|
merged_retained
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
merged_retained["a"] == 3,
|
merged_retained["a"] == 3,
|
||||||
"//a was not set to 3. src={}, dst={}",
|
"//a was not set to 3. src={:#?}, dst={:#?}",
|
||||||
src,
|
src,
|
||||||
merged_retained
|
merged_retained
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
merged_retained["b"]["x"].is_object(),
|
merged_retained["b"]["x"].is_object(),
|
||||||
"//b/x is not an object. src={}, dst={}",
|
"//b/x is not an object. src={:#?}, dst={:#?}",
|
||||||
src,
|
src,
|
||||||
merged_retained
|
merged_retained
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
merged_retained["c"]["foo"] == "bar",
|
merged_retained["c"]["foo"] == "bar",
|
||||||
"//c/foo != bar. src={}, dst={}",
|
"//c/foo != bar. src={:#?}, dst={:#?}",
|
||||||
|
src,
|
||||||
|
merged_retained
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn merge_yaml(
|
||||||
|
src: &serde_yaml::Value,
|
||||||
|
dst: &mut serde_yaml::Value,
|
||||||
|
overwrite_existing: bool,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
if src.is_mapping() && dst.is_mapping() {
|
||||||
|
let src = src.as_mapping().unwrap();
|
||||||
|
let dst = dst.as_mapping_mut().unwrap();
|
||||||
|
|
||||||
|
for (k, v) in src.iter() {
|
||||||
|
if v.is_mapping() {
|
||||||
|
let dst_v = dst.entry(k.clone()).or_insert(serde_yaml::from_str("{}")?);
|
||||||
|
merge_yaml(v, dst_v, overwrite_existing)?;
|
||||||
|
} else {
|
||||||
|
if overwrite_existing || !dst.contains_key(k) {
|
||||||
|
dst.insert(k.clone(), v.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: Keep track of path for better errors
|
||||||
|
anyhow::bail!("Cannot merge non-objects: {src:#?} and {dst:#?}")
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_merge_yaml() {
|
||||||
|
let src = serde_yaml::from_str(
|
||||||
|
r#"{
|
||||||
|
"a": 3,
|
||||||
|
"b": {
|
||||||
|
"x": {
|
||||||
|
|
||||||
|
},
|
||||||
|
"y": {
|
||||||
|
"test": "thing"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"c": {}
|
||||||
|
}"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let dst: serde_yaml::Value = serde_yaml::from_str(
|
||||||
|
r#"{
|
||||||
|
"b": {
|
||||||
|
"y": {
|
||||||
|
"test": "something"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"c": {
|
||||||
|
"foo": "bar"
|
||||||
|
}
|
||||||
|
}"#,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut merged_overwrite = dst.clone();
|
||||||
|
let mut merged_retained = dst.clone();
|
||||||
|
merge_yaml(&src, &mut merged_overwrite, true).unwrap();
|
||||||
|
merge_yaml(&src, &mut merged_retained, false).unwrap();
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
merged_overwrite["b"]["y"]["test"] == "thing",
|
||||||
|
"//b/y/test wasn't overwritten with \"thing\". src={:#?}, dst={:#?}",
|
||||||
|
src,
|
||||||
|
merged_overwrite
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
merged_overwrite["a"] == 3,
|
||||||
|
"//a was not set to 3. src={:#?}, dst={:#?}",
|
||||||
|
src,
|
||||||
|
merged_overwrite
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
merged_overwrite["b"]["x"].is_mapping(),
|
||||||
|
"//b/x is not a mapping. src={:#?}, dst={:#?}",
|
||||||
|
src,
|
||||||
|
merged_overwrite
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
merged_overwrite["c"]["foo"] == "bar",
|
||||||
|
"//c/foo != bar. src={:#?}, dst={:#?}",
|
||||||
|
src,
|
||||||
|
merged_overwrite
|
||||||
|
);
|
||||||
|
|
||||||
|
assert!(
|
||||||
|
merged_retained["b"]["y"]["test"] == "something",
|
||||||
|
"//b/y/test was overwritten. src={:#?}, dst={:#?}",
|
||||||
|
src,
|
||||||
|
merged_retained
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
merged_retained["a"] == 3,
|
||||||
|
"//a was not set to 3. src={:#?}, dst={:#?}",
|
||||||
|
src,
|
||||||
|
merged_retained
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
merged_retained["b"]["x"].is_mapping(),
|
||||||
|
"//b/x is not a mapping. src={:#?}, dst={:#?}",
|
||||||
|
src,
|
||||||
|
merged_retained
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
merged_retained["c"]["foo"] == "bar",
|
||||||
|
"//c/foo != bar. src={:#?}, dst={:#?}",
|
||||||
src,
|
src,
|
||||||
merged_retained
|
merged_retained
|
||||||
);
|
);
|
||||||
|
@ -144,7 +258,12 @@ fn merge_files(
|
||||||
merge_json(&src_val, &mut dst_val, overwrite_existing)?;
|
merge_json(&src_val, &mut dst_val, overwrite_existing)?;
|
||||||
dst_val.to_string()
|
dst_val.to_string()
|
||||||
}
|
}
|
||||||
FileType::Yaml => todo!(),
|
FileType::Yaml => {
|
||||||
|
let src_val = serde_yaml::Value::from(src);
|
||||||
|
let mut dst_val = serde_yaml::Value::from(dst);
|
||||||
|
merge_yaml(&src_val, &mut dst_val, overwrite_existing)?;
|
||||||
|
serde_yaml::to_string(&dst_val)?
|
||||||
|
}
|
||||||
FileType::Toml => todo!(),
|
FileType::Toml => todo!(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue