author | Simon Sapin <simon.sapin@octobus.net> |
Fri, 10 Dec 2021 14:27:00 +0100 | |
changeset 48490 | 4a983b69e519 |
parent 48388 | a2e278b5e265 |
child 48742 | d4a5c2197208 |
permissions | -rw-r--r-- |
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 |
|
46748
12d59eec7f1d
rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents:
46746
diff
changeset
|
10 |
use crate::errors::HgError; |
47413
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46756
diff
changeset
|
11 |
use crate::exit_codes::CONFIG_PARSE_ERROR_ABORT; |
46540
0d734c0ae1cf
rust: replace read_whole_file with std::fs::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46515
diff
changeset
|
12 |
use crate::utils::files::{get_bytes_from_path, get_path_from_bytes}; |
46744
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
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 |
|
46556
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
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:
46551
diff
changeset
|
56 |
pub(crate) fn parse_cli_args( |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
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:
46551
diff
changeset
|
58 |
) -> Result<Option<Self>, ConfigError> { |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
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:
46551
diff
changeset
|
60 |
use crate::utils::SliceExt; |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
61 |
|
46557
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46556
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:
46556
diff
changeset
|
63 |
let (section, item) = section_and_item.trim().split_2(b'.')?; |
46556
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
64 |
Some(( |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
65 |
section.to_owned(), |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
66 |
item.to_owned(), |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
67 |
value.trim().to_owned(), |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
68 |
)) |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
69 |
} |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
70 |
|
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
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:
46551
diff
changeset
|
72 |
for arg in cli_config_args { |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
73 |
let arg = arg.as_ref(); |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
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:
46551
diff
changeset
|
75 |
layer.add(section, item, value, None); |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
76 |
} else { |
47413
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46756
diff
changeset
|
77 |
Err(HgError::abort( |
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46756
diff
changeset
|
78 |
format!( |
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46756
diff
changeset
|
79 |
"abort: malformed --config option: '{}' \ |
46556
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
80 |
(use --config section.name=value)", |
47413
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46756
diff
changeset
|
81 |
String::from_utf8_lossy(arg), |
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46756
diff
changeset
|
82 |
), |
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46756
diff
changeset
|
83 |
CONFIG_PARSE_ERROR_ABORT, |
6e49769b7f97
rhg: add exit code to HgError::Abort()
Pulkit Goyal <7895pulkit@gmail.com>
parents:
46756
diff
changeset
|
84 |
))? |
46556
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
85 |
} |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
86 |
} |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
87 |
if layer.sections.is_empty() { |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
88 |
Ok(None) |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
89 |
} else { |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
90 |
Ok(Some(layer)) |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
91 |
} |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
92 |
} |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46551
diff
changeset
|
93 |
|
46545
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
94 |
/// Returns whether this layer comes from `--config` CLI arguments |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
95 |
pub(crate) fn is_from_command_line(&self) -> bool { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
96 |
if let ConfigOrigin::CommandLine = self.origin { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
97 |
true |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
98 |
} else { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
99 |
false |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
100 |
} |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
101 |
} |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
102 |
|
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
103 |
/// 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
|
104 |
pub fn add( |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
105 |
&mut self, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
106 |
section: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
107 |
item: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
108 |
value: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
109 |
line: Option<usize>, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
110 |
) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
111 |
self.sections |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
112 |
.entry(section) |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
113 |
.or_insert_with(|| HashMap::new()) |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
114 |
.insert(item, ConfigValue { bytes: value, line }); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
115 |
} |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
116 |
|
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
117 |
/// 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
|
118 |
pub fn get(&self, section: &[u8], item: &[u8]) -> Option<&ConfigValue> { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
119 |
Some(self.sections.get(section)?.get(item)?) |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
120 |
} |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
121 |
|
46746
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46744
diff
changeset
|
122 |
/// 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:
46744
diff
changeset
|
123 |
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:
46744
diff
changeset
|
124 |
self.sections |
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46744
diff
changeset
|
125 |
.get(section) |
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46744
diff
changeset
|
126 |
.into_iter() |
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46744
diff
changeset
|
127 |
.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:
46744
diff
changeset
|
128 |
} |
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46744
diff
changeset
|
129 |
|
48490
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48388
diff
changeset
|
130 |
/// 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:
48388
diff
changeset
|
131 |
pub fn iter_section<'layer>( |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48388
diff
changeset
|
132 |
&'layer self, |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48388
diff
changeset
|
133 |
section: &[u8], |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48388
diff
changeset
|
134 |
) -> 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:
48388
diff
changeset
|
135 |
self.sections |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48388
diff
changeset
|
136 |
.get(section) |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48388
diff
changeset
|
137 |
.into_iter() |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48388
diff
changeset
|
138 |
.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:
48388
diff
changeset
|
139 |
} |
4a983b69e519
rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents:
48388
diff
changeset
|
140 |
|
48388
a2e278b5e265
rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
47413
diff
changeset
|
141 |
/// 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:
47413
diff
changeset
|
142 |
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:
47413
diff
changeset
|
143 |
self.sections |
a2e278b5e265
rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
47413
diff
changeset
|
144 |
.get(section) |
a2e278b5e265
rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
47413
diff
changeset
|
145 |
.map_or(false, |section| !section.is_empty()) |
a2e278b5e265
rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
47413
diff
changeset
|
146 |
} |
a2e278b5e265
rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents:
47413
diff
changeset
|
147 |
|
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
148 |
pub fn is_empty(&self) -> bool { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
149 |
self.sections.is_empty() |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
150 |
} |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
151 |
|
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
152 |
/// 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
|
153 |
/// recursively parsing the `%include` directives if any. |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
154 |
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
|
155 |
let mut layers = vec![]; |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
156 |
|
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
157 |
// Discard byte order mark if any |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
158 |
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
|
159 |
&data[3..] |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
160 |
} else { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
161 |
data |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
162 |
}; |
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 |
// TODO check if it's trusted |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
165 |
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
|
166 |
|
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
167 |
let mut lines_iter = |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
168 |
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
|
169 |
let mut section = b"".to_vec(); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
170 |
|
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
171 |
while let Some((index, bytes)) = lines_iter.next() { |
46748
12d59eec7f1d
rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents:
46746
diff
changeset
|
172 |
let line = Some(index + 1); |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
173 |
if let Some(m) = INCLUDE_RE.captures(&bytes) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
174 |
let filename_bytes = &m[1]; |
46755
91ab5190a3de
rhg: Add support for environment variables in config include paths
Simon Sapin <simon.sapin@octobus.net>
parents:
46748
diff
changeset
|
175 |
let filename_bytes = crate::utils::expand_vars(filename_bytes); |
46541
39128182f04e
rust: Remove unnecessary check for absolute path before joining
Simon Sapin <simon.sapin@octobus.net>
parents:
46540
diff
changeset
|
176 |
// `Path::parent` only fails for the root directory, |
46545
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
177 |
// 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:
46542
diff
changeset
|
178 |
// file. |
46541
39128182f04e
rust: Remove unnecessary check for absolute path before joining
Simon Sapin <simon.sapin@octobus.net>
parents:
46540
diff
changeset
|
179 |
let dir = src |
39128182f04e
rust: Remove unnecessary check for absolute path before joining
Simon Sapin <simon.sapin@octobus.net>
parents:
46540
diff
changeset
|
180 |
.parent() |
39128182f04e
rust: Remove unnecessary check for absolute path before joining
Simon Sapin <simon.sapin@octobus.net>
parents:
46540
diff
changeset
|
181 |
.expect("Path::parent fail on a file we’ve read"); |
46545
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
182 |
// `Path::join` with an absolute argument correctly ignores the |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
183 |
// base path |
46541
39128182f04e
rust: Remove unnecessary check for absolute path before joining
Simon Sapin <simon.sapin@octobus.net>
parents:
46540
diff
changeset
|
184 |
let filename = dir.join(&get_path_from_bytes(&filename_bytes)); |
46756
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
185 |
match std::fs::read(&filename) { |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
186 |
Ok(data) => { |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
187 |
layers.push(current_layer); |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
188 |
layers.extend(Self::parse(&filename, &data)?); |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
189 |
current_layer = |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
190 |
Self::new(ConfigOrigin::File(src.to_owned())); |
46748
12d59eec7f1d
rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents:
46746
diff
changeset
|
191 |
} |
46756
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
192 |
Err(error) => { |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
193 |
if error.kind() != std::io::ErrorKind::NotFound { |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
194 |
return Err(ConfigParseError { |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
195 |
origin: ConfigOrigin::File(src.to_owned()), |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
196 |
line, |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
197 |
message: format_bytes!( |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
198 |
b"cannot include {} ({})", |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
199 |
filename_bytes, |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
200 |
format_bytes::Utf8(error) |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
201 |
), |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
202 |
} |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
203 |
.into()); |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
204 |
} |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
205 |
} |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46755
diff
changeset
|
206 |
} |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
207 |
} else if let Some(_) = EMPTY_RE.captures(&bytes) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
208 |
} else if let Some(m) = SECTION_RE.captures(&bytes) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
209 |
section = m[1].to_vec(); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
210 |
} else if let Some(m) = ITEM_RE.captures(&bytes) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
211 |
let item = m[1].to_vec(); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
212 |
let mut value = m[2].to_vec(); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
213 |
loop { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
214 |
match lines_iter.peek() { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
215 |
None => break, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
216 |
Some((_, v)) => { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
217 |
if let Some(_) = COMMENT_RE.captures(&v) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
218 |
} else if let Some(_) = CONT_RE.captures(&v) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
219 |
value.extend(b"\n"); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
220 |
value.extend(&m[1]); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
221 |
} else { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
222 |
break; |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
223 |
} |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
224 |
} |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
225 |
}; |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
226 |
lines_iter.next(); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
227 |
} |
46748
12d59eec7f1d
rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents:
46746
diff
changeset
|
228 |
current_layer.add(section.clone(), item, value, line); |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
229 |
} else if let Some(m) = UNSET_RE.captures(&bytes) { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
230 |
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
|
231 |
map.remove(&m[1]); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
232 |
} |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
233 |
} else { |
46744
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
234 |
let message = if bytes.starts_with(b" ") { |
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
235 |
format_bytes!(b"unexpected leading whitespace: {}", bytes) |
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
236 |
} else { |
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
237 |
bytes.to_owned() |
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
238 |
}; |
46515
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
239 |
return Err(ConfigParseError { |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
240 |
origin: ConfigOrigin::File(src.to_owned()), |
46748
12d59eec7f1d
rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents:
46746
diff
changeset
|
241 |
line, |
46744
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
242 |
message, |
46515
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
243 |
} |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
244 |
.into()); |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
245 |
} |
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 |
if !current_layer.is_empty() { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
248 |
layers.push(current_layer); |
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 |
Ok(layers) |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
251 |
} |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
252 |
} |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
253 |
|
46551
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
254 |
impl DisplayBytes for ConfigLayer { |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
255 |
fn display_bytes( |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
256 |
&self, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
257 |
out: &mut dyn std::io::Write, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
258 |
) -> std::io::Result<()> { |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
259 |
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
|
260 |
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
|
261 |
|
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
262 |
for (section, items) in sections.into_iter() { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
263 |
let mut items: Vec<_> = items.into_iter().collect(); |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
264 |
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
|
265 |
|
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
266 |
for (item, config_entry) in items { |
46551
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
267 |
write_bytes!( |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
268 |
out, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
269 |
b"{}.{}={} # {}\n", |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
270 |
section, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
271 |
item, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
272 |
&config_entry.bytes, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
273 |
&self.origin, |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
274 |
)? |
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 |
Ok(()) |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
278 |
} |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
279 |
} |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
280 |
|
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
281 |
/// Mapping of section item to value. |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
282 |
/// In the following: |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
283 |
/// ```text |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
284 |
/// [ui] |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
285 |
/// paginate=no |
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 |
/// "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
|
288 |
pub type ConfigItem = HashMap<Vec<u8>, ConfigValue>; |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
289 |
|
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
290 |
#[derive(Clone, Debug, PartialEq)] |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
291 |
pub struct ConfigValue { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
292 |
/// 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
|
293 |
pub bytes: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
294 |
/// 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
|
295 |
pub line: Option<usize>, |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
296 |
} |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
297 |
|
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
298 |
#[derive(Clone, Debug)] |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
299 |
pub enum ConfigOrigin { |
46545
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
300 |
/// From a configuration file |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
301 |
File(PathBuf), |
46545
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
302 |
/// From a `--config` CLI argument |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
303 |
CommandLine, |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46542
diff
changeset
|
304 |
/// 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
|
305 |
Environment(Vec<u8>), |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
306 |
/* TODO cli |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
307 |
* TODO defaults (configitems.py) |
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 |
|
46551
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
313 |
impl DisplayBytes for ConfigOrigin { |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
314 |
fn display_bytes( |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
315 |
&self, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
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:
46545
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 { |
46551
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
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:
46545
diff
changeset
|
320 |
ConfigOrigin::CommandLine => out.write_all(b"--config"), |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46545
diff
changeset
|
321 |
ConfigOrigin::Environment(e) => write_bytes!(out, b"${}", e), |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
322 |
} |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
323 |
} |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
324 |
} |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
325 |
|
46515
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
326 |
#[derive(Debug)] |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
327 |
pub struct ConfigParseError { |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
328 |
pub origin: ConfigOrigin, |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
329 |
pub line: Option<usize>, |
46744
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46740
diff
changeset
|
330 |
pub message: Vec<u8>, |
46515
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
331 |
} |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
332 |
|
46503
2e2033081274
rust: replace trivial `impl From …` with `#[derive(derive_more::From)]`
Simon Sapin <simon.sapin@octobus.net>
parents:
46187
diff
changeset
|
333 |
#[derive(Debug, derive_more::From)] |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
334 |
pub enum ConfigError { |
46515
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
335 |
Parse(ConfigParseError), |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46503
diff
changeset
|
336 |
Other(HgError), |
46187
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
337 |
} |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
338 |
|
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
339 |
fn make_regex(pattern: &'static str) -> Regex { |
95d6f31e88db
hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff
changeset
|
340 |
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
|
341 |
} |