From 59cb9d5c6fbcecbe9a473fa3465d7d3712f3a5ab Mon Sep 17 00:00:00 2001 From: Techassi Date: Thu, 28 Nov 2024 15:30:23 +0100 Subject: [PATCH] refactor(stackable-versioned): Simplify crate overrides (#919) * refactor(stackable-versioned): Simplify crate overrides * chore(stackable-versioned): Update changelog * Apply suggestions from code review --------- Co-authored-by: Nick <10092581+NickLarsenNZ@users.noreply.github.com> --- .../fixtures/inputs/k8s/crate_overrides.rs | 26 +++ ..._macros__test__k8s_snapshots@basic.rs.snap | 6 +- ...est__k8s_snapshots@crate_overrides.rs.snap | 180 ++++++++++++++++ ...macros__test__k8s_snapshots@module.rs.snap | 12 +- ...est__k8s_snapshots@module_preserve.rs.snap | 12 +- .../src/attrs/k8s.rs | 28 --- .../src/codegen/container/mod.rs | 143 ++++++++++++- .../src/codegen/container/struct.rs | 195 ++++++++---------- crates/stackable-versioned/CHANGELOG.md | 2 + 9 files changed, 444 insertions(+), 160 deletions(-) create mode 100644 crates/stackable-versioned-macros/fixtures/inputs/k8s/crate_overrides.rs create mode 100644 crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@crate_overrides.rs.snap diff --git a/crates/stackable-versioned-macros/fixtures/inputs/k8s/crate_overrides.rs b/crates/stackable-versioned-macros/fixtures/inputs/k8s/crate_overrides.rs new file mode 100644 index 00000000..8b441cd0 --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/inputs/k8s/crate_overrides.rs @@ -0,0 +1,26 @@ +#[versioned( + version(name = "v1alpha1"), + version(name = "v1beta1"), + version(name = "v1"), + k8s( + group = "foo.example.org", + singular = "foo", + plural = "foos", + namespaced, + crates( + kube_core = ::kube::core + ) + ) +)] +// --- +#[derive( + Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema, kube::CustomResource, +)] +pub struct FooSpec { + #[versioned( + added(since = "v1beta1"), + changed(since = "v1", from_name = "bah", from_type = "u16") + )] + bar: usize, + baz: bool, +} diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@basic.rs.snap b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@basic.rs.snap index fce0647e..24ed425b 100644 --- a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@basic.rs.snap +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@basic.rs.snap @@ -122,9 +122,9 @@ impl Foo { > { ::kube::core::crd::merge_crds( vec![ - < v1alpha1::Foo as ::kube::CustomResourceExt > ::crd(), < v1beta1::Foo as - ::kube::CustomResourceExt > ::crd(), < v1::Foo as - ::kube::CustomResourceExt > ::crd() + < v1alpha1::Foo as ::kube::core::CustomResourceExt > ::crd(), < + v1beta1::Foo as ::kube::core::CustomResourceExt > ::crd(), < v1::Foo as + ::kube::core::CustomResourceExt > ::crd() ], &stored_apiversion.to_string(), ) diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@crate_overrides.rs.snap b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@crate_overrides.rs.snap new file mode 100644 index 00000000..121bc32e --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@crate_overrides.rs.snap @@ -0,0 +1,180 @@ +--- +source: crates/stackable-versioned-macros/src/lib.rs +expression: formatted +input_file: crates/stackable-versioned-macros/fixtures/inputs/k8s/crate_overrides.rs +--- +#[automatically_derived] +pub mod v1alpha1 { + use super::*; + #[derive( + Clone, + Debug, + serde::Deserialize, + serde::Serialize, + schemars::JsonSchema, + kube::CustomResource, + )] + #[kube( + group = "foo.example.org", + version = "v1alpha1", + kind = "Foo", + singular = "foo", + plural = "foos", + namespaced, + crates(kube_core = ::kube::core) + )] + pub struct FooSpec { + pub baz: bool, + } +} +#[automatically_derived] +impl ::std::convert::From for v1beta1::FooSpec { + fn from(__sv_foospec: v1alpha1::FooSpec) -> Self { + Self { + bah: ::std::default::Default::default(), + baz: __sv_foospec.baz, + } + } +} +#[automatically_derived] +pub mod v1beta1 { + use super::*; + #[derive( + Clone, + Debug, + serde::Deserialize, + serde::Serialize, + schemars::JsonSchema, + kube::CustomResource, + )] + #[kube( + group = "foo.example.org", + version = "v1beta1", + kind = "Foo", + singular = "foo", + plural = "foos", + namespaced, + crates(kube_core = ::kube::core) + )] + pub struct FooSpec { + pub bah: u16, + pub baz: bool, + } +} +#[automatically_derived] +impl ::std::convert::From for v1::FooSpec { + fn from(__sv_foospec: v1beta1::FooSpec) -> Self { + Self { + bar: __sv_foospec.bah.into(), + baz: __sv_foospec.baz, + } + } +} +#[automatically_derived] +pub mod v1 { + use super::*; + #[derive( + Clone, + Debug, + serde::Deserialize, + serde::Serialize, + schemars::JsonSchema, + kube::CustomResource, + )] + #[kube( + group = "foo.example.org", + version = "v1", + kind = "Foo", + singular = "foo", + plural = "foos", + namespaced, + crates(kube_core = ::kube::core) + )] + pub struct FooSpec { + pub bar: usize, + pub baz: bool, + } +} +#[automatically_derived] +pub enum Foo { + V1Alpha1, + V1Beta1, + V1, +} +#[automatically_derived] +impl ::std::fmt::Display for Foo { + fn fmt( + &self, + f: &mut ::std::fmt::Formatter<'_>, + ) -> ::std::result::Result<(), ::std::fmt::Error> { + match self { + Self::V1Alpha1 => f.write_str("v1alpha1"), + Self::V1Beta1 => f.write_str("v1beta1"), + Self::V1 => f.write_str("v1"), + } + } +} +#[automatically_derived] +impl Foo { + /// Generates a merged CRD which contains all versions defined using the `#[versioned()]` macro. + pub fn merged_crd( + stored_apiversion: Self, + ) -> ::std::result::Result< + ::k8s_openapi::apiextensions_apiserver::pkg::apis::apiextensions::v1::CustomResourceDefinition, + ::kube::core::crd::MergeError, + > { + ::kube::core::crd::merge_crds( + vec![ + < v1alpha1::Foo as ::kube::core::CustomResourceExt > ::crd(), < + v1beta1::Foo as ::kube::core::CustomResourceExt > ::crd(), < v1::Foo as + ::kube::core::CustomResourceExt > ::crd() + ], + &stored_apiversion.to_string(), + ) + } + /// Generates and writes a merged CRD which contains all versions defined using the `#[versioned()]` + /// macro to a file located at `path`. + pub fn write_merged_crd

( + path: P, + stored_apiversion: Self, + operator_version: &str, + ) -> Result<(), ::stackable_versioned::Error> + where + P: AsRef<::std::path::Path>, + { + use ::stackable_shared::yaml::{YamlSchema, SerializeOptions}; + let merged_crd = Self::merged_crd(stored_apiversion) + .map_err(|err| ::stackable_versioned::Error::MergeCrd { + source: err, + })?; + YamlSchema::write_yaml_schema( + &merged_crd, + path, + operator_version, + SerializeOptions::default(), + ) + .map_err(|err| ::stackable_versioned::Error::SerializeYaml { + source: err, + }) + } + /// Generates and writes a merged CRD which contains all versions defined using the `#[versioned()]` + /// macro to stdout. + pub fn print_merged_crd( + stored_apiversion: Self, + operator_version: &str, + ) -> Result<(), ::stackable_versioned::Error> { + use ::stackable_shared::yaml::{YamlSchema, SerializeOptions}; + let merged_crd = Self::merged_crd(stored_apiversion) + .map_err(|err| ::stackable_versioned::Error::MergeCrd { + source: err, + })?; + YamlSchema::print_yaml_schema( + &merged_crd, + operator_version, + SerializeOptions::default(), + ) + .map_err(|err| ::stackable_versioned::Error::SerializeYaml { + source: err, + }) + } +} diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@module.rs.snap b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@module.rs.snap index dfbe2f79..099c62bf 100644 --- a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@module.rs.snap +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@module.rs.snap @@ -235,9 +235,9 @@ impl Foo { > { ::kube::core::crd::merge_crds( vec![ - < v1alpha1::Foo as ::kube::CustomResourceExt > ::crd(), < v1::Foo as - ::kube::CustomResourceExt > ::crd(), < v2alpha1::Foo as - ::kube::CustomResourceExt > ::crd() + < v1alpha1::Foo as ::kube::core::CustomResourceExt > ::crd(), < v1::Foo + as ::kube::core::CustomResourceExt > ::crd(), < v2alpha1::Foo as + ::kube::core::CustomResourceExt > ::crd() ], &stored_apiversion.to_string(), ) @@ -318,9 +318,9 @@ impl Bar { > { ::kube::core::crd::merge_crds( vec![ - < v1alpha1::Bar as ::kube::CustomResourceExt > ::crd(), < v1::Bar as - ::kube::CustomResourceExt > ::crd(), < v2alpha1::Bar as - ::kube::CustomResourceExt > ::crd() + < v1alpha1::Bar as ::kube::core::CustomResourceExt > ::crd(), < v1::Bar + as ::kube::core::CustomResourceExt > ::crd(), < v2alpha1::Bar as + ::kube::core::CustomResourceExt > ::crd() ], &stored_apiversion.to_string(), ) diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@module_preserve.rs.snap b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@module_preserve.rs.snap index 40246829..01f4c033 100644 --- a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@module_preserve.rs.snap +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots@module_preserve.rs.snap @@ -223,9 +223,9 @@ pub(crate) mod versioned { > { ::kube::core::crd::merge_crds( vec![ - < v1alpha1::Foo as ::kube::CustomResourceExt > ::crd(), < v1::Foo as - ::kube::CustomResourceExt > ::crd(), < v2alpha1::Foo as - ::kube::CustomResourceExt > ::crd() + < v1alpha1::Foo as ::kube::core::CustomResourceExt > ::crd(), < + v1::Foo as ::kube::core::CustomResourceExt > ::crd(), < v2alpha1::Foo + as ::kube::core::CustomResourceExt > ::crd() ], &stored_apiversion.to_string(), ) @@ -303,9 +303,9 @@ pub(crate) mod versioned { > { ::kube::core::crd::merge_crds( vec![ - < v1alpha1::Bar as ::kube::CustomResourceExt > ::crd(), < v1::Bar as - ::kube::CustomResourceExt > ::crd(), < v2alpha1::Bar as - ::kube::CustomResourceExt > ::crd() + < v1alpha1::Bar as ::kube::core::CustomResourceExt > ::crd(), < + v1::Bar as ::kube::core::CustomResourceExt > ::crd(), < v2alpha1::Bar + as ::kube::core::CustomResourceExt > ::crd() ], &stored_apiversion.to_string(), ) diff --git a/crates/stackable-versioned-macros/src/attrs/k8s.rs b/crates/stackable-versioned-macros/src/attrs/k8s.rs index f4ad9851..0397d12c 100644 --- a/crates/stackable-versioned-macros/src/attrs/k8s.rs +++ b/crates/stackable-versioned-macros/src/attrs/k8s.rs @@ -1,6 +1,4 @@ use darling::{util::Flag, FromMeta}; -use proc_macro2::TokenStream; -use quote::{quote, ToTokens}; use syn::Path; /// This struct contains supported Kubernetes arguments. @@ -65,29 +63,3 @@ pub(crate) struct KubernetesCrateArguments { pub(crate) serde: Option, pub(crate) serde_json: Option, } - -impl ToTokens for KubernetesCrateArguments { - fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { - let mut crate_overrides = TokenStream::new(); - - if let Some(path) = &self.k8s_openapi { - crate_overrides.extend(quote! { k8s_openapi = #path, }); - } - if let Some(path) = &self.kube_core { - crate_overrides.extend(quote! { kube_core = #path, }); - } - if let Some(path) = &self.schemars { - crate_overrides.extend(quote! { schemars = #path, }); - } - if let Some(path) = &self.serde { - crate_overrides.extend(quote! { serde = #path, }); - } - if let Some(path) = &self.serde_json { - crate_overrides.extend(quote! { serde_json = #path, }); - } - - if !crate_overrides.is_empty() { - tokens.extend(quote! { , crates(#crate_overrides) }); - } - } -} diff --git a/crates/stackable-versioned-macros/src/codegen/container/mod.rs b/crates/stackable-versioned-macros/src/codegen/container/mod.rs index ef8f247b..048ba1a0 100644 --- a/crates/stackable-versioned-macros/src/codegen/container/mod.rs +++ b/crates/stackable-versioned-macros/src/codegen/container/mod.rs @@ -1,7 +1,9 @@ +use std::ops::Deref; + use darling::{util::IdentString, Result}; use proc_macro2::TokenStream; -use quote::quote; -use syn::{Attribute, Ident, ItemEnum, ItemStruct, Visibility}; +use quote::{quote, ToTokens}; +use syn::{parse_quote, Attribute, Ident, ItemEnum, ItemStruct, Path, Visibility}; use crate::{ attrs::{ @@ -259,7 +261,7 @@ pub(crate) struct KubernetesOptions { pub(crate) plural: Option, pub(crate) namespaced: bool, // root - pub(crate) crates: Option, + pub(crate) crates: KubernetesCrateOptions, pub(crate) status: Option, // derive // schema @@ -282,10 +284,143 @@ impl From for KubernetesOptions { singular: args.singular, plural: args.plural, namespaced: args.namespaced.is_present(), - crates: args.crates, + crates: args + .crates + .map_or_else(KubernetesCrateOptions::default, |crates| crates.into()), status: args.status, shortname: args.shortname, skip_merged_crd: args.skip.map_or(false, |s| s.merged_crd.is_present()), } } } + +#[derive(Debug)] +pub(crate) struct KubernetesCrateOptions { + pub(crate) kube_core: Override, + pub(crate) k8s_openapi: Override, + pub(crate) schemars: Override, + pub(crate) serde: Override, + pub(crate) serde_json: Override, +} + +impl Default for KubernetesCrateOptions { + fn default() -> Self { + Self { + k8s_openapi: Override::new_default(parse_quote! { ::k8s_openapi }), + serde_json: Override::new_default(parse_quote! { ::serde_json }), + kube_core: Override::new_default(parse_quote! { ::kube::core }), + schemars: Override::new_default(parse_quote! { ::schemars }), + serde: Override::new_default(parse_quote! { ::serde }), + } + } +} + +impl From for KubernetesCrateOptions { + fn from(args: KubernetesCrateArguments) -> Self { + let mut crate_options = Self::default(); + + if let Some(k8s_openapi) = args.k8s_openapi { + crate_options.k8s_openapi = Override::new_custom(k8s_openapi); + } + + if let Some(serde_json) = args.serde_json { + crate_options.serde_json = Override::new_custom(serde_json); + } + + if let Some(kube_core) = args.kube_core { + crate_options.kube_core = Override::new_custom(kube_core); + } + + if let Some(schemars) = args.schemars { + crate_options.schemars = Override::new_custom(schemars); + } + + if let Some(serde) = args.serde { + crate_options.serde = Override::new_custom(serde); + } + + crate_options + } +} + +impl ToTokens for KubernetesCrateOptions { + fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) { + let mut crate_overrides = TokenStream::new(); + + let KubernetesCrateOptions { + k8s_openapi, + serde_json, + kube_core, + schemars, + serde, + } = self; + + if let Some(k8s_openapi) = k8s_openapi.get_if_overridden() { + crate_overrides.extend(quote! { k8s_openapi = #k8s_openapi, }); + } + + if let Some(serde_json) = serde_json.get_if_overridden() { + crate_overrides.extend(quote! { serde_json = #serde_json, }); + } + + if let Some(kube_core) = kube_core.get_if_overridden() { + crate_overrides.extend(quote! { kube_core = #kube_core, }); + } + + if let Some(schemars) = schemars.get_if_overridden() { + crate_overrides.extend(quote! { schemars = #schemars, }); + } + + if let Some(serde) = serde.get_if_overridden() { + crate_overrides.extend(quote! { serde = #serde, }); + } + + if !crate_overrides.is_empty() { + tokens.extend(quote! { , crates(#crate_overrides) }); + } + } +} + +/// Wraps a value to indicate whether it is original or has been overridden. +#[derive(Debug)] +pub(crate) struct Override { + is_overridden: bool, + inner: T, +} + +impl Override { + /// Mark a value as a default. + /// + /// This is used to indicate that the value is a default and was not overridden. + pub(crate) fn new_default(inner: T) -> Self { + Override { + is_overridden: false, + inner, + } + } + + /// Mark a value as overridden. + /// + /// This is used to indicate that the value was overridden and not the default. + pub(crate) fn new_custom(inner: T) -> Self { + Override { + is_overridden: true, + inner, + } + } + + pub(crate) fn get_if_overridden(&self) -> Option<&T> { + match &self.is_overridden { + true => Some(&self.inner), + false => None, + } + } +} + +impl Deref for Override { + type Target = T; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} diff --git a/crates/stackable-versioned-macros/src/codegen/container/struct.rs b/crates/stackable-versioned-macros/src/codegen/container/struct.rs index ae385360..d09d0cee 100644 --- a/crates/stackable-versioned-macros/src/codegen/container/struct.rs +++ b/crates/stackable-versioned-macros/src/codegen/container/struct.rs @@ -1,6 +1,6 @@ use std::ops::Not; -use darling::{util::IdentString, Error, FromAttributes, FromMeta, Result}; +use darling::{util::IdentString, Error, FromAttributes, Result}; use proc_macro2::TokenStream; use quote::{quote, ToTokens}; use syn::{parse_quote, ItemStruct, Path}; @@ -306,21 +306,10 @@ impl Struct { &self, version: &VersionDefinition, ) -> Option<(IdentString, String, TokenStream)> { - let kube_core_module_default = &Path::from_string("::kube::core").expect("valid path"); - let kube_core_module = self.common.options.kubernetes_options.as_ref().map_or_else( - || quote! {#kube_core_module_default}, - |options| { - if let Some(crates) = &options.crates { - if let Some(kube_core) = &crates.kube_core { - return quote! {#kube_core}; - } - } - quote! {#kube_core_module_default} - }, - ); - match &self.common.options.kubernetes_options { Some(options) if !options.skip_merged_crd => { + let kube_core_path = &*options.crates.kube_core; + let enum_variant_ident = version.inner.as_variant_ident(); let enum_variant_string = version.inner.to_string(); @@ -329,7 +318,7 @@ impl Struct { let qualified_path: Path = parse_quote!(#module_ident::#struct_ident); let merge_crds_fn_call = quote! { - <#qualified_path as #kube_core_module::CustomResourceExt>::crd() + <#qualified_path as #kube_core_path::CustomResourceExt>::crd() }; Some((enum_variant_ident, enum_variant_string, merge_crds_fn_call)) @@ -345,109 +334,89 @@ impl Struct { fn_calls: &[TokenStream], is_nested: bool, ) -> Option { - if enum_variant_idents.is_empty() { - return None; - } + match &self.common.options.kubernetes_options { + Some(kubernetes_options) if !kubernetes_options.skip_merged_crd => { + let enum_ident = &self.common.idents.kubernetes; + + // Only add the #[automatically_derived] attribute if this impl is used outside of a + // module (in standalone mode). + let automatically_derived = + is_nested.not().then(|| quote! {#[automatically_derived]}); + + // Get the crate paths + let k8s_openapi_path = &*kubernetes_options.crates.k8s_openapi; + let kube_core_path = &*kubernetes_options.crates.kube_core; + + // TODO (@Techassi): Use proper visibility instead of hard-coding 'pub' + // TODO (@Techassi): Move the YAML printing code into 'stackable-versioned' so that we don't + // have any cross-dependencies and the macro can be used on it's own (K8s features of course + // still need kube and friends). + Some(quote! { + #automatically_derived + pub enum #enum_ident { + #(#enum_variant_idents),* + } - let enum_ident = &self.common.idents.kubernetes; + #automatically_derived + impl ::std::fmt::Display for #enum_ident { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::result::Result<(), ::std::fmt::Error> { + match self { + #(Self::#enum_variant_idents => f.write_str(#enum_variant_strings)),* + } + } + } - // Only add the #[automatically_derived] attribute if this impl is used outside of a - // module (in standalone mode). - let automatically_derived = is_nested.not().then(|| quote! {#[automatically_derived]}); + #automatically_derived + impl #enum_ident { + /// Generates a merged CRD which contains all versions defined using the `#[versioned()]` macro. + pub fn merged_crd( + stored_apiversion: Self + ) -> ::std::result::Result<#k8s_openapi_path::apiextensions_apiserver::pkg::apis::apiextensions::v1::CustomResourceDefinition, #kube_core_path::crd::MergeError> { + #kube_core_path::crd::merge_crds(vec![#(#fn_calls),*], &stored_apiversion.to_string()) + } - let kube_core_module_default = &Path::from_string("::kube::core").expect("valid path"); - let kube_core_module = self.common.options.kubernetes_options.as_ref().map_or_else( - || quote! {#kube_core_module_default}, - |options| { - if let Some(crates) = &options.crates { - if let Some(kube_core) = &crates.kube_core { - return quote! {#kube_core}; - } - } - quote! {#kube_core_module_default} - }, - ); - - let k8s_openapi_crate_default = &Path::from_string("::k8s_openapi").expect("valid path"); - let k8s_openapi_crate = self.common.options.kubernetes_options.as_ref().map_or_else( - || quote! {#k8s_openapi_crate_default}, - |options| { - if let Some(crates) = &options.crates { - if let Some(k8s_openapi) = &crates.k8s_openapi { - return quote! {#k8s_openapi}; - } - } - quote! {#k8s_openapi_crate_default} - }, - ); - - // TODO (@Techassi): Use proper visibility instead of hard-coding 'pub' - // TODO (@Techassi): Move the YAML printing code into 'stackable-versioned' so that we don't - // have any cross-dependencies and the macro can be used on it's own (K8s features of course - // still need kube and friends). - Some(quote! { - #automatically_derived - pub enum #enum_ident { - #(#enum_variant_idents),* - } + /// Generates and writes a merged CRD which contains all versions defined using the `#[versioned()]` + /// macro to a file located at `path`. + pub fn write_merged_crd

(path: P, stored_apiversion: Self, operator_version: &str) -> Result<(), ::stackable_versioned::Error> + where P: AsRef<::std::path::Path> + { + use ::stackable_shared::yaml::{YamlSchema, SerializeOptions}; + + let merged_crd = Self::merged_crd(stored_apiversion).map_err(|err| ::stackable_versioned::Error::MergeCrd { + source: err, + })?; + + YamlSchema::write_yaml_schema( + &merged_crd, + path, + operator_version, + SerializeOptions::default() + ).map_err(|err| ::stackable_versioned::Error::SerializeYaml { + source: err, + }) + } - #automatically_derived - impl ::std::fmt::Display for #enum_ident { - fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::result::Result<(), ::std::fmt::Error> { - match self { - #(Self::#enum_variant_idents => f.write_str(#enum_variant_strings)),* + /// Generates and writes a merged CRD which contains all versions defined using the `#[versioned()]` + /// macro to stdout. + pub fn print_merged_crd(stored_apiversion: Self, operator_version: &str) -> Result<(), ::stackable_versioned::Error> { + use ::stackable_shared::yaml::{YamlSchema, SerializeOptions}; + + let merged_crd = Self::merged_crd(stored_apiversion).map_err(|err| ::stackable_versioned::Error::MergeCrd { + source: err, + })?; + + YamlSchema::print_yaml_schema( + &merged_crd, + operator_version, + SerializeOptions::default() + ).map_err(|err| ::stackable_versioned::Error::SerializeYaml { + source: err, + }) + } } - } - } - - #automatically_derived - impl #enum_ident { - /// Generates a merged CRD which contains all versions defined using the `#[versioned()]` macro. - pub fn merged_crd( - stored_apiversion: Self - ) -> ::std::result::Result<#k8s_openapi_crate::apiextensions_apiserver::pkg::apis::apiextensions::v1::CustomResourceDefinition, #kube_core_module::crd::MergeError> { - #kube_core_module::crd::merge_crds(vec![#(#fn_calls),*], &stored_apiversion.to_string()) - } - - /// Generates and writes a merged CRD which contains all versions defined using the `#[versioned()]` - /// macro to a file located at `path`. - pub fn write_merged_crd

(path: P, stored_apiversion: Self, operator_version: &str) -> Result<(), ::stackable_versioned::Error> - where P: AsRef<::std::path::Path> - { - use ::stackable_shared::yaml::{YamlSchema, SerializeOptions}; - - let merged_crd = Self::merged_crd(stored_apiversion).map_err(|err| ::stackable_versioned::Error::MergeCrd { - source: err, - })?; - - YamlSchema::write_yaml_schema( - &merged_crd, - path, - operator_version, - SerializeOptions::default() - ).map_err(|err| ::stackable_versioned::Error::SerializeYaml { - source: err, - }) - } - - /// Generates and writes a merged CRD which contains all versions defined using the `#[versioned()]` - /// macro to stdout. - pub fn print_merged_crd(stored_apiversion: Self, operator_version: &str) -> Result<(), ::stackable_versioned::Error> { - use ::stackable_shared::yaml::{YamlSchema, SerializeOptions}; - - let merged_crd = Self::merged_crd(stored_apiversion).map_err(|err| ::stackable_versioned::Error::MergeCrd { - source: err, - })?; - - YamlSchema::print_yaml_schema( - &merged_crd, - operator_version, - SerializeOptions::default() - ).map_err(|err| ::stackable_versioned::Error::SerializeYaml { - source: err, - }) - } + }) } - }) + _ => None, + } } } diff --git a/crates/stackable-versioned/CHANGELOG.md b/crates/stackable-versioned/CHANGELOG.md index af68f221..85756ea7 100644 --- a/crates/stackable-versioned/CHANGELOG.md +++ b/crates/stackable-versioned/CHANGELOG.md @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. ### Changed +- Simplify crate override handling and generation ([#919]). - Bump Rust to 1.82.0 ([#891]). ### Fixed @@ -29,6 +30,7 @@ All notable changes to this project will be documented in this file. [#912]: https://github.com/stackabletech/operator-rs/pull/912 [#913]: https://github.com/stackabletech/operator-rs/pull/913 [#914]: https://github.com/stackabletech/operator-rs/pull/914 +[#919]: https://github.com/stackabletech/operator-rs/pull/919 ## [0.4.1] - 2024-10-23