Skip to content

Commit

Permalink
feat(stackable-versioned): Add YAML serialization for merged CRD (#884)
Browse files Browse the repository at this point in the history
* feat(stackable-versioned): Add YAML serialization for merged CRD

* chore: Add versions to local dependencies

* chore: Add changelog entry

* feat: Make YAML helpers fallible

* test: Update snapshot file

* chore: Remove explicit dependency versions

* ci: Run cargo test on all features

* test: Fix K8s doc test

* ci: Run cargo-udeps with all features

* chore: Add cargo-udeps ignores
  • Loading branch information
Techassi authored Oct 9, 2024
1 parent 194d33e commit daf9908
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 15 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
with:
key: udeps
- run: cargo install --locked [email protected]
- run: cargo udeps --all-targets
- run: cargo udeps --all-targets --all-features

run_cargodeny:
name: Run Cargo Deny
Expand Down Expand Up @@ -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
Expand Down
5 changes: 5 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions crates/stackable-operator/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
18 changes: 13 additions & 5 deletions crates/stackable-versioned-macros/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

42 changes: 40 additions & 2 deletions crates/stackable-versioned-macros/src/codegen/vstruct/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<P>(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,
})
}
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions crates/stackable-versioned/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 10 additions & 2 deletions crates/stackable-versioned/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
13 changes: 13 additions & 0 deletions crates/stackable-versioned/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down

0 comments on commit daf9908

Please sign in to comment.