From 233033626c119e1996d6734279adf89091719cee Mon Sep 17 00:00:00 2001 From: Techassi Date: Tue, 8 Oct 2024 12:27:51 +0200 Subject: [PATCH 01/10] feat(stackable-versioned): Add YAML serialization for merged CRD --- Cargo.lock | 1 + crates/stackable-versioned-macros/Cargo.toml | 3 +- ...versioned_macros__test__k8s_snapshots.snap | 31 +++++++++++++++-- .../src/codegen/vstruct/mod.rs | 34 +++++++++++++++++-- 4 files changed, 64 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e2ccf753..2319512d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3112,6 +3112,7 @@ dependencies = [ "serde_json", "serde_yaml", "snafu 0.8.4", + "stackable-shared", "strum", "syn 2.0.77", "trybuild", diff --git a/crates/stackable-versioned-macros/Cargo.toml b/crates/stackable-versioned-macros/Cargo.toml index 1329633c..7f6790e3 100644 --- a/crates/stackable-versioned-macros/Cargo.toml +++ b/crates/stackable-versioned-macros/Cargo.toml @@ -22,9 +22,10 @@ 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 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..e2bb9091 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,32 @@ 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) + where + P: AsRef<::std::path::Path>, + { + use ::stackable_shared::yaml::{YamlSchema, SerializeOptions}; + let merged_crd = Self::merged_crd(stored_apiversion).unwrap(); + YamlSchema::write_yaml_schema( + &merged_crd, + path, + operator_version, + SerializeOptions::default(), + ) + .unwrap(); + } + /// 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) { + use ::stackable_shared::yaml::{YamlSchema, SerializeOptions}; + let merged_crd = Self::merged_crd(stored_apiversion).unwrap(); + YamlSchema::print_yaml_schema( + &merged_crd, + operator_version, + SerializeOptions::default(), + ) + .unwrap(); + } } diff --git a/crates/stackable-versioned-macros/src/codegen/vstruct/mod.rs b/crates/stackable-versioned-macros/src/codegen/vstruct/mod.rs index f48a80c2..a4f02e08 100644 --- a/crates/stackable-versioned-macros/src/codegen/vstruct/mod.rs +++ b/crates/stackable-versioned-macros/src/codegen/vstruct/mod.rs @@ -382,13 +382,43 @@ 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) + where P: AsRef<::std::path::Path> + { + use ::stackable_shared::yaml::{YamlSchema, SerializeOptions}; + + let merged_crd = Self::merged_crd(stored_apiversion).unwrap(); + + YamlSchema::write_yaml_schema( + &merged_crd, + path, + operator_version, + SerializeOptions::default() + ).unwrap(); + } + + /// 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) { + use ::stackable_shared::yaml::{YamlSchema, SerializeOptions}; + + let merged_crd = Self::merged_crd(stored_apiversion).unwrap(); + + YamlSchema::print_yaml_schema( + &merged_crd, + operator_version, + SerializeOptions::default() + ).unwrap(); + } } } } From e7639705cae5c3a3e5daac3467c37d5834a6195d Mon Sep 17 00:00:00 2001 From: Techassi Date: Tue, 8 Oct 2024 12:33:13 +0200 Subject: [PATCH 02/10] chore: Add versions to local dependencies --- crates/stackable-versioned-macros/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/stackable-versioned-macros/Cargo.toml b/crates/stackable-versioned-macros/Cargo.toml index 7f6790e3..45e5cc63 100644 --- a/crates/stackable-versioned-macros/Cargo.toml +++ b/crates/stackable-versioned-macros/Cargo.toml @@ -25,8 +25,8 @@ full = ["k8s"] k8s = ["dep:kube", "dep:k8s-openapi", "dep:stackable-shared"] [dependencies] -stackable-shared = { path = "../stackable-shared", optional = true } -k8s-version = { path = "../k8s-version", features = ["darling"] } +stackable-shared = { path = "../stackable-shared", version = "0.0.1", optional = true } +k8s-version = { path = "../k8s-version", version = "0.1.2", features = ["darling"] } convert_case.workspace = true darling.workspace = true From c4fe882065fefb1d7958972518b501b61c313788 Mon Sep 17 00:00:00 2001 From: Techassi Date: Wed, 9 Oct 2024 08:39:45 +0200 Subject: [PATCH 03/10] chore: Add changelog entry --- crates/stackable-versioned/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) 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 From 9e538403cc6c9bd8267b0ad5a5d81653d78ea270 Mon Sep 17 00:00:00 2001 From: Techassi Date: Wed, 9 Oct 2024 14:22:08 +0200 Subject: [PATCH 04/10] feat: Make YAML helpers fallible --- Cargo.lock | 3 +++ .../src/codegen/vstruct/mod.rs | 20 +++++++++++++------ crates/stackable-versioned/Cargo.toml | 12 +++++++++-- crates/stackable-versioned/src/lib.rs | 13 ++++++++++++ 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2319512d..3b8dc922 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", ] diff --git a/crates/stackable-versioned-macros/src/codegen/vstruct/mod.rs b/crates/stackable-versioned-macros/src/codegen/vstruct/mod.rs index a4f02e08..6de44835 100644 --- a/crates/stackable-versioned-macros/src/codegen/vstruct/mod.rs +++ b/crates/stackable-versioned-macros/src/codegen/vstruct/mod.rs @@ -391,33 +391,41 @@ impl VersionedStruct { /// 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) + 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).unwrap(); + 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() - ).unwrap(); + ).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) { + 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).unwrap(); + 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() - ).unwrap(); + ).map_err(|err| ::stackable_versioned::Error::SerializeYaml { + source: err, + }) } } } diff --git a/crates/stackable-versioned/Cargo.toml b/crates/stackable-versioned/Cargo.toml index c95a3b3e..eac679b9 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-shared = { path = "../stackable-shared", version = "0.0.1", optional = true } stackable-versioned-macros = { path = "../stackable-versioned-macros" } + +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 { From e808f4912c931dcb8a27dd2f5cb6c9f650b24a9b Mon Sep 17 00:00:00 2001 From: Techassi Date: Wed, 9 Oct 2024 15:07:34 +0200 Subject: [PATCH 05/10] test: Update snapshot file --- ...versioned_macros__test__k8s_snapshots.snap | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) 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 e2bb9091..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 @@ -113,30 +113,47 @@ impl Foo { } /// 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) + 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).unwrap(); + 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(), ) - .unwrap(); + .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) { + 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).unwrap(); + 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(), ) - .unwrap(); + .map_err(|err| ::stackable_versioned::Error::SerializeYaml { + source: err, + }) } } From c714a1f8005968ad555a4c4ce69df47a4a44ea41 Mon Sep 17 00:00:00 2001 From: Techassi Date: Wed, 9 Oct 2024 15:13:04 +0200 Subject: [PATCH 06/10] chore: Remove explicit dependency versions --- crates/stackable-operator/Cargo.toml | 4 ++-- crates/stackable-versioned-macros/Cargo.toml | 4 ++-- crates/stackable-versioned/Cargo.toml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) 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 45e5cc63..7f6790e3 100644 --- a/crates/stackable-versioned-macros/Cargo.toml +++ b/crates/stackable-versioned-macros/Cargo.toml @@ -25,8 +25,8 @@ full = ["k8s"] k8s = ["dep:kube", "dep:k8s-openapi", "dep:stackable-shared"] [dependencies] -stackable-shared = { path = "../stackable-shared", version = "0.0.1", optional = true } -k8s-version = { path = "../k8s-version", version = "0.1.2", features = ["darling"] } +stackable-shared = { path = "../stackable-shared", optional = true } +k8s-version = { path = "../k8s-version", features = ["darling"] } convert_case.workspace = true darling.workspace = true diff --git a/crates/stackable-versioned/Cargo.toml b/crates/stackable-versioned/Cargo.toml index eac679b9..2004914d 100644 --- a/crates/stackable-versioned/Cargo.toml +++ b/crates/stackable-versioned/Cargo.toml @@ -20,8 +20,8 @@ k8s = [ ] [dependencies] -stackable-shared = { path = "../stackable-shared", version = "0.0.1", optional = true } stackable-versioned-macros = { path = "../stackable-versioned-macros" } +stackable-shared = { path = "../stackable-shared", optional = true } kube = { workspace = true, optional = true } snafu = { workspace = true, optional = true } From 58e336b695b42e3ff8014aff5693a4ea33052637 Mon Sep 17 00:00:00 2001 From: Techassi Date: Wed, 9 Oct 2024 15:15:23 +0200 Subject: [PATCH 07/10] ci: Run cargo test on all features --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 12e3562b..8b75d9fb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -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 From edc7ffe5adeb1ae93b4b3936198acc3964f175a5 Mon Sep 17 00:00:00 2001 From: Techassi Date: Wed, 9 Oct 2024 15:31:17 +0200 Subject: [PATCH 08/10] test: Fix K8s doc test --- Cargo.lock | 1 + crates/stackable-versioned-macros/Cargo.toml | 3 +++ 2 files changed, 4 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 3b8dc922..60d7eba6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3116,6 +3116,7 @@ dependencies = [ "serde_yaml", "snafu 0.8.4", "stackable-shared", + "stackable-versioned", "strum", "syn 2.0.77", "trybuild", diff --git a/crates/stackable-versioned-macros/Cargo.toml b/crates/stackable-versioned-macros/Cargo.toml index 7f6790e3..3945722a 100644 --- a/crates/stackable-versioned-macros/Cargo.toml +++ b/crates/stackable-versioned-macros/Cargo.toml @@ -39,6 +39,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 From 0d6f5aea07ad8b7d9283062d995ee2d2485911cd Mon Sep 17 00:00:00 2001 From: Techassi Date: Wed, 9 Oct 2024 15:42:10 +0200 Subject: [PATCH 09/10] ci: Run cargo-udeps with all features --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8b75d9fb..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 From 209ed8e821c2ac16955303a2ead8de2052778b03 Mon Sep 17 00:00:00 2001 From: Techassi Date: Wed, 9 Oct 2024 15:55:18 +0200 Subject: [PATCH 10/10] chore: Add cargo-udeps ignores --- crates/stackable-versioned-macros/Cargo.toml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/crates/stackable-versioned-macros/Cargo.toml b/crates/stackable-versioned-macros/Cargo.toml index 3945722a..f857f713 100644 --- a/crates/stackable-versioned-macros/Cargo.toml +++ b/crates/stackable-versioned-macros/Cargo.toml @@ -10,12 +10,16 @@ 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