Show More
@@ -65,9 +65,9 b' impl Config {' | |||
|
65 | 65 | /// Load system and user configuration from various files. |
|
66 | 66 | /// |
|
67 | 67 | /// This is also affected by some environment variables. |
|
68 | /// | |
|
69 | /// TODO: add a parameter for `--config` CLI arguments | |
|
70 |
|
|
|
68 | pub fn load( | |
|
69 | cli_config_args: impl IntoIterator<Item = impl AsRef<[u8]>>, | |
|
70 | ) -> Result<Self, ConfigError> { | |
|
71 | 71 | let mut config = Self { layers: Vec::new() }; |
|
72 | 72 | let opt_rc_path = env::var_os("HGRCPATH"); |
|
73 | 73 | // HGRCPATH replaces system config |
@@ -92,6 +92,9 b' impl Config {' | |||
|
92 | 92 | } |
|
93 | 93 | } |
|
94 | 94 | } |
|
95 | if let Some(layer) = ConfigLayer::parse_cli_args(cli_config_args)? { | |
|
96 | config.layers.push(layer) | |
|
97 | } | |
|
95 | 98 | Ok(config) |
|
96 | 99 | } |
|
97 | 100 |
@@ -51,6 +51,49 b' impl ConfigLayer {' | |||
|
51 | 51 | } |
|
52 | 52 | } |
|
53 | 53 | |
|
54 | /// Parse `--config` CLI arguments and return a layer if thereβs any | |
|
55 | pub(crate) fn parse_cli_args( | |
|
56 | cli_config_args: impl IntoIterator<Item = impl AsRef<[u8]>>, | |
|
57 | ) -> Result<Option<Self>, ConfigError> { | |
|
58 | fn parse_one(arg: &[u8]) -> Option<(Vec<u8>, Vec<u8>, Vec<u8>)> { | |
|
59 | use crate::utils::SliceExt; | |
|
60 | ||
|
61 | let (section_and_item, value) = split_2(arg, b'=')?; | |
|
62 | let (section, item) = split_2(section_and_item.trim(), b'.')?; | |
|
63 | Some(( | |
|
64 | section.to_owned(), | |
|
65 | item.to_owned(), | |
|
66 | value.trim().to_owned(), | |
|
67 | )) | |
|
68 | } | |
|
69 | ||
|
70 | fn split_2(bytes: &[u8], separator: u8) -> Option<(&[u8], &[u8])> { | |
|
71 | let mut iter = bytes.splitn(2, |&byte| byte == separator); | |
|
72 | let a = iter.next()?; | |
|
73 | let b = iter.next()?; | |
|
74 | Some((a, b)) | |
|
75 | } | |
|
76 | ||
|
77 | let mut layer = Self::new(ConfigOrigin::CommandLine); | |
|
78 | for arg in cli_config_args { | |
|
79 | let arg = arg.as_ref(); | |
|
80 | if let Some((section, item, value)) = parse_one(arg) { | |
|
81 | layer.add(section, item, value, None); | |
|
82 | } else { | |
|
83 | Err(HgError::abort(format!( | |
|
84 | "malformed --config option: \"{}\" \ | |
|
85 | (use --config section.name=value)", | |
|
86 | String::from_utf8_lossy(arg), | |
|
87 | )))? | |
|
88 | } | |
|
89 | } | |
|
90 | if layer.sections.is_empty() { | |
|
91 | Ok(None) | |
|
92 | } else { | |
|
93 | Ok(Some(layer)) | |
|
94 | } | |
|
95 | } | |
|
96 | ||
|
54 | 97 | /// Returns whether this layer comes from `--config` CLI arguments |
|
55 | 98 | pub(crate) fn is_from_command_line(&self) -> bool { |
|
56 | 99 | if let ConfigOrigin::CommandLine = self.origin { |
@@ -20,6 +20,17 b" fn add_global_args<'a, 'b>(app: App<'a, " | |||
|
20 | 20 | .value_name("REPO") |
|
21 | 21 | .takes_value(true), |
|
22 | 22 | ) |
|
23 | .arg( | |
|
24 | Arg::with_name("config") | |
|
25 | .help("set/override config option (use 'section.name=value')") | |
|
26 | .long("--config") | |
|
27 | .value_name("CONFIG") | |
|
28 | .takes_value(true) | |
|
29 | // Ok: `--config section.key1=val --config section.key2=val2` | |
|
30 | .multiple(true) | |
|
31 | // Not ok: `--config section.key1=val section.key2=val2` | |
|
32 | .number_of_values(1), | |
|
33 | ) | |
|
23 | 34 | } |
|
24 | 35 | |
|
25 | 36 | fn main() { |
@@ -47,12 +58,22 b' fn main() {' | |||
|
47 | 58 | |
|
48 | 59 | // Global arguments can be in either based on e.g. `hg -R ./foo log` v.s. |
|
49 | 60 | // `hg log -R ./foo` |
|
50 | let global_arg = | |
|
61 | let value_of_global_arg = | |
|
51 | 62 | |name| args.value_of_os(name).or_else(|| matches.value_of_os(name)); |
|
63 | // For arguments where multiple occurences are allowed, return a | |
|
64 | // possibly-iterator of all values. | |
|
65 | let values_of_global_arg = |name: &str| { | |
|
66 | let a = matches.values_of_os(name).into_iter().flatten(); | |
|
67 | let b = args.values_of_os(name).into_iter().flatten(); | |
|
68 | a.chain(b) | |
|
69 | }; | |
|
52 | 70 | |
|
53 | let repo_path = global_arg("repository").map(Path::new); | |
|
71 | let repo_path = value_of_global_arg("repository").map(Path::new); | |
|
54 | 72 | let result = (|| -> Result<(), CommandError> { |
|
55 | let config = hg::config::Config::load()?; | |
|
73 | let config_args = values_of_global_arg("config") | |
|
74 | // `get_bytes_from_path` works for OsStr the same as for Path | |
|
75 | .map(hg::utils::files::get_bytes_from_path); | |
|
76 | let config = hg::config::Config::load(config_args)?; | |
|
56 | 77 | run(&ui, &config, repo_path, args) |
|
57 | 78 | })(); |
|
58 | 79 |
General Comments 0
You need to be logged in to leave comments.
Login now