Mercurial > public > mercurial-scm > hg
annotate rust/hg-core/src/config/layer.rs @ 47379:f6bb181c75f8
rust: Parse "subinclude"d files along the way, not later
When parsing a `.hgignore` file and encountering an `include:` line,
the included file is parsed recursively right then in a depth-first fashion.
With `subinclude:` however included files were parsed (recursively) much later.
This changes it to be expanded during parsing, like `.hgignore`.
The motivation for this is an upcoming changeset that needs to detect changes
in which files are ignored or not. The plan is to hash all ignore files while
they are being read, and store that hash in the dirstate (in v2 format).
In order to allow a potential alternative implementations to read that format,
the algorithm to compute that hash must be documented. Having a well-defined
depth-first ordering for the tree of (sub-)included files makes that easier.
Differential Revision: https://phab.mercurial-scm.org/D10834
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Wed, 02 Jun 2021 18:03:43 +0200 |
parents | 84a3deca963a |
children | 6e49769b7f97 |
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; |
46481
0d734c0ae1cf
rust: replace read_whole_file with std::fs::read
Simon Sapin <simon.sapin@octobus.net>
parents:
46447
diff
changeset
|
11 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
|
12 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
|
13 use lazy_static::lazy_static; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
14 use regex::bytes::Regex; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
15 use std::collections::HashMap; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
16 use std::path::{Path, PathBuf}; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
17 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
18 lazy_static! { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
19 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
|
20 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
|
21 /// Continuation whitespace |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
22 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
|
23 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
|
24 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
|
25 /// 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
|
26 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
|
27 /// 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
|
28 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
|
29 } |
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 /// 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
|
32 /// 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
|
33 /// are used. |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
34 /// TODO detail the general precedence |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
35 #[derive(Clone)] |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
36 pub struct ConfigLayer { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
37 /// Mapping of the sections to their items |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
38 sections: HashMap<Vec<u8>, ConfigItem>, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
39 /// 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
|
40 pub origin: ConfigOrigin, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
41 /// 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
|
42 pub trusted: bool, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
43 } |
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 impl ConfigLayer { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
46 pub fn new(origin: ConfigOrigin) -> Self { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
47 ConfigLayer { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
48 sections: HashMap::new(), |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
49 trusted: true, // TODO check |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
50 origin, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
51 } |
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 |
46504
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
54 /// 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
|
55 pub(crate) fn parse_cli_args( |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
56 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
|
57 ) -> Result<Option<Self>, ConfigError> { |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
58 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
|
59 use crate::utils::SliceExt; |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
60 |
46505
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46504
diff
changeset
|
61 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
|
62 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
|
63 Some(( |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
64 section.to_owned(), |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
65 item.to_owned(), |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
66 value.trim().to_owned(), |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
67 )) |
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 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
|
71 for arg in cli_config_args { |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
72 let arg = arg.as_ref(); |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
73 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
|
74 layer.add(section, item, value, None); |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
75 } else { |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
76 Err(HgError::abort(format!( |
46735
12d59eec7f1d
rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents:
46733
diff
changeset
|
77 "abort: malformed --config option: '{}' \ |
46504
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
78 (use --config section.name=value)", |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
79 String::from_utf8_lossy(arg), |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
80 )))? |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
81 } |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
82 } |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
83 if layer.sections.is_empty() { |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
84 Ok(None) |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
85 } else { |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
86 Ok(Some(layer)) |
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 } |
2e5dd18d6dc3
rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46499
diff
changeset
|
89 |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
90 /// 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
|
91 pub(crate) fn is_from_command_line(&self) -> bool { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
92 if let ConfigOrigin::CommandLine = self.origin { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
93 true |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
94 } else { |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
95 false |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
96 } |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
97 } |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
98 |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
99 /// 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
|
100 pub fn add( |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
101 &mut self, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
102 section: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
103 item: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
104 value: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
105 line: Option<usize>, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
106 ) { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
107 self.sections |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
108 .entry(section) |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
109 .or_insert_with(|| HashMap::new()) |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
110 .insert(item, ConfigValue { bytes: value, line }); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
111 } |
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 /// 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
|
114 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
|
115 Some(self.sections.get(section)?.get(item)?) |
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 |
46733
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46731
diff
changeset
|
118 /// 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
|
119 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
|
120 self.sections |
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46731
diff
changeset
|
121 .get(section) |
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46731
diff
changeset
|
122 .into_iter() |
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46731
diff
changeset
|
123 .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
|
124 } |
1bac7764ceef
rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents:
46731
diff
changeset
|
125 |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
126 pub fn is_empty(&self) -> bool { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
127 self.sections.is_empty() |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
128 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
129 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
130 /// 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
|
131 /// recursively parsing the `%include` directives if any. |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
132 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
|
133 let mut layers = vec![]; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
134 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
135 // Discard byte order mark if any |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
136 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
|
137 &data[3..] |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
138 } else { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
139 data |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
140 }; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
141 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
142 // TODO check if it's trusted |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
143 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
|
144 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
145 let mut lines_iter = |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
146 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
|
147 let mut section = b"".to_vec(); |
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 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
|
150 let line = Some(index + 1); |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
151 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
|
152 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
|
153 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
|
154 // `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
|
155 // 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
|
156 // file. |
46482
39128182f04e
rust: Remove unnecessary check for absolute path before joining
Simon Sapin <simon.sapin@octobus.net>
parents:
46481
diff
changeset
|
157 let dir = src |
39128182f04e
rust: Remove unnecessary check for absolute path before joining
Simon Sapin <simon.sapin@octobus.net>
parents:
46481
diff
changeset
|
158 .parent() |
39128182f04e
rust: Remove unnecessary check for absolute path before joining
Simon Sapin <simon.sapin@octobus.net>
parents:
46481
diff
changeset
|
159 .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
|
160 // `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
|
161 // base path |
46482
39128182f04e
rust: Remove unnecessary check for absolute path before joining
Simon Sapin <simon.sapin@octobus.net>
parents:
46481
diff
changeset
|
162 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
|
163 match std::fs::read(&filename) { |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
164 Ok(data) => { |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
165 layers.push(current_layer); |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
166 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
|
167 current_layer = |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
168 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
|
169 } |
46743
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
170 Err(error) => { |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
171 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
|
172 return Err(ConfigParseError { |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
173 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
|
174 line, |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
175 message: format_bytes!( |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
176 b"cannot include {} ({})", |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
177 filename_bytes, |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
178 format_bytes::Utf8(error) |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
179 ), |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
180 } |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
181 .into()); |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
182 } |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
183 } |
84a3deca963a
rhg: Silently ignore missing files in config %include
Simon Sapin <simon.sapin@octobus.net>
parents:
46742
diff
changeset
|
184 } |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
185 } 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
|
186 } 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
|
187 section = m[1].to_vec(); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
188 } 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
|
189 let item = m[1].to_vec(); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
190 let mut value = m[2].to_vec(); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
191 loop { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
192 match lines_iter.peek() { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
193 None => break, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
194 Some((_, v)) => { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
195 if let Some(_) = COMMENT_RE.captures(&v) { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
196 } 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
|
197 value.extend(b"\n"); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
198 value.extend(&m[1]); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
199 } else { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
200 break; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
201 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
202 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
203 }; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
204 lines_iter.next(); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
205 } |
46735
12d59eec7f1d
rhg: Align with Python on some more error messages
Simon Sapin <simon.sapin@octobus.net>
parents:
46733
diff
changeset
|
206 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
|
207 } 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
|
208 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
|
209 map.remove(&m[1]); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
210 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
211 } else { |
46731
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46727
diff
changeset
|
212 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
|
213 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
|
214 } else { |
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46727
diff
changeset
|
215 bytes.to_owned() |
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46727
diff
changeset
|
216 }; |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
217 return Err(ConfigParseError { |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
218 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
|
219 line, |
46731
3d692e724d06
rhg: Align config file parse error formatting with Python
Simon Sapin <simon.sapin@octobus.net>
parents:
46727
diff
changeset
|
220 message, |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
221 } |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
222 .into()); |
46187
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 if !current_layer.is_empty() { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
226 layers.push(current_layer); |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
227 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
228 Ok(layers) |
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 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
231 |
46499
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
232 impl DisplayBytes for ConfigLayer { |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
233 fn display_bytes( |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
234 &self, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
235 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
|
236 ) -> std::io::Result<()> { |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
237 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
|
238 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
|
239 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
240 for (section, items) in sections.into_iter() { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
241 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
|
242 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
|
243 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
244 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
|
245 write_bytes!( |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
246 out, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
247 b"{}.{}={} # {}\n", |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
248 section, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
249 item, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
250 &config_entry.bytes, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
251 &self.origin, |
46187
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 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
254 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
255 Ok(()) |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
256 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
257 } |
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 /// Mapping of section item to value. |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
260 /// In the following: |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
261 /// ```text |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
262 /// [ui] |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
263 /// paginate=no |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
264 /// ``` |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
265 /// "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
|
266 pub type ConfigItem = HashMap<Vec<u8>, ConfigValue>; |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
267 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
268 #[derive(Clone, Debug, PartialEq)] |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
269 pub struct ConfigValue { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
270 /// 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
|
271 pub bytes: Vec<u8>, |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
272 /// 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
|
273 pub line: Option<usize>, |
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 #[derive(Clone, Debug)] |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
277 pub enum ConfigOrigin { |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
278 /// From a configuration file |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
279 File(PathBuf), |
46486
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
280 /// From a `--config` CLI argument |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
281 CommandLine, |
d7685105e504
rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents:
46483
diff
changeset
|
282 /// 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
|
283 Environment(Vec<u8>), |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
284 /* TODO cli |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
285 * TODO defaults (configitems.py) |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
286 * TODO extensions |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
287 * TODO Python resources? |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
288 * Others? */ |
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 |
46499
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
291 impl DisplayBytes for ConfigOrigin { |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
292 fn display_bytes( |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
293 &self, |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
294 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
|
295 ) -> std::io::Result<()> { |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
296 match self { |
46499
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
297 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
|
298 ConfigOrigin::CommandLine => out.write_all(b"--config"), |
eace48b4a786
rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents:
46486
diff
changeset
|
299 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
|
300 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
301 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
302 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
303 |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
304 #[derive(Debug)] |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
305 pub struct ConfigParseError { |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
306 pub origin: ConfigOrigin, |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
307 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
|
308 pub message: Vec<u8>, |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
309 } |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
310 |
46435
2e2033081274
rust: replace trivial `impl From ?` with `#[derive(derive_more::From)]`
Simon Sapin <simon.sapin@octobus.net>
parents:
46187
diff
changeset
|
311 #[derive(Debug, derive_more::From)] |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
312 pub enum ConfigError { |
46447
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
313 Parse(ConfigParseError), |
0cb1b02228a6
rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents:
46435
diff
changeset
|
314 Other(HgError), |
46187
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
315 } |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
316 |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
317 fn make_regex(pattern: &'static str) -> Regex { |
95d6f31e88db
hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff
changeset
|
318 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
|
319 } |