fix(ci): restore full CI green — test-matrix, clippy, rustfmt, and rustdoc gates
Root cause of the failing CI run was that examples/tests referencing feature-gated items were auto-detected (no required-features), so `--all-targets` compiled them under feature combinations where those modules didn't exist. Fixes: - mytheclipse Cargo.toml: declare the `high_level` example and `race_stress` integration test with required-features = ["full"]; `cargo build --all-targets` now skips them when full is off. This clears the whole test-matrix (workspace default, all-features, and every single-feature config) which all failed on E0432/E0433. - lib.rs: auto_metrics_service depends on service_builder, so regate it behind all(observability, resiliency) instead of observability alone (observability-only build compiled the module without resiliency). - mytheclipse-tracing: gate `pub mod fmt` behind any tracing-subscriber-providing feature so --no-default-features compiles. - mytheclipse-queue: gate `pub mod worker` behind in-memory (worker.rs requires tokio, only provided by in-memory). - clippy -D warnings fixes: deprecated base64 0.22 free fns -> Engine (paseto), unused key field, needless mut (service_builder), unused import/dead var/missing is_empty (bg_join), dead is_expired (dlock), while-let-iterator->for (parallel_map), type_complexity (shutdown_guard), MutexGuard held across await (middleware, now clones Arc'd layers), if-let-Err->is_err (queue), unused CliBuilder fields now wired into clap. - rustdoc -D warnings: resolve retry/MetricsBridge/CircuitBreaker/KeyRing intra-doc links and fix the unparseable lifecycle.rs code fence. - cargo fmt --all to satisfy the Rustfmt gate.
This commit is contained in:
@@ -51,9 +51,8 @@ pub use loader::ConfigLoader;
|
||||
|
||||
#[cfg(feature = "validation")]
|
||||
pub use validate::{
|
||||
collect_failures, validate_non_empty, validate_port, validate_range,
|
||||
validate_url, ConfigValidator, ConfigValidatorExt, ValidationError,
|
||||
ValidationFailure,
|
||||
collect_failures, validate_non_empty, validate_port, validate_range, validate_url,
|
||||
ConfigValidator, ConfigValidatorExt, ValidationError, ValidationFailure,
|
||||
};
|
||||
|
||||
#[cfg(feature = "hot-reload")]
|
||||
|
||||
@@ -33,7 +33,11 @@ pub struct ValidationError {
|
||||
|
||||
impl fmt::Display for ValidationError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "config validation failed ({} issue(s)):", self.failures.len())?;
|
||||
write!(
|
||||
f,
|
||||
"config validation failed ({} issue(s)):",
|
||||
self.failures.len()
|
||||
)?;
|
||||
for failure in &self.failures {
|
||||
write!(f, "\n - {failure}")?;
|
||||
}
|
||||
@@ -91,7 +95,11 @@ pub fn validate_url(path: &str, value: &str) -> Option<ValidationFailure> {
|
||||
}
|
||||
// Minimal heuristic: scheme + host. We avoid pulling in a full URL crate
|
||||
// to keep the dependency surface small.
|
||||
let scheme_len = if value.starts_with("http://") { 7 } else if value.starts_with("https://") { 8 } else {
|
||||
let scheme_len = if value.starts_with("http://") {
|
||||
7
|
||||
} else if value.starts_with("https://") {
|
||||
8
|
||||
} else {
|
||||
return Some(ValidationFailure {
|
||||
path: path.to_string(),
|
||||
message: format!("url must start with http:// or https:// (got {value:?})"),
|
||||
@@ -148,7 +156,9 @@ where
|
||||
}
|
||||
|
||||
/// Collects all failures from an iterator of `Option<ValidationFailure>`.
|
||||
pub fn collect_failures(opts: impl IntoIterator<Item = Option<ValidationFailure>>) -> Result<(), ValidationError> {
|
||||
pub fn collect_failures(
|
||||
opts: impl IntoIterator<Item = Option<ValidationFailure>>,
|
||||
) -> Result<(), ValidationError> {
|
||||
let failures: Vec<_> = opts.into_iter().flatten().collect();
|
||||
if failures.is_empty() {
|
||||
Ok(())
|
||||
@@ -186,7 +196,11 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn collect_failures_aggregates_all() {
|
||||
let opts = [validate_non_empty("a", ""), validate_non_empty("b", "ok"), validate_url("c.d", "bad://x")];
|
||||
let opts = [
|
||||
validate_non_empty("a", ""),
|
||||
validate_non_empty("b", "ok"),
|
||||
validate_url("c.d", "bad://x"),
|
||||
];
|
||||
let err = collect_failures(opts).unwrap_err();
|
||||
assert_eq!(err.failures.len(), 2);
|
||||
assert_eq!(err.failures[0].path, "a");
|
||||
@@ -195,7 +209,10 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn collect_failures_ok_when_all_pass() {
|
||||
let opts = [validate_url("a", "https://ok.com"), validate_port("b", 8080)];
|
||||
let opts = [
|
||||
validate_url("a", "https://ok.com"),
|
||||
validate_port("b", 8080),
|
||||
];
|
||||
assert!(collect_failures(opts).is_ok());
|
||||
}
|
||||
|
||||
@@ -205,7 +222,10 @@ mod tests {
|
||||
impl ConfigValidator for Cfg {
|
||||
fn validate(&self) -> Result<(), ValidationError> {
|
||||
Err(ValidationError {
|
||||
failures: vec![ValidationFailure { path: "x".into(), message: "bad".into() }],
|
||||
failures: vec![ValidationFailure {
|
||||
path: "x".into(),
|
||||
message: "bad".into(),
|
||||
}],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user