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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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(&section) {
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 }