Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/config/layer.rs @ 50818:28c0fcff24e5 stable
rhg: fix the bug where sparse config is interpreted as relglob instead of glob
relglob apparently (in contrast with relpath) matches everywhere in the tree,
whereas glob only matches at the root.
The python version interprets these patterns as "glob" (see
"normalize(include, b'glob', ...)" in match.py)
author | Arseniy Alekseyev <aalekseyev@janestreet.com> |
---|---|
date | Thu, 10 Aug 2023 19:00:19 +0100 |
parents | e98fd81bb151 |
children | f8412da86d05 |
rev | line source |
---|---|
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
1 // layer.rs |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
2 // |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
3 // Copyright 2020 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
4 // Valentin Gatien-Baron, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
5 // Raphaël Gomès <rgomes@octobus.net> |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
6 // |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
7 // This software may be used and distributed according to the terms of the |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
8 // GNU General Public License version 2 or any later version. |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
9 |
46735
12d59eec7f1d
rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents:
46733
diff
changeset
|
10 use crate::errors::HgError; |
47407
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46743
diff
changeset
|
11 use crate::exit_codes::CONFIG_PARSE_ERROR_ABORT; |
46481
0d734c0ae1cf
rust: replace read_whole_file with std::fs::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46447
diff
changeset
|
12 use crate::utils::files::{get_bytes_from_path, get_path_from_bytes}; |
46731
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46727
diff
changeset
|
13 use format_bytes::{format_bytes, write_bytes, DisplayBytes}; |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
14 use lazy_static::lazy_static; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
15 use regex::bytes::Regex; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
16 use std::collections::HashMap; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
17 use std::path::{Path, PathBuf}; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
18 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
19 lazy_static! { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
20 static ref SECTION_RE: Regex = make_regex(r"^\[([^\[]+)\]"); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
21 static ref ITEM_RE: Regex = make_regex(r"^([^=\s][^=]*?)\s*=\s*((.*\S)?)"); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
22 /// Continuation whitespace |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
23 static ref CONT_RE: Regex = make_regex(r"^\s+(\S|\S.*\S)\s*$"); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
24 static ref EMPTY_RE: Regex = make_regex(r"^(;|#|\s*$)"); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
25 static ref COMMENT_RE: Regex = make_regex(r"^(;|#)"); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
26 /// A directive that allows for removing previous entries |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
27 static ref UNSET_RE: Regex = make_regex(r"^%unset\s+(\S+)"); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
28 /// A directive that allows for including other config files |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
29 static ref INCLUDE_RE: Regex = make_regex(r"^%include\s+(\S|\S.*\S)\s*$"); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
30 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
31 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
32 /// All config values separated by layers of precedence. |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
33 /// Each config source may be split in multiple layers if `%include` directives |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
34 /// are used. |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
35 /// TODO detail the general precedence |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
36 #[derive(Clone)] |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
37 pub struct ConfigLayer { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
38 /// Mapping of the sections to their items |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
39 sections: HashMap<Vec<u8>, ConfigItem>, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
40 /// All sections (and their items/values) in a layer share the same origin |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
41 pub origin: ConfigOrigin, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
42 /// Whether this layer comes from a trusted user or group |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
43 pub trusted: bool, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
44 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
45 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
46 impl ConfigLayer { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
47 pub fn new(origin: ConfigOrigin) -> Self { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
48 ConfigLayer { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
49 sections: HashMap::new(), |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
50 trusted: true, // TODO check |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
51 origin, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
52 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
53 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
54 |
46504
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
55 /// Parse `--config` CLI arguments and return a layer if there’s any |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
56 pub(crate) fn parse_cli_args( |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
57 cli_config_args: impl IntoIterator<Item = impl AsRef<[u8]>>, |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
58 ) -> Result<Option<Self>, ConfigError> { |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
59 fn parse_one(arg: &[u8]) -> Option<(Vec<u8>, Vec<u8>, Vec<u8>)> { |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
60 use crate::utils::SliceExt; |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
61 |
46505
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46504
diff
changeset
|
62 let (section_and_item, value) = arg.split_2(b'=')?; |
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46504
diff
changeset
|
63 let (section, item) = section_and_item.trim().split_2(b'.')?; |
46504
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
64 Some(( |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
65 section.to_owned(), |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
66 item.to_owned(), |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
67 value.trim().to_owned(), |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
68 )) |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
69 } |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
70 |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
71 let mut layer = Self::new(ConfigOrigin::CommandLine); |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
72 for arg in cli_config_args { |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
73 let arg = arg.as_ref(); |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
74 if let Some((section, item, value)) = parse_one(arg) { |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
75 layer.add(section, item, value, None); |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
76 } else { |
47407
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46743
diff
changeset
|
77 Err(HgError::abort( |
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46743
diff
changeset
|
78 format!( |
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46743
diff
changeset
|
79 "abort: malformed --config option: '{}' \ |
46504
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
80 (use --config section.name=value)", |
47407
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46743
diff
changeset
|
81 String::from_utf8_lossy(arg), |
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46743
diff
changeset
|
82 ), |
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46743
diff
changeset
|
83 CONFIG_PARSE_ERROR_ABORT, |
49488
9f14126cfc4c
rust: add support for hints in error messages
Rapha?l Gom?s <rgomes@octobus.net>
parents:
48733
diff
changeset
|
84 None, |
47407
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46743
diff
changeset
|
85 ))? |
46504
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
86 } |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
87 } |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
88 if layer.sections.is_empty() { |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
89 Ok(None) |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
90 } else { |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
91 Ok(Some(layer)) |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
92 } |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
93 } |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
94 |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
95 /// Returns whether this layer comes from `--config` CLI arguments |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
96 pub(crate) fn is_from_command_line(&self) -> bool { |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49514
diff
changeset
|
97 matches!(self.origin, ConfigOrigin::CommandLine) |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
98 } |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
99 |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
100 /// Add an entry to the config, overwriting the old one if already present. |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
101 pub fn add( |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
102 &mut self, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
103 section: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
104 item: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
105 value: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
106 line: Option<usize>, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
107 ) { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
108 self.sections |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
109 .entry(section) |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49514
diff
changeset
|
110 .or_insert_with(HashMap::new) |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
111 .insert(item, ConfigValue { bytes: value, line }); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
112 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
113 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
114 /// Returns the config value in `<section>.<item>` if it exists |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
115 pub fn get(&self, section: &[u8], item: &[u8]) -> Option<&ConfigValue> { |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49514
diff
changeset
|
116 self.sections.get(section)?.get(item) |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
117 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
118 |
46733
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46731
diff
changeset
|
119 /// Returns the keys defined in the given section |
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46731
diff
changeset
|
120 pub fn iter_keys(&self, section: &[u8]) -> impl Iterator<Item = &[u8]> { |
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46731
diff
changeset
|
121 self.sections |
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46731
diff
changeset
|
122 .get(section) |
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46731
diff
changeset
|
123 .into_iter() |
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46731
diff
changeset
|
124 .flat_map(|section| section.keys().map(|vec| &**vec)) |
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46731
diff
changeset
|
125 } |
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46731
diff
changeset
|
126 |
48451
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48339
diff
changeset
|
127 /// Returns the (key, value) pairs defined in the given section |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48339
diff
changeset
|
128 pub fn iter_section<'layer>( |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48339
diff
changeset
|
129 &'layer self, |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48339
diff
changeset
|
130 section: &[u8], |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48339
diff
changeset
|
131 ) -> impl Iterator<Item = (&'layer [u8], &'layer [u8])> { |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48339
diff
changeset
|
132 self.sections |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48339
diff
changeset
|
133 .get(section) |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48339
diff
changeset
|
134 .into_iter() |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48339
diff
changeset
|
135 .flat_map(|section| section.iter().map(|(k, v)| (&**k, &*v.bytes))) |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48339
diff
changeset
|
136 } |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48339
diff
changeset
|
137 |
48339
a2e278b5e265
rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
47407
diff
changeset
|
138 /// Returns whether any key is defined in the given section |
a2e278b5e265
rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
47407
diff
changeset
|
139 pub fn has_non_empty_section(&self, section: &[u8]) -> bool { |
a2e278b5e265
rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
47407
diff
changeset
|
140 self.sections |
a2e278b5e265
rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
47407
diff
changeset
|
141 .get(section) |
a2e278b5e265
rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
47407
diff
changeset
|
142 .map_or(false, |section| !section.is_empty()) |
a2e278b5e265
rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
47407
diff
changeset
|
143 } |
a2e278b5e265
rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
47407
diff
changeset
|
144 |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
145 pub fn is_empty(&self) -> bool { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
146 self.sections.is_empty() |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
147 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
148 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
149 /// Returns a `Vec` of layers in order of precedence (so, in read order), |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
150 /// recursively parsing the `%include` directives if any. |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
151 pub fn parse(src: &Path, data: &[u8]) -> Result<Vec<Self>, ConfigError> { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
152 let mut layers = vec![]; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
153 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
154 // Discard byte order mark if any |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
155 let data = if data.starts_with(b"\xef\xbb\xbf") { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
156 &data[3..] |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
157 } else { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
158 data |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
159 }; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
160 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
161 // TODO check if it's trusted |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
162 let mut current_layer = Self::new(ConfigOrigin::File(src.to_owned())); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
163 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
164 let mut lines_iter = |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
165 data.split(|b| *b == b'\n').enumerate().peekable(); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
166 let mut section = b"".to_vec(); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
167 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
168 while let Some((index, bytes)) = lines_iter.next() { |
46735
12d59eec7f1d
rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents:
46733
diff
changeset
|
169 let line = Some(index + 1); |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49514
diff
changeset
|
170 if let Some(m) = INCLUDE_RE.captures(bytes) { |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
171 let filename_bytes = &m[1]; |
46742
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46735
diff
changeset
|
172 let filename_bytes = crate::utils::expand_vars(filename_bytes); |
46482
39128182f04e
rust: Remove unnecessary check for absolute path before joining
Simon Sapin <simon.sapin@octobus.net>
parents:
46481
diff
changeset
|
173 // `Path::parent` only fails for the root directory, |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
174 // which `src` can’t be since we’ve managed to open it as a |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
175 // file. |
46482
39128182f04e
rust: Remove unnecessary check for absolute path before joining
Simon Sapin <simon.sapin@octobus.net>
parents:
46481
diff
changeset
|
176 let dir = src |
39128182f04e
rust: Remove unnecessary check for absolute path before joining
Simon Sapin <simon.sapin@octobus.net>
parents:
46481
diff
changeset
|
177 .parent() |
39128182f04e
rust: Remove unnecessary check for absolute path before joining
Simon Sapin <simon.sapin@octobus.net>
parents:
46481
diff
changeset
|
178 .expect("Path::parent fail on a file we’ve read"); |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
179 // `Path::join` with an absolute argument correctly ignores the |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
180 // base path |
46482
39128182f04e
rust: Remove unnecessary check for absolute path before joining
Simon Sapin <simon.sapin@octobus.net>
parents:
46481
diff
changeset
|
181 let filename = dir.join(&get_path_from_bytes(&filename_bytes)); |
46743
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
182 match std::fs::read(&filename) { |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
183 Ok(data) => { |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
184 layers.push(current_layer); |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
185 layers.extend(Self::parse(&filename, &data)?); |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
186 current_layer = |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
187 Self::new(ConfigOrigin::File(src.to_owned())); |
46735
12d59eec7f1d
rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents:
46733
diff
changeset
|
188 } |
46743
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
189 Err(error) => { |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
190 if error.kind() != std::io::ErrorKind::NotFound { |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
191 return Err(ConfigParseError { |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
192 origin: ConfigOrigin::File(src.to_owned()), |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
193 line, |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
194 message: format_bytes!( |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
195 b"cannot include {} ({})", |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
196 filename_bytes, |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
197 format_bytes::Utf8(error) |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
198 ), |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
199 } |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
200 .into()); |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
201 } |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
202 } |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
203 } |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49514
diff
changeset
|
204 } else if EMPTY_RE.captures(bytes).is_some() { |
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49514
diff
changeset
|
205 } else if let Some(m) = SECTION_RE.captures(bytes) { |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
206 section = m[1].to_vec(); |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49514
diff
changeset
|
207 } else if let Some(m) = ITEM_RE.captures(bytes) { |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
208 let item = m[1].to_vec(); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
209 let mut value = m[2].to_vec(); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
210 loop { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
211 match lines_iter.peek() { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
212 None => break, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
213 Some((_, v)) => { |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49514
diff
changeset
|
214 if COMMENT_RE.captures(v).is_some() { |
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49514
diff
changeset
|
215 } else if CONT_RE.captures(v).is_some() { |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
216 value.extend(b"\n"); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
217 value.extend(&m[1]); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
218 } else { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
219 break; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
220 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
221 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
222 }; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
223 lines_iter.next(); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
224 } |
46735
12d59eec7f1d
rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents:
46733
diff
changeset
|
225 current_layer.add(section.clone(), item, value, line); |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49514
diff
changeset
|
226 } else if let Some(m) = UNSET_RE.captures(bytes) { |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
227 if let Some(map) = current_layer.sections.get_mut(§ion) { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
228 map.remove(&m[1]); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
229 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
230 } else { |
46731
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46727
diff
changeset
|
231 let message = if bytes.starts_with(b" ") { |
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46727
diff
changeset
|
232 format_bytes!(b"unexpected leading whitespace: {}", bytes) |
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46727
diff
changeset
|
233 } else { |
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46727
diff
changeset
|
234 bytes.to_owned() |
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46727
diff
changeset
|
235 }; |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
236 return Err(ConfigParseError { |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
237 origin: ConfigOrigin::File(src.to_owned()), |
46735
12d59eec7f1d
rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents:
46733
diff
changeset
|
238 line, |
46731
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46727
diff
changeset
|
239 message, |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
240 } |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
241 .into()); |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
242 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
243 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
244 if !current_layer.is_empty() { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
245 layers.push(current_layer); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
246 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
247 Ok(layers) |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
248 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
249 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
250 |
46499
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
251 impl DisplayBytes for ConfigLayer { |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
252 fn display_bytes( |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
253 &self, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
254 out: &mut dyn std::io::Write, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
255 ) -> std::io::Result<()> { |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
256 let mut sections: Vec<_> = self.sections.iter().collect(); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
257 sections.sort_by(|e0, e1| e0.0.cmp(e1.0)); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
258 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
259 for (section, items) in sections.into_iter() { |
49930
e98fd81bb151
rust-clippy: fix most warnings in `hg-core`
Rapha?l Gom?s <rgomes@octobus.net>
parents:
49514
diff
changeset
|
260 let mut items: Vec<_> = items.iter().collect(); |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
261 items.sort_by(|e0, e1| e0.0.cmp(e1.0)); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
262 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
263 for (item, config_entry) in items { |
46499
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
264 write_bytes!( |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
265 out, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
266 b"{}.{}={} # {}\n", |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
267 section, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
268 item, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
269 &config_entry.bytes, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
270 &self.origin, |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
271 )? |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
272 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
273 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
274 Ok(()) |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
275 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
276 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
277 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
278 /// Mapping of section item to value. |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
279 /// In the following: |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
280 /// ```text |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
281 /// [ui] |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
282 /// paginate=no |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
283 /// ``` |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
284 /// "paginate" is the section item and "no" the value. |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
285 pub type ConfigItem = HashMap<Vec<u8>, ConfigValue>; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
286 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
287 #[derive(Clone, Debug, PartialEq)] |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
288 pub struct ConfigValue { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
289 /// The raw bytes of the value (be it from the CLI, env or from a file) |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
290 pub bytes: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
291 /// Only present if the value comes from a file, 1-indexed. |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
292 pub line: Option<usize>, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
293 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
294 |
48733
39c447e03dbc
rhg: Add support for colored output
Simon Sapin <simon.sapin@octobus.net>
parents:
48732
diff
changeset
|
295 #[derive(Clone, Debug, PartialEq, Eq)] |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
296 pub enum ConfigOrigin { |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
297 /// From a configuration file |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
298 File(PathBuf), |
49514
e37416d432e9
rhg: support tweakdefaults
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49488
diff
changeset
|
299 /// From [ui.tweakdefaults] |
e37416d432e9
rhg: support tweakdefaults
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49488
diff
changeset
|
300 Tweakdefaults, |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
301 /// From a `--config` CLI argument |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
302 CommandLine, |
48732
d4a5c2197208
rhg: Add parsing for the --color global CLI argument
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
303 /// From a `--color` CLI argument |
d4a5c2197208
rhg: Add parsing for the --color global CLI argument
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
304 CommandLineColor, |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
305 /// From environment variables like `$PAGER` or `$EDITOR` |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
306 Environment(Vec<u8>), |
48732
d4a5c2197208
rhg: Add parsing for the --color global CLI argument
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
307 /* TODO defaults (configitems.py) |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
308 * TODO extensions |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
309 * TODO Python resources? |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
310 * Others? */ |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
311 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
312 |
46499
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
313 impl DisplayBytes for ConfigOrigin { |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
314 fn display_bytes( |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
315 &self, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
316 out: &mut dyn std::io::Write, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
317 ) -> std::io::Result<()> { |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
318 match self { |
46499
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
319 ConfigOrigin::File(p) => out.write_all(&get_bytes_from_path(p)), |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
320 ConfigOrigin::CommandLine => out.write_all(b"--config"), |
48732
d4a5c2197208
rhg: Add parsing for the --color global CLI argument
Simon Sapin <simon.sapin@octobus.net>
parents:
48451
diff
changeset
|
321 ConfigOrigin::CommandLineColor => out.write_all(b"--color"), |
46499
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
322 ConfigOrigin::Environment(e) => write_bytes!(out, b"${}", e), |
49514
e37416d432e9
rhg: support tweakdefaults
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49488
diff
changeset
|
323 ConfigOrigin::Tweakdefaults => { |
e37416d432e9
rhg: support tweakdefaults
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49488
diff
changeset
|
324 write_bytes!(out, b"ui.tweakdefaults") |
e37416d432e9
rhg: support tweakdefaults
Arseniy Alekseyev <aalekseyev@janestreet.com>
parents:
49488
diff
changeset
|
325 } |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
326 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
327 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
328 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
329 |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
330 #[derive(Debug)] |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
331 pub struct ConfigParseError { |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
332 pub origin: ConfigOrigin, |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
333 pub line: Option<usize>, |
46731
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46727
diff
changeset
|
334 pub message: Vec<u8>, |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
335 } |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
336 |
46435
2e2033081274
rust: replace trivial `impl From ?` with `#[derive(derive_more::From)]`
Simon Sapin <simon.sapin@octobus.net>
parents:
46187
diff
changeset
|
337 #[derive(Debug, derive_more::From)] |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
338 pub enum ConfigError { |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
339 Parse(ConfigParseError), |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
340 Other(HgError), |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
341 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
342 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
343 fn make_regex(pattern: &'static str) -> Regex { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
344 Regex::new(pattern).expect("expected a valid regex") |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
345 } |