|
1 | 1 | mod helpers; |
2 | 2 | mod settings; |
3 | 3 | mod watched_file; |
| 4 | +use crate::helpers::expand_tilde; |
4 | 5 | use crate::settings::ConfigSettings; |
5 | 6 | use crate::watched_file::WatchedFile; |
6 | 7 | use log::debug; |
@@ -72,24 +73,40 @@ impl Default for CodebookConfigFile { |
72 | 73 | impl CodebookConfigFile { |
73 | 74 | /// Load configuration by searching for both global and project-specific configs |
74 | 75 | pub fn load(current_dir: Option<&Path>) -> Result<Self, io::Error> { |
| 76 | + Self::load_with_global_config(current_dir, None) |
| 77 | + } |
| 78 | + |
| 79 | + /// Load configuration with an explicit global config override. |
| 80 | + pub fn load_with_global_config( |
| 81 | + current_dir: Option<&Path>, |
| 82 | + global_config_path: Option<PathBuf>, |
| 83 | + ) -> Result<Self, io::Error> { |
75 | 84 | debug!("Initializing CodebookConfig"); |
76 | 85 |
|
77 | 86 | if let Some(current_dir) = current_dir { |
78 | 87 | let current_dir = Path::new(current_dir); |
79 | | - Self::load_configs(current_dir) |
| 88 | + Self::load_configs(current_dir, global_config_path) |
80 | 89 | } else { |
81 | 90 | let current_dir = env::current_dir()?; |
82 | | - Self::load_configs(¤t_dir) |
| 91 | + Self::load_configs(¤t_dir, global_config_path) |
83 | 92 | } |
84 | 93 | } |
85 | 94 |
|
86 | 95 | /// Load both global and project configuration |
87 | | - fn load_configs(start_dir: &Path) -> Result<Self, io::Error> { |
| 96 | + fn load_configs( |
| 97 | + start_dir: &Path, |
| 98 | + global_config_override: Option<PathBuf>, |
| 99 | + ) -> Result<Self, io::Error> { |
88 | 100 | let config = Self::default(); |
89 | 101 | let mut inner = config.inner.write().unwrap(); |
90 | 102 |
|
91 | 103 | // First, try to load global config |
92 | | - if let Some(global_path) = Self::find_global_config_path() { |
| 104 | + let global_config_path = match global_config_override { |
| 105 | + Some(path) => Some(path.to_path_buf()), |
| 106 | + None => Self::find_global_config_path(), |
| 107 | + }; |
| 108 | + |
| 109 | + if let Some(global_path) = global_config_path { |
93 | 110 | let global_config = WatchedFile::new(Some(global_path.clone())); |
94 | 111 |
|
95 | 112 | if global_path.exists() { |
@@ -321,6 +338,10 @@ impl CodebookConfigFile { |
321 | 338 | None => return Ok(()), |
322 | 339 | }; |
323 | 340 |
|
| 341 | + #[cfg(not(windows))] |
| 342 | + let global_config_path = expand_tilde(global_config_path) |
| 343 | + .expect("Failed to expand tilde in: {global_config_path}"); |
| 344 | + |
324 | 345 | let settings = match inner.global_config.content() { |
325 | 346 | Some(settings) => settings, |
326 | 347 | None => return Ok(()), |
@@ -806,14 +827,40 @@ mod tests { |
806 | 827 | "# |
807 | 828 | )?; |
808 | 829 |
|
809 | | - let config = CodebookConfigFile::load_configs(&sub_sub_dir)?; |
| 830 | + let config = CodebookConfigFile::load_configs(&sub_sub_dir, None)?; |
810 | 831 | assert!(config.snapshot().words.contains(&"testword".to_string())); |
811 | 832 |
|
812 | 833 | // Check that the config file path is stored |
813 | 834 | assert_eq!(config.project_config_path(), Some(config_path)); |
814 | 835 | Ok(()) |
815 | 836 | } |
816 | 837 |
|
| 838 | + #[test] |
| 839 | + fn test_global_config_override_is_used() -> Result<(), io::Error> { |
| 840 | + let temp_dir = TempDir::new().unwrap(); |
| 841 | + let workspace_dir = temp_dir.path().join("workspace"); |
| 842 | + fs::create_dir_all(&workspace_dir)?; |
| 843 | + let custom_global_dir = temp_dir.path().join("global"); |
| 844 | + fs::create_dir_all(&custom_global_dir)?; |
| 845 | + let override_path = custom_global_dir.join("codebook.toml"); |
| 846 | + |
| 847 | + fs::write( |
| 848 | + &override_path, |
| 849 | + r#" |
| 850 | + words = ["customword"] |
| 851 | + "#, |
| 852 | + )?; |
| 853 | + |
| 854 | + let config = CodebookConfigFile::load_with_global_config( |
| 855 | + Some(workspace_dir.as_path()), |
| 856 | + Some(override_path.clone()), |
| 857 | + )?; |
| 858 | + |
| 859 | + assert_eq!(config.global_config_path(), Some(override_path)); |
| 860 | + assert!(config.is_allowed_word("customword")); |
| 861 | + Ok(()) |
| 862 | + } |
| 863 | + |
817 | 864 | #[test] |
818 | 865 | fn test_should_ignore_path() { |
819 | 866 | let config = CodebookConfigFile::default(); |
|
0 commit comments