diff --git a/Cargo.lock b/Cargo.lock index 6cae06ced..8869e1884 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -729,17 +729,6 @@ dependencies = [ "powerfmt", ] -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "digest" version = "0.10.7" @@ -3043,8 +3032,8 @@ dependencies = [ "clap", "const_format", "delegate", - "derivative", "dockerfile-parser", + "educe", "either", "futures", "indexmap 2.6.0", diff --git a/Cargo.toml b/Cargo.toml index 5530a075e..610c77350 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,9 +19,9 @@ const-oid = "0.9.6" convert_case = "0.6.0" darling = "0.20.10" delegate = "0.13.0" -derivative = "2.2.0" dockerfile-parser = "0.8.0" ecdsa = { version = "0.16.9", features = ["digest", "pem"] } +educe = { version = "0.6.0", default-features = false, features = ["Clone", "Debug", "Default", "PartialEq"] } either = "1.13.0" futures = "0.3.30" futures-util = "0.3.30" diff --git a/crates/stackable-operator/CHANGELOG.md b/crates/stackable-operator/CHANGELOG.md index c01e7972e..bed1cdff7 100644 --- a/crates/stackable-operator/CHANGELOG.md +++ b/crates/stackable-operator/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Changed + +- Replace unmaintained `derivative` crate with `educe` ([#907]). + +[#907]: https://github.com/stackabletech/operator-rs/pull/907 + ## [0.82.0] - 2024-11-23 ### Fixed diff --git a/crates/stackable-operator/Cargo.toml b/crates/stackable-operator/Cargo.toml index a6844ef4b..9b3dec1e5 100644 --- a/crates/stackable-operator/Cargo.toml +++ b/crates/stackable-operator/Cargo.toml @@ -18,9 +18,9 @@ chrono.workspace = true clap.workspace = true const_format.workspace = true delegate.workspace = true -derivative.workspace = true dockerfile-parser.workspace = true either.workspace = true +educe.workspace = true futures.workspace = true indexmap.workspace = true json-patch.workspace = true diff --git a/crates/stackable-operator/src/commons/resources.rs b/crates/stackable-operator/src/commons/resources.rs index 101dd288e..fbaaf9f1e 100644 --- a/crates/stackable-operator/src/commons/resources.rs +++ b/crates/stackable-operator/src/commons/resources.rs @@ -76,7 +76,7 @@ use crate::{ cpu::CpuQuantity, memory::MemoryQuantity, }; -use derivative::Derivative; +use educe::Educe; use k8s_openapi::api::core::v1::{ Container, PersistentVolumeClaim, PersistentVolumeClaimSpec, PodSpec, ResourceRequirements, VolumeResourceRequirements, @@ -133,13 +133,8 @@ pub enum Error { path_overrides(fragment = "crate::config::fragment") )] #[fragment_attrs( - derive(Merge, Serialize, Deserialize, JsonSchema, Derivative), - derivative( - Default(bound = "T::Fragment: Default, K::Fragment: Default"), - Debug(bound = "T::Fragment: Debug, K::Fragment: Debug"), - Clone(bound = "T::Fragment: Clone, K::Fragment: Clone"), - PartialEq(bound = "T::Fragment: PartialEq, K::Fragment: PartialEq") - ), + derive(Merge, Serialize, Deserialize, JsonSchema, Educe), + educe(Clone, Debug, Default, PartialEq), merge( bound = "T::Fragment: Merge, K::Fragment: Merge", path_overrides(merge = "crate::config::merge") @@ -172,13 +167,8 @@ pub struct Resources { path_overrides(fragment = "crate::config::fragment") )] #[fragment_attrs( - derive(Merge, Serialize, Deserialize, JsonSchema, Derivative), - derivative( - Default(bound = "T::Fragment: Default"), - Debug(bound = "T::Fragment: Debug"), - Clone(bound = "T::Fragment: Clone"), - PartialEq(bound = "T::Fragment: PartialEq") - ), + derive(Merge, Serialize, Deserialize, JsonSchema, Educe), + educe(Clone, Debug, Default, PartialEq), merge( bound = "T::Fragment: Merge", path_overrides(merge = "crate::config::merge") diff --git a/crates/stackable-operator/src/crd.rs b/crates/stackable-operator/src/crd.rs index 666e84ef6..c3c607056 100644 --- a/crates/stackable-operator/src/crd.rs +++ b/crates/stackable-operator/src/crd.rs @@ -1,27 +1,24 @@ use std::marker::PhantomData; -use derivative::Derivative; +use educe::Educe; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; /// A reference to a product cluster (for example, a `ZookeeperCluster`) /// /// `namespace`'s defaulting only applies when retrieved via [`ClusterRef::namespace_relative_from`] -#[derive(Deserialize, Serialize, JsonSchema, Derivative)] -#[derivative( - Default(bound = ""), - Clone(bound = ""), - Debug(bound = ""), - PartialEq(bound = "") -)] +#[derive(Deserialize, Serialize, JsonSchema, Educe)] +#[educe(Clone(bound()), Debug(bound()), Default(bound()), PartialEq(bound()))] pub struct ClusterRef { /// The name of the cluster pub name: Option, + /// The namespace of the cluster /// /// This field is optional, and will default to the namespace of the referring object. #[serde(default)] pub namespace: Option, + #[serde(skip)] _kind: PhantomData, } diff --git a/crates/stackable-operator/src/product_logging/spec.rs b/crates/stackable-operator/src/product_logging/spec.rs index 062afa1d2..29a904a82 100644 --- a/crates/stackable-operator/src/product_logging/spec.rs +++ b/crates/stackable-operator/src/product_logging/spec.rs @@ -8,7 +8,7 @@ use crate::config::{ merge::Merge, }; -use derivative::Derivative; +use educe::Educe; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -46,21 +46,21 @@ use serde::{Deserialize, Serialize}; /// /// let logging = product_logging::spec::default_logging::(); /// ``` -#[derive(Clone, Debug, Derivative, Eq, Fragment, JsonSchema, PartialEq)] -#[derivative(Default(bound = ""))] +#[derive(Clone, Debug, Eq, Fragment, JsonSchema, PartialEq, Educe)] +#[educe(Default)] #[fragment(path_overrides(fragment = "crate::config::fragment"))] #[fragment_attrs( derive( Clone, Debug, - Derivative, Deserialize, JsonSchema, Merge, PartialEq, - Serialize + Serialize, + Educe, ), - derivative(Default(bound = "")), + educe(Default), merge(path_overrides(merge = "crate::config::merge")), serde( bound(serialize = "T: Serialize", deserialize = "T: Deserialize<'de>",), @@ -75,6 +75,7 @@ where { /// Wether or not to deploy a container with the Vector log agent. pub enable_vector_agent: bool, + /// Log configuration per container. #[fragment_attrs(serde(default))] pub containers: BTreeMap, @@ -119,25 +120,27 @@ pub struct ContainerLogConfig { /// Custom or automatic log configuration /// /// The custom log configuration takes precedence over the automatic one. -#[derive(Clone, Debug, Derivative, Eq, JsonSchema, PartialEq)] -#[derivative(Default)] +#[derive(Clone, Debug, Eq, JsonSchema, PartialEq, Educe)] +#[educe(Default)] pub enum ContainerLogConfigChoice { /// Custom log configuration provided in a ConfigMap Custom(CustomContainerLogConfig), + /// Automatic log configuration according to the given values - #[derivative(Default)] + #[educe(Default)] Automatic(AutomaticContainerLogConfig), } -#[derive(Clone, Debug, Derivative, Deserialize, JsonSchema, Merge, PartialEq, Serialize)] -#[derivative(Default)] +#[derive(Clone, Debug, Deserialize, JsonSchema, Merge, PartialEq, Serialize, Educe)] +#[educe(Default)] #[merge(path_overrides(merge = "crate::config::merge"))] #[serde(untagged)] pub enum ContainerLogConfigChoiceFragment { /// Custom log configuration provided in a ConfigMap Custom(CustomContainerLogConfigFragment), - #[derivative(Default)] + /// Automatic log configuration according to the given values + #[educe(Default)] Automatic(AutomaticContainerLogConfigFragment), } @@ -306,7 +309,7 @@ pub struct AppenderConfig { Clone, Copy, Debug, - Derivative, + Default, Deserialize, Eq, JsonSchema, @@ -316,11 +319,10 @@ pub struct AppenderConfig { Serialize, strum::Display, )] -#[derivative(Default)] pub enum LogLevel { TRACE, DEBUG, - #[derivative(Default)] + #[default] INFO, WARN, ERROR, diff --git a/crates/stackable-operator/src/role_utils.rs b/crates/stackable-operator/src/role_utils.rs index 35941ea66..04ecd2593 100644 --- a/crates/stackable-operator/src/role_utils.rs +++ b/crates/stackable-operator/src/role_utils.rs @@ -94,7 +94,7 @@ use crate::{ product_config_utils::Configuration, utils::crds::raw_object_schema, }; -use derivative::Derivative; +use educe::Educe; use k8s_openapi::api::core::v1::PodTemplateSpec; use kube::{runtime::reflector::ObjectRef, Resource}; use schemars::JsonSchema; @@ -274,11 +274,8 @@ impl RoleGroup { } /// A reference to a named role group of a given cluster object -#[derive(Derivative)] -#[derivative( - Debug(bound = "K::DynamicType: Debug"), - Clone(bound = "K::DynamicType: Clone") -)] +#[derive(Educe)] +#[educe(Clone, Debug)] pub struct RoleGroupRef { pub cluster: ObjectRef, pub role: String, diff --git a/crates/stackable-operator/src/time/duration.rs b/crates/stackable-operator/src/time/duration.rs index 16558511f..d7053bd73 100644 --- a/crates/stackable-operator/src/time/duration.rs +++ b/crates/stackable-operator/src/time/duration.rs @@ -1,8 +1,7 @@ //! This module contains a common [`Duration`] struct which is able to parse //! human-readable duration formats, like `5s`, `24h`, `2y2h20m42s` or`15d2m2s`. It -//! additionally implements many required traits, like [`Derivative`], -//! [`JsonSchema`], [`Deserialize`][serde::Deserialize], and -//! [`Serialize`][serde::Serialize]. +//! additionally implements many required traits, like [`JsonSchema`], +//! [`Deserialize`][serde::Deserialize], and [`Serialize`][serde::Serialize]. //! //! Furthermore, it implements [`Deref`], which enables us to use all associated //! functions of [`std::time::Duration`] without re-implementing the public @@ -20,7 +19,6 @@ use std::{ str::FromStr, }; -use derivative::Derivative; use schemars::JsonSchema; use snafu::{OptionExt, ResultExt, Snafu}; use strum::IntoEnumIterator; @@ -63,7 +61,7 @@ pub enum DurationParseError { /// A common [`Duration`] struct which is able to parse human-readable duration /// formats, like `5s`, `24h`, `2y2h20m42s` or`15d2m2s`. It additionally /// implements many required traits (for CRD deserialization and serialization). -#[derive(Clone, Copy, Debug, Derivative, Hash, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Clone, Copy, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)] pub struct Duration(std::time::Duration); impl FromStr for Duration { diff --git a/deny.toml b/deny.toml index ed90301c3..ba73fa966 100644 --- a/deny.toml +++ b/deny.toml @@ -1,3 +1,4 @@ +[graph] targets = [ { triple = "x86_64-unknown-linux-gnu" }, { triple = "aarch64-unknown-linux-gnu" }, @@ -7,49 +8,44 @@ targets = [ ] [advisories] -vulnerability = "warn" -unmaintained = "allow" -unsound = "warn" -yanked = "warn" -notice = "warn" +yanked = "deny" [bans] multiple-versions = "allow" -[[bans.deny]] -name = "time" -version = "0.1" - [licenses] -unlicensed = "deny" -copyleft = "deny" -allow-osi-fsf-free = "neither" -default = "deny" +unused-allowed-license = "allow" confidence-threshold = 1.0 allow = [ "Apache-2.0", + "BSD-2-Clause", "BSD-3-Clause", "CC0-1.0", "ISC", "LicenseRef-ring", "LicenseRef-webpki", "MIT", + "MPL-2.0", + "Unicode-3.0", "Unicode-DFS-2016", "Zlib", "Unlicense", - "OpenSSL", - "Unicode-3.0", ] +private = { ignore = true } [[licenses.clarify]] name = "ring" expression = "LicenseRef-ring" -license-files = [{ path = "LICENSE", hash = 0xbd0eed23 }] +license-files = [ + { path = "LICENSE", hash = 0xbd0eed23 }, +] [[licenses.clarify]] name = "webpki" expression = "LicenseRef-webpki" -license-files = [{ path = "LICENSE", hash = 0x001c7e6c }] +license-files = [ + { path = "LICENSE", hash = 0x001c7e6c }, +] [sources] unknown-registry = "deny"