20 use std::path::{Path, PathBuf}; |
20 use std::path::{Path, PathBuf}; |
21 use std::str; |
21 use std::str; |
22 |
22 |
23 use crate::errors::{HgResultExt, IoResultExt}; |
23 use crate::errors::{HgResultExt, IoResultExt}; |
24 |
24 |
|
25 #[derive(Clone)] |
|
26 pub struct PlainInfo { |
|
27 pub plain: bool, |
|
28 pub plainalias: bool, |
|
29 pub plainrevsetalias: bool, |
|
30 pub plaintemplatealias: bool, |
|
31 } |
|
32 |
25 /// Holds the config values for the current repository |
33 /// Holds the config values for the current repository |
26 /// TODO update this docstring once we support more sources |
34 /// TODO update this docstring once we support more sources |
27 #[derive(Clone)] |
35 #[derive(Clone)] |
28 pub struct Config { |
36 pub struct Config { |
29 layers: Vec<layer::ConfigLayer>, |
37 layers: Vec<layer::ConfigLayer>, |
|
38 plain: PlainInfo, |
30 } |
39 } |
31 |
40 |
32 impl DisplayBytes for Config { |
41 impl DisplayBytes for Config { |
33 fn display_bytes( |
42 fn display_bytes( |
34 &self, |
43 &self, |
81 String::from_utf8_lossy(&self.value) |
90 String::from_utf8_lossy(&self.value) |
82 ) |
91 ) |
83 } |
92 } |
84 } |
93 } |
85 |
94 |
|
95 fn should_ignore(plain: &PlainInfo, section: &[u8], item: &[u8]) -> bool { |
|
96 // duplication with [_applyconfig] in [ui.py], |
|
97 if !plain.plain { |
|
98 return false; |
|
99 } |
|
100 if section == b"alias" { |
|
101 return plain.plainalias; |
|
102 } |
|
103 if section == b"revsetalias" { |
|
104 return plain.plainrevsetalias; |
|
105 } |
|
106 if section == b"templatealias" { |
|
107 return plain.plaintemplatealias; |
|
108 } |
|
109 |
|
110 if section == b"ui" { |
|
111 let to_delete: &[&[u8]] = &[ |
|
112 b"debug", |
|
113 b"fallbackencoding", |
|
114 b"quiet", |
|
115 b"slash", |
|
116 b"logtemplate", |
|
117 b"message-output", |
|
118 b"statuscopies", |
|
119 b"style", |
|
120 b"traceback", |
|
121 b"verbose", |
|
122 ]; |
|
123 return to_delete.contains(&item); |
|
124 } |
|
125 let sections_to_delete: &[&[u8]] = |
|
126 &[b"defaults", b"commands", b"command-templates"]; |
|
127 return sections_to_delete.contains(§ion); |
|
128 } |
|
129 |
|
130 impl PlainInfo { |
|
131 pub fn empty() -> Self { |
|
132 Self { |
|
133 plain: false, |
|
134 plainalias: false, |
|
135 plainrevsetalias: false, |
|
136 plaintemplatealias: false, |
|
137 } |
|
138 } |
|
139 } |
86 impl Config { |
140 impl Config { |
87 /// The configuration to use when printing configuration-loading errors |
141 /// The configuration to use when printing configuration-loading errors |
88 pub fn empty() -> Self { |
142 pub fn empty() -> Self { |
89 Self { layers: Vec::new() } |
143 Self { |
|
144 layers: Vec::new(), |
|
145 plain: PlainInfo::empty(), |
|
146 } |
90 } |
147 } |
91 |
148 |
92 /// Load system and user configuration from various files. |
149 /// Load system and user configuration from various files. |
93 /// |
150 /// |
94 /// This is also affected by some environment variables. |
151 /// This is also affected by some environment variables. |
95 pub fn load_non_repo() -> Result<Self, ConfigError> { |
152 pub fn load_non_repo() -> Result<Self, ConfigError> { |
96 let mut config = Self { layers: Vec::new() }; |
153 let mut config = Self::empty(); |
97 let opt_rc_path = env::var_os("HGRCPATH"); |
154 let opt_rc_path = env::var_os("HGRCPATH"); |
98 // HGRCPATH replaces system config |
155 // HGRCPATH replaces system config |
99 if opt_rc_path.is_none() { |
156 if opt_rc_path.is_none() { |
100 config.add_system_config()? |
157 config.add_system_config()? |
101 } |
158 } |
281 .cloned() |
341 .cloned() |
282 .partition(ConfigLayer::is_from_command_line); |
342 .partition(ConfigLayer::is_from_command_line); |
283 |
343 |
284 let mut repo_config = Self { |
344 let mut repo_config = Self { |
285 layers: other_layers, |
345 layers: other_layers, |
|
346 plain: PlainInfo::empty(), |
286 }; |
347 }; |
287 for path in repo_config_files { |
348 for path in repo_config_files { |
288 // TODO: check if this file should be trusted: |
349 // TODO: check if this file should be trusted: |
289 // `mercurial/ui.py:427` |
350 // `mercurial/ui.py:427` |
290 repo_config.add_trusted_file(path)?; |
351 repo_config.add_trusted_file(path)?; |
291 } |
352 } |
292 repo_config.layers.extend(cli_layers); |
353 repo_config.layers.extend(cli_layers); |
293 Ok(repo_config) |
354 Ok(repo_config) |
|
355 } |
|
356 |
|
357 pub fn apply_plain(&mut self, plain: PlainInfo) { |
|
358 self.plain = plain; |
294 } |
359 } |
295 |
360 |
296 fn get_parse<'config, T: 'config>( |
361 fn get_parse<'config, T: 'config>( |
297 &'config self, |
362 &'config self, |
298 section: &[u8], |
363 section: &[u8], |
411 fn get_inner( |
476 fn get_inner( |
412 &self, |
477 &self, |
413 section: &[u8], |
478 section: &[u8], |
414 item: &[u8], |
479 item: &[u8], |
415 ) -> Option<(&ConfigLayer, &ConfigValue)> { |
480 ) -> Option<(&ConfigLayer, &ConfigValue)> { |
|
481 if should_ignore(&self.plain, §ion, &item) { |
|
482 return None; |
|
483 } |
416 for layer in self.layers.iter().rev() { |
484 for layer in self.layers.iter().rev() { |
417 if !layer.trusted { |
485 if !layer.trusted { |
418 continue; |
486 continue; |
419 } |
487 } |
420 if let Some(v) = layer.get(§ion, &item) { |
488 if let Some(v) = layer.get(§ion, &item) { |