gather_all_code_from_crates/
global_config.rs1crate::ix!();
2
3#[derive(Debug, Clone, Deserialize, Builder, Getters, Setters)]
4#[builder(setter(into))]
5#[getset(get = "pub", set = "pub")]
6pub struct GlobalConfig {
7 #[serde(default)]
8 #[builder(default)]
9 project_overrides: HashMap<String, AstFilterCriteria>,
10
11 #[serde(default)]
12 #[builder(default)]
13 default_include_tests: bool,
14
15 #[serde(default)]
16 #[builder(default)]
17 default_omit_bodies: bool,
18
19 #[serde(default)]
20 #[builder(default)]
21 extra_flags: u64,
22}
23
24impl GlobalConfig {
25 fn load_from_file(path: &PathBuf) -> AppResult<GlobalConfig> {
26 if !path.exists() {
27 return Ok(GlobalConfigBuilder::default().build().map_err(|_|AppError::Config{reason:ErrorReason::Config})?);
28 }
29 let file = File::open(path).map_err(|e|AppError::Io{code:e.kind()})?;
30 let mut reader = BufReader::new(file);
31 let mut content = String::new();
32 reader.read_to_string(&mut content).map_err(|e|AppError::Io{code:e.kind()})?;
33 let cfg: GlobalConfig = serde_json::from_str(&content).map_err(|_|
34 AppError::Config{reason:ErrorReason::Parse}
35 )?;
36 Ok(cfg)
37 }
38}
39
40pub fn load_global_config() -> AppResult<GlobalConfig> {
41 let home = std::env::var("HOME").map_err(|_|AppError::Config{reason:ErrorReason::MissingData})?;
42 let config_path = PathBuf::from(home).join(".gather-all-code-from-crates");
43 GlobalConfig::load_from_file(&config_path)
44}
45
46#[cfg(test)]
47mod global_config_tests {
48 use super::*;
49
50 #[test]
51 fn test_effective_config_from_cli_and_global() {
52 let global_cfg = GlobalConfigBuilder::default()
53 .default_include_tests(true)
54 .default_omit_bodies(false)
55 .build().unwrap();
56
57 let cli = CliBuilder::default()
58 .crates(vec![])
59 .include_tests(false)
60 .single_test_name(None)
61 .omit_private(true)
62 .omit_bodies(false)
63 .single_function_name(None)
64 .excluded_files(vec![])
65 .exclude_main_file(false)
66 .remove_doc_comments(false)
67 .build()
68 .unwrap();
69
70
71 let eff = EffectiveConfig::from_cli_and_global(&cli, &global_cfg).unwrap();
72 assert_eq!(*eff.criteria().include_tests(), true);
74 assert_eq!(*eff.criteria().omit_private(), true); assert_eq!(*eff.criteria().omit_bodies(), false); }
77
78 #[test]
79 fn test_global_config_load_defaults_if_missing() {
80 let path = PathBuf::from("non_existent_config_file.json");
81 let cfg = GlobalConfig::load_from_file(&path).unwrap();
82 assert_eq!(cfg.project_overrides().len(), 0);
83 assert_eq!(*cfg.default_include_tests(), false);
84 assert_eq!(*cfg.default_omit_bodies(), false);
85 }
86
87 #[test]
88 fn test_global_config_load_from_file() {
89 let tmp_dir = TempDir::new().unwrap();
90 let cfg_path = tmp_dir.path().join("config.json");
91 let content = r#"
92 {
93 "project_overrides": {
94 "mycrate": {
95 "include_tests": true,
96 "omit_private": true
97 }
98 },
99 "default_include_tests": true,
100 "default_omit_bodies": false,
101 "extra_flags": 42
102 }
103 "#;
104
105 {
106 let mut f = File::create(&cfg_path).unwrap();
107 f.write_all(content.as_bytes()).unwrap();
108 }
109
110 let cfg = GlobalConfig::load_from_file(&cfg_path).unwrap();
111 assert_eq!(cfg.project_overrides().len(), 1);
112 assert!(cfg.project_overrides().get("mycrate").unwrap().include_tests());
113 assert!(cfg.project_overrides().get("mycrate").unwrap().omit_private());
114 assert_eq!(*cfg.default_include_tests(), true);
115 assert_eq!(*cfg.default_omit_bodies(), false);
116 assert_eq!(*cfg.extra_flags(), 42);
117 }
118
119 #[test]
120 fn test_global_config_load_failure_on_invalid_json() {
121 let tmp_dir = TempDir::new().unwrap();
122 let cfg_path = tmp_dir.path().join("config.json");
123 {
124 let mut f = File::create(&cfg_path).unwrap();
125 f.write_all(b"{ invalid json }").unwrap();
126 }
127
128 let result = GlobalConfig::load_from_file(&cfg_path);
129 match result {
130 Err(AppError::Config { reason: ErrorReason::Parse }) => (),
131 _ => panic!("Expected parse error"),
132 }
133 }
134
135 #[test]
136 fn test_global_config_missing_home_env() {
137 let original_home = std::env::var_os("HOME");
139 std::env::remove_var("HOME");
140
141 let result = load_global_config();
142 match result {
143 Err(AppError::Config{reason:ErrorReason::MissingData}) => (),
144 _ => panic!("Expected MissingData error when HOME is unset"),
145 }
146
147 if let Some(h) = original_home {
149 std::env::set_var("HOME", h);
150 }
151 }
152}