Skip to main content

cvkg_cli/
config.rs

1//! Configuration file support for the CVKG CLI.
2//!
3//! Reads settings from `.cvkg.toml` (or paths specified by `CVKG_CONFIG` env var)
4//! and merges them with CLI flags (CLI > env > file).
5
6use serde::Deserialize;
7use std::path::PathBuf;
8use tracing::{info, warn};
9
10/// CLI configuration that can be set via config file, env vars, or CLI flags.
11#[derive(Debug, Default, Deserialize)]
12pub struct CliConfig {
13    /// Default target platform.
14    pub target: Option<String>,
15    /// Default dev server port.
16    pub port: Option<u16>,
17    /// Default asset directory.
18    pub assets_dir: Option<String>,
19    /// Default output directory for builds.
20    pub dist_dir: Option<String>,
21    /// Enable inspector by default.
22    pub inspector: Option<bool>,
23    /// Respect reduced-motion preference.
24    pub reduced_motion: Option<bool>,
25}
26
27impl CliConfig {
28    /// Load configuration from `.cvkg.toml` in the current directory,
29    /// or from the path specified by `CVKG_CONFIG` env var.
30    pub fn load() -> Self {
31        let config_path = std::env::var("CVKG_CONFIG")
32            .map(PathBuf::from)
33            .unwrap_or_else(|_| PathBuf::from(".cvkg.toml"));
34
35        if !config_path.exists() {
36            return Self::default();
37        }
38
39        match std::fs::read_to_string(&config_path) {
40            Ok(content) => match toml::from_str::<CliConfig>(&content) {
41                Ok(config) => {
42                    info!("Loaded config from {:?}", config_path);
43                    config
44                }
45                Err(e) => {
46                    warn!("Failed to parse {:?}: {}", config_path, e);
47                    Self::default()
48                }
49            },
50            Err(e) => {
51                warn!("Failed to read {:?}: {}", config_path, e);
52                Self::default()
53            }
54        }
55    }
56
57    /// Merge CLI flags into config. CLI flags take precedence over config file values.
58    pub fn merge_cli(
59        &mut self,
60        target: Option<String>,
61        port: Option<u16>,
62        inspector: bool,
63        reduced_motion: bool,
64    ) {
65        if target.is_some() {
66            self.target = target;
67        }
68        if port.is_some() {
69            self.port = port;
70        }
71        // Inspector and reduced_motion are boolean flags — CLI always overrides
72        self.inspector = Some(inspector);
73        self.reduced_motion = Some(reduced_motion);
74    }
75}