Skip to main content

rok_cli/
config.rs

1use crate::error::RokError;
2use crate::schema::Options;
3use std::path::Path;
4
5#[derive(Debug)]
6pub struct Config {
7    pub options: Options,
8    pub cwd: std::path::PathBuf,
9    pub env: std::collections::HashMap<String, String>,
10}
11
12impl Config {
13    pub fn from_options(options: Options) -> Result<Self, RokError> {
14        let cwd_str = options.cwd.clone();
15        let cwd = Path::new(&cwd_str);
16
17        if !cwd.exists() {
18            return Err(RokError::startup(format!(
19                "Working directory does not exist: {}",
20                cwd_str
21            )));
22        }
23
24        if !cwd.is_dir() {
25            return Err(RokError::startup(format!(
26                "Working directory is not a directory: {}",
27                cwd_str
28            )));
29        }
30
31        let mut env = std::env::vars().collect::<std::collections::HashMap<_, _>>();
32        env.extend(options.env.clone());
33
34        Ok(Self {
35            options,
36            cwd: cwd.to_path_buf(),
37            env,
38        })
39    }
40}
41
42#[cfg(test)]
43mod tests {
44    use super::*;
45    use std::collections::HashMap;
46    use std::fs;
47    use tempfile::TempDir;
48
49    #[test]
50    fn test_config_from_options_valid() {
51        let temp_dir = TempDir::new().unwrap();
52        let options = Options {
53            cwd: temp_dir.path().to_string_lossy().to_string(),
54            stop_on_error: true,
55            timeout_ms: 30000,
56            env: HashMap::new(),
57            cache: false,
58            cache_dir: None,
59            incremental: false,
60        };
61
62        let config = Config::from_options(options);
63        assert!(config.is_ok());
64        let config = config.unwrap();
65        assert_eq!(config.cwd, temp_dir.path());
66    }
67
68    #[test]
69    fn test_config_from_options_nonexistent_dir() {
70        let options = Options {
71            cwd: "/nonexistent/path/that/does/not/exist".to_string(),
72            stop_on_error: true,
73            timeout_ms: 30000,
74            env: HashMap::new(),
75            cache: false,
76            cache_dir: None,
77            incremental: false,
78        };
79
80        let config = Config::from_options(options);
81        assert!(config.is_err());
82        let err = config.unwrap_err();
83        assert!(err.message.contains("Working directory does not exist"));
84    }
85
86    #[test]
87    fn test_config_from_options_file_not_dir() {
88        let temp_dir = TempDir::new().unwrap();
89        let file_path = temp_dir.path().join("test.txt");
90        fs::write(&file_path, "content").unwrap();
91
92        let options = Options {
93            cwd: file_path.to_string_lossy().to_string(),
94            stop_on_error: true,
95            timeout_ms: 30000,
96            env: HashMap::new(),
97            cache: false,
98            cache_dir: None,
99            incremental: false,
100        };
101
102        let config = Config::from_options(options);
103        assert!(config.is_err());
104        let err = config.unwrap_err();
105        assert!(err.message.contains("is not a directory"));
106    }
107
108    #[test]
109    fn test_config_merges_env_vars() {
110        let temp_dir = TempDir::new().unwrap();
111        let mut custom_env = HashMap::new();
112        custom_env.insert("CUSTOM_VAR".to_string(), "custom_value".to_string());
113
114        let options = Options {
115            cwd: temp_dir.path().to_string_lossy().to_string(),
116            stop_on_error: true,
117            timeout_ms: 30000,
118            env: custom_env,
119            cache: false,
120            cache_dir: None,
121            incremental: false,
122        };
123
124        let config = Config::from_options(options);
125        assert!(config.is_ok());
126        let config = config.unwrap();
127        assert_eq!(
128            config.env.get("CUSTOM_VAR"),
129            Some(&"custom_value".to_string())
130        );
131    }
132
133    #[test]
134    fn test_config_default_cwd() {
135        let options = Options::default();
136        assert_eq!(options.cwd, ".");
137    }
138}