diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 12e3562b..313334d3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -38,7 +38,7 @@ jobs: with: key: udeps - run: cargo install --locked cargo-udeps@0.1.50 - - run: cargo udeps --all-targets + - run: cargo udeps --all-targets --all-features run_cargodeny: name: Run Cargo Deny @@ -142,7 +142,7 @@ jobs: - uses: Swatinem/rust-cache@23bce251a8cd2ffc3c1075eaa2367cf899916d84 # v2.7.3 with: key: test - - run: cargo test + - run: cargo test --all-features tests_passed: name: All tests passed diff --git a/Cargo.lock b/Cargo.lock index e2ccf753..60d7eba6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3088,6 +3088,9 @@ dependencies = [ name = "stackable-versioned" version = "0.3.0" dependencies = [ + "kube", + "snafu 0.8.4", + "stackable-shared", "stackable-versioned-macros", ] @@ -3112,6 +3115,8 @@ dependencies = [ "serde_json", "serde_yaml", "snafu 0.8.4", + "stackable-shared", + "stackable-versioned", "strum", "syn 2.0.77", "trybuild", diff --git a/crates/stackable-operator/Cargo.toml b/crates/stackable-operator/Cargo.toml index 0196fb8b..e6f182fc 100644 --- a/crates/stackable-operator/Cargo.toml +++ b/crates/stackable-operator/Cargo.toml @@ -11,8 +11,8 @@ repository.workspace = true time = ["dep:time"] [dependencies] -stackable-operator-derive = { path = "../stackable-operator-derive", version = "0.3.1" } -stackable-shared = { path = "../stackable-shared", version = "0.0.1" } +stackable-operator-derive = { path = "../stackable-operator-derive" } +stackable-shared = { path = "../stackable-shared" } chrono.workspace = true clap.workspace = true diff --git a/crates/stackable-versioned-macros/Cargo.toml b/crates/stackable-versioned-macros/Cargo.toml index 1329633c..f857f713 100644 --- a/crates/stackable-versioned-macros/Cargo.toml +++ b/crates/stackable-versioned-macros/Cargo.toml @@ -10,21 +10,26 @@ repository.workspace = true [package.metadata."docs.rs"] all-features = true -# cargo-udeps throws an error that these dependencies are unused. They are, -# however, used in K8s specific test cases. This is a false-positive and an +[package.metadata.cargo-udeps.ignore] +# cargo-udeps throws an error stating that these dependencies are unused. They +# are, however, used in K8s specific test cases. This is a false-positive and an # apparent limitation of cargo-udeps. These entries can be removed once # cargo-udeps supports detecting usage of such dependencies. -[package.metadata.cargo-udeps.ignore] -development = ["schemars", "serde_yaml"] +development = ["schemars", "serde_yaml", "stackable-versioned"] + +# cargo-udeps throws an error stating that these dependencies are unused. They are all marked as +# optional, which trips up cargo-udeps for whatever reason... +normal = ["k8s-openapi", "kube", "stackable-shared"] [lib] proc-macro = true [features] full = ["k8s"] -k8s = ["dep:kube", "dep:k8s-openapi"] +k8s = ["dep:kube", "dep:k8s-openapi", "dep:stackable-shared"] [dependencies] +stackable-shared = { path = "../stackable-shared", optional = true } k8s-version = { path = "../k8s-version", features = ["darling"] } convert_case.workspace = true @@ -38,6 +43,9 @@ syn.workspace = true quote.workspace = true [dev-dependencies] +# Only needed for doc tests / examples +stackable-versioned = { path = "../stackable-versioned", features = ["k8s"] } + insta.workspace = true prettyplease.workspace = true regex.workspace = true diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots.snap b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots.snap index 6561d0db..df79bb1d 100644 --- a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots.snap +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots.snap @@ -95,8 +95,7 @@ impl ::std::fmt::Display for Foo { } #[automatically_derived] impl Foo { - /// Generates a merged CRD which contains all versions defined using the - /// `#[versioned()]` macro. + /// Generates a merged CRD which contains all versions defined using the `#[versioned()]` macro. pub fn merged_crd( stored_apiversion: Self, ) -> ::std::result::Result< @@ -112,4 +111,49 @@ impl Foo { &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/src/codegen/vstruct/mod.rs b/crates/stackable-versioned-macros/src/codegen/vstruct/mod.rs index f48a80c2..6de44835 100644 --- a/crates/stackable-versioned-macros/src/codegen/vstruct/mod.rs +++ b/crates/stackable-versioned-macros/src/codegen/vstruct/mod.rs @@ -382,13 +382,51 @@ impl VersionedStruct { #[automatically_derived] impl #enum_ident { - /// Generates a merged CRD which contains all versions defined using the - /// `#[versioned()]` macro. + /// 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![#(#crd_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, + }) + } } } } diff --git a/crates/stackable-versioned/CHANGELOG.md b/crates/stackable-versioned/CHANGELOG.md index 2158638b..18f13541 100644 --- a/crates/stackable-versioned/CHANGELOG.md +++ b/crates/stackable-versioned/CHANGELOG.md @@ -6,9 +6,12 @@ All notable changes to this project will be documented in this file. ### Added +- Add YAML serialization for merged CRD schema. The schema can now be printed to stdout or written + to file ([#884]). - Add snapshot tests to verify generated code matches expected output ([#881]). [#881]: https://github.com/stackabletech/operator-rs/pull/881 +[#884]: https://github.com/stackabletech/operator-rs/pull/884 ## [0.3.0] - 2024-09-26 diff --git a/crates/stackable-versioned/Cargo.toml b/crates/stackable-versioned/Cargo.toml index c95a3b3e..2004914d 100644 --- a/crates/stackable-versioned/Cargo.toml +++ b/crates/stackable-versioned/Cargo.toml @@ -12,8 +12,16 @@ all-features = true [features] full = ["k8s"] -# Forward the k8s feature to the underlying macro crate -k8s = ["stackable-versioned-macros/k8s"] +k8s = [ + "stackable-versioned-macros/k8s", # Forward the k8s feature to the underlying macro crate + "dep:stackable-shared", + "dep:snafu", + "dep:kube", +] [dependencies] stackable-versioned-macros = { path = "../stackable-versioned-macros" } +stackable-shared = { path = "../stackable-shared", optional = true } + +kube = { workspace = true, optional = true } +snafu = { workspace = true, optional = true } diff --git a/crates/stackable-versioned/src/lib.rs b/crates/stackable-versioned/src/lib.rs index 1f2d99d1..6352ed30 100644 --- a/crates/stackable-versioned/src/lib.rs +++ b/crates/stackable-versioned/src/lib.rs @@ -12,8 +12,21 @@ //! See [`versioned`] for an in-depth usage guide and a list of supported //! parameters. +// Re-export macro pub use stackable_versioned_macros::*; +#[cfg(feature = "k8s")] +#[derive(Debug, snafu::Snafu)] +pub enum Error { + #[snafu(display("failed to merge CRDs"))] + MergeCrd { source: kube::core::crd::MergeError }, + + #[snafu(display("failed to serialize YAML"))] + SerializeYaml { + source: stackable_shared::yaml::Error, + }, +} + // Unused for now, might get picked up again in the future. #[doc(hidden)] pub trait AsVersionStr {