diff --git a/justfile b/justfile index 5b21142..4841f03 100644 --- a/justfile +++ b/justfile @@ -86,9 +86,9 @@ test-istio-destrule: cargo test --test runner -- --nocapture test-podmon: - curl -sSL https://github.com/prometheus-operator/prometheus-operator/raw/main/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml > tests/podmon-crd.yaml kubectl apply --server-side -f tests/podmon-crd.yaml - cargo run --bin kopium -- podmonitors.monitoring.coreos.com > tests/gen.rs + #curl -sSL https://github.com/prometheus-operator/prometheus-operator/raw/main/example/prometheus-operator-crd/monitoring.coreos.com_podmonitors.yaml > tests/podmon-crd.yaml + cargo run --bin kopium -- --no-rename RelabelingsAction podmonitors.monitoring.coreos.com > tests/gen.rs echo "pub type CR = PodMonitor;" >> tests/gen.rs kubectl apply -f tests/podmon.yaml cargo test --test runner -- --nocapture diff --git a/src/analyzer.rs b/src/analyzer.rs index 7aa4fb1..d28086d 100644 --- a/src/analyzer.rs +++ b/src/analyzer.rs @@ -173,7 +173,7 @@ fn find_containers( // plain enums do not need to recurse, can collect it here // ....although this makes it impossible for us to handle enums at the top level // TODO: move this to the top level - let new_result = analyze_enum_properties(en, &next_stack, level, schema)?; + let new_result = analyze_enum_properties(en, &next_stack, level, schema, cfg)?; results.push(new_result); } else { debug!("..not recursing into {} ('{}' is not a container)", key, x) @@ -190,6 +190,7 @@ fn analyze_enum_properties( stack: &str, level: u8, schema: &JSONSchemaProps, + cfg: &Config, ) -> Result { let mut members = vec![]; debug!("analyzing enum {}", serde_json::to_string(&schema).unwrap()); @@ -224,6 +225,7 @@ fn analyze_enum_properties( level, docs: schema.description.clone(), is_enum: true, + no_rename: cfg.no_rename.iter().any(|x| stack.contains(x)), }) } @@ -328,6 +330,7 @@ fn extract_container( level, docs: schema.description.clone(), is_enum: false, + no_rename: cfg.no_rename.iter().any(|x| stack.contains(x)), }) } @@ -740,8 +743,6 @@ type: object - Replace - keep - Keep - - drop - - Drop - labelkeep - LabelKeep type: string @@ -753,28 +754,31 @@ type: object type: object "#; let cfg = Cfg { - no_rename: vec!["MetricsRelabelingsAction".into()], + no_rename: vec!["RelabelingsAction".into()], ..Cfg::default() }; let schema: JSONSchemaProps = serde_yaml::from_str(schema_str).unwrap(); - let structs = analyze(schema, "MetricRelabelings", cfg).unwrap().0; + let structs = analyze(schema, "Endpoint", cfg).unwrap().0; println!("got {:?}", structs); let root = &structs[0]; - assert_eq!(root.name, "MetricRelabelings"); - assert_eq!(root.level, 0); - assert_eq!(&root.members[0].name, "action"); - assert_eq!(&root.members[0].type_, "MetricRelabelingsAction"); + assert_eq!(root.name, "Endpoint"); + assert_eq!(&root.members[0].type_, "Option>"); + assert!(!root.no_rename); // no-rename NOT set on EP (string not similar) - // operator member - let op = &structs[1]; - assert!(op.is_enum); - assert_eq!(op.name, "MetricRelabelingsAction"); + let rel = &structs[1]; + assert_eq!(rel.name, "EndpointRelabelings"); + assert_eq!(rel.is_enum, false); + assert_eq!(&rel.members[0].name, "action"); + assert_eq!(&rel.members[0].type_, "Option"); + assert!(!rel.no_rename); // no-rename NOT set EPR (action not in string) - // should have enum members that avoids the clashes - assert_eq!(&op.members[0].name, "replace"); - assert_eq!(&op.members[0].type_, ""); - assert_eq!(&op.members[0].name, "Replace"); - assert_eq!(&op.members[0].type_, ""); + // action enum member + let act = &structs[2]; + assert_eq!(act.name, "EndpointRelabelingsAction"); + assert_eq!(act.is_enum, true); + // no-rename SET! contains partial struct name + assert!(act.no_rename); + // NB: we verify that this causes no renames in output.rs } #[test] diff --git a/src/main.rs b/src/main.rs index 104b64f..f2b3e89 100644 --- a/src/main.rs +++ b/src/main.rs @@ -199,7 +199,7 @@ impl Kopium { log::debug!("schema: {}", serde_json::to_string_pretty(&schema)?); let cfg = Config { no_condition: self.no_condition, - no_rename: self.no_rename, + no_rename: self.no_rename.clone(), }; let structs = analyze(schema, kind, cfg)? .rename() diff --git a/src/output.rs b/src/output.rs index 5724f2a..a528be1 100644 --- a/src/output.rs +++ b/src/output.rs @@ -16,6 +16,8 @@ pub struct Container { pub docs: Option, /// Whether this container is an enum pub is_enum: bool, + /// Elide rename for this container (when passing no-rename) + pub no_rename: bool, } /// Output member belonging to an Container @@ -111,7 +113,7 @@ impl Container { .unwrap_or_else(|| panic!("invalid field name '{}' could not be escaped", m.name)) }; - if new_name != m.name { + if new_name != m.name && !self.no_rename { m.serde_annot.push(format!("rename = \"{}\"", m.name)); m.name = new_name; } @@ -177,3 +179,46 @@ impl Output { self } } + +// unit tests +#[cfg(test)] +mod test { + use super::{Container, Member}; + fn name_only_enum_member(name: &str) -> Member { + Member { + name: name.to_string(), + type_: "".to_string(), + serde_annot: vec![], + extra_annot: vec![], + docs: None, + } + } + + #[test] + fn no_rename_is_respected() { + let mut c = Container { + name: "EndpointRelabelingsAction".to_string(), + level: 1, + members: vec![ + name_only_enum_member("replace"), + name_only_enum_member("Replace"), + name_only_enum_member("keep"), + name_only_enum_member("Keep"), + name_only_enum_member("labelkeep"), + name_only_enum_member("LabelKeep"), + ], + docs: None, + is_enum: true, + no_rename: true, + }; + + c.rename(); + // should have enum members with ORIGINAL names AFTER rename + assert_eq!(&c.members[0].name, "replace"); + assert_eq!(&c.members[1].name, "Replace"); + assert_eq!(&c.members[2].name, "keep"); + assert_eq!(&c.members[3].name, "Keep"); + assert_eq!(&c.members[4].name, "labelkeep"); + assert_eq!(&c.members[5].name, "LabelKeep"); + } +}