Skip to main content

helm_schema_cli/cli/
crd_args.rs

1use std::path::PathBuf;
2
3use clap::{Args, ValueEnum};
4
5/// Policy for resolving CRD versions missing from the configured catalog.
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, ValueEnum)]
7pub enum CrdVersionLookup {
8    /// Consult only the exact group, kind, and version.
9    #[default]
10    Strict,
11    /// Scan other versions and emit informational alternatives.
12    Loose,
13}
14
15/// CRD catalog, override, cache, and version-resolution options.
16#[derive(Args, Debug, Clone)]
17pub struct CrdArgs {
18    /// CRD version lookup mode. Default `strict`: only the exact
19    /// `(group, kind, version)` is consulted. `loose` enables cross-scan
20    /// + informational hints; mirrors are available in BOTH modes.
21    #[arg(long = "crd-version-lookup", value_enum, default_value_t = CrdVersionLookup::Strict)]
22    pub crd_version_lookup: CrdVersionLookup,
23
24    /// Short alias for `--crd-version-lookup=strict`. Kept for
25    /// symmetry with `--strict-k8s-version` / `--strict-api-versions`
26    /// and to keep CI opt-out flags short.
27    #[arg(long = "strict-crd-version")]
28    pub strict_crd_version: bool,
29
30    /// Additional upstream CRD catalog mirror URL. Repeatable.
31    /// Per-source cache namespacing keeps mirror entries from masking
32    /// the default.
33    #[arg(long = "crd-catalog-mirror")]
34    pub crd_catalog_mirror: Vec<String>,
35
36    /// Managed cache root for CRD schemas. Subject to the cache
37    /// invalidation contract.
38    #[arg(long = "crd-catalog-cache-dir")]
39    pub crd_catalog_cache_dir: Option<PathBuf>,
40
41    /// Hand-maintained CRD schema overrides. Never wiped, never
42    /// subject to the cache invalidation contract.
43    #[arg(long = "crd-override-dir")]
44    pub crd_override_dir: Option<PathBuf>,
45
46    /// Write a `<schema>.json.meta` sidecar alongside every CRD cache
47    /// entry recording the fetch URL and timestamp.
48    #[arg(long = "crd-cache-record-source")]
49    pub crd_cache_record_source: bool,
50
51    /// Removed in this alpha — use `--crd-override-dir` and/or
52    /// `--crd-catalog-cache-dir` instead.
53    #[arg(long = "crd-catalog-dir", hide = true)]
54    pub crd_catalog_dir_removed: Option<PathBuf>,
55}
56
57impl CrdArgs {
58    /// Resolved version-lookup mode after considering the alias flag.
59    #[must_use]
60    pub fn lookup_mode(&self) -> CrdVersionLookup {
61        if self.strict_crd_version {
62            CrdVersionLookup::Strict
63        } else {
64            self.crd_version_lookup
65        }
66    }
67
68    /// Validate CRD-related flags. Returns a user-facing error string
69    /// on invalid combinations.
70    ///
71    /// # Errors
72    ///
73    /// Returns an error for removed flags or overlapping managed and
74    /// hand-maintained cache directories.
75    pub fn validate(&self) -> Result<(), String> {
76        if self.crd_catalog_dir_removed.is_some() {
77            return Err(
78                "--crd-catalog-dir is removed; use --crd-override-dir (hand-maintained schemas, never wiped) and/or --crd-catalog-cache-dir (managed cache root)".to_string(),
79            );
80        }
81        if let (Some(o), Some(c)) = (&self.crd_override_dir, &self.crd_catalog_cache_dir)
82            && o == c
83        {
84            return Err(
85                "--crd-override-dir and --crd-catalog-cache-dir must point at different paths (override is hand-maintained, cache is wipe-eligible)".to_string(),
86            );
87        }
88        Ok(())
89    }
90}