annotate rust/hg-core/src/config/config.rs @ 47347:73ddcedeaadf

dirstate-tree: Change status() results to not borrow DirstateMap The `status` function takes a `&'tree mut DirstateMap<'on_disk>` parameter. `'on_disk` borrows a read-only byte buffer with the contents of the `.hg/dirstate` file. `DirstateMap` internally uses represents file paths as `std::borrow::Cow<'on_disk, HgPath>`, which borrows the byte buffer when possible and allocates an owned string if not, such as for files added to the dirstate after it was loaded from disk. Previously the return type of of `status` has a `'tree`?lifetime, meaning it could borrow all paths from the `DirstateMap`. With this changeset, that lifetime is changed to `'on_disk` meaning that only paths from the byte buffer can be borrowed, and paths allocated by `DirstateMap` must be copied. Usually most paths are in the byte buffer, and most paths are not part of the return value of `status`, so the number of extra copies should be small. This change will enable `status` to mutate the `DirstateMap` after it has finished constructing its return value. Previously such mutation would be prevented by possible on-going borrows. Differential Revision: https://phab.mercurial-scm.org/D10824
author Simon Sapin <simon.sapin@octobus.net>
date Fri, 28 May 2021 20:07:27 +0200
parents b0e92313107e
children 3237ed4dcda4
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 // config.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
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
10 use super::layer;
46602
a687a7f27951 rust: Move config value parsing functions to a new module
Simon Sapin <simon.sapin@octobus.net>
parents: 46599
diff changeset
11 use super::values;
46447
0cb1b02228a6 rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
12 use crate::config::layer::{
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
13 ConfigError, ConfigLayer, ConfigOrigin, ConfigValue,
46447
0cb1b02228a6 rust: use HgError in ConfigError
Simon Sapin <simon.sapin@octobus.net>
parents: 46446
diff changeset
14 };
46596
d2e61f00ee9d rust: Introduce a get_bytes_from_os_str utility function
Simon Sapin <simon.sapin@octobus.net>
parents: 46504
diff changeset
15 use crate::utils::files::get_bytes_from_os_str;
46734
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
16 use crate::utils::SliceExt;
46499
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
17 use format_bytes::{write_bytes, DisplayBytes};
46733
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46732
diff changeset
18 use std::collections::HashSet;
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
19 use std::env;
46797
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
20 use std::fmt;
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
21 use std::path::{Path, PathBuf};
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
22 use std::str;
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
23
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
24 use crate::errors::{HgResultExt, IoResultExt};
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
25
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
26 /// Holds the config values for the current repository
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
27 /// TODO update this docstring once we support more sources
46741
25e3dac511f0 rhg: Add support for the HGRCSKIPREPO environment variable
Simon Sapin <simon.sapin@octobus.net>
parents: 46734
diff changeset
28 #[derive(Clone)]
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
29 pub struct Config {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
30 layers: Vec<layer::ConfigLayer>,
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
46499
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
33 impl DisplayBytes for Config {
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
34 fn display_bytes(
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
35 &self,
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
36 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
37 ) -> std::io::Result<()> {
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
38 for (index, layer) in self.layers.iter().rev().enumerate() {
46499
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
39 write_bytes!(
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
40 out,
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
41 b"==== Layer {} (trusted: {}) ====\n{}",
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
42 index,
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
43 if layer.trusted {
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
44 &b"yes"[..]
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
45 } else {
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
46 &b"no"[..]
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
47 },
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
48 layer
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
49 )?;
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
50 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
51 Ok(())
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
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
55 pub enum ConfigSource {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
56 /// Absolute path to a config file
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
57 AbsPath(PathBuf),
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
58 /// Already parsed (from the CLI, env, Python resources, etc.)
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
59 Parsed(layer::ConfigLayer),
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
60 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
61
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
62 #[derive(Debug)]
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
63 pub struct ConfigValueParseError {
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
64 pub origin: ConfigOrigin,
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
65 pub line: Option<usize>,
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
66 pub section: Vec<u8>,
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
67 pub item: Vec<u8>,
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
68 pub value: Vec<u8>,
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
69 pub expected_type: &'static str,
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
70 }
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
71
46797
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
72 impl fmt::Display for ConfigValueParseError {
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
73 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
74 // TODO: add origin and line number information, here and in
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
75 // corresponding python code
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
76 write!(
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
77 f,
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
78 "config error: {}.{} is not a {} ('{}')",
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
79 String::from_utf8_lossy(&self.section),
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
80 String::from_utf8_lossy(&self.item),
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
81 self.expected_type,
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
82 String::from_utf8_lossy(&self.value)
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
83 )
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
84 }
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
85 }
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
86
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
87 impl Config {
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
88 /// Load system and user configuration from various files.
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
89 ///
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
90 /// This is also affected by some environment variables.
46504
2e5dd18d6dc3 rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
91 pub fn load(
2e5dd18d6dc3 rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
92 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
93 ) -> Result<Self, ConfigError> {
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
94 let mut config = Self { layers: Vec::new() };
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
95 let opt_rc_path = env::var_os("HGRCPATH");
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
96 // HGRCPATH replaces system config
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
97 if opt_rc_path.is_none() {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
98 config.add_system_config()?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
99 }
46722
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
100
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
101 config.add_for_environment_variable("EDITOR", b"ui", b"editor");
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
102 config.add_for_environment_variable("VISUAL", b"ui", b"editor");
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
103 config.add_for_environment_variable("PAGER", b"pager", b"pager");
46722
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
104
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
105 // These are set by `run-tests.py --rhg` to enable fallback for the
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
106 // entire test suite. Alternatives would be setting configuration
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
107 // through `$HGRCPATH` but some tests override that, or changing the
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
108 // `hg` shell alias to include `--config` but that disrupts tests that
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
109 // print command lines and check expected output.
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
110 config.add_for_environment_variable(
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
111 "RHG_ON_UNSUPPORTED",
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
112 b"rhg",
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
113 b"on-unsupported",
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
114 );
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
115 config.add_for_environment_variable(
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
116 "RHG_FALLBACK_EXECUTABLE",
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
117 b"rhg",
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
118 b"fallback-executable",
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
119 );
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
120
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
121 // HGRCPATH replaces user config
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
122 if opt_rc_path.is_none() {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
123 config.add_user_config()?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
124 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
125 if let Some(rc_path) = &opt_rc_path {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
126 for path in env::split_paths(rc_path) {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
127 if !path.as_os_str().is_empty() {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
128 if path.is_dir() {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
129 config.add_trusted_dir(&path)?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
130 } else {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
131 config.add_trusted_file(&path)?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
132 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
133 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
134 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
135 }
46504
2e5dd18d6dc3 rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
136 if let Some(layer) = ConfigLayer::parse_cli_args(cli_config_args)? {
2e5dd18d6dc3 rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
137 config.layers.push(layer)
2e5dd18d6dc3 rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
138 }
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
139 Ok(config)
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
140 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
141
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
142 fn add_trusted_dir(&mut self, path: &Path) -> Result<(), ConfigError> {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
143 if let Some(entries) = std::fs::read_dir(path)
46599
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46598
diff changeset
144 .when_reading_file(path)
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
145 .io_not_found_as_none()?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
146 {
46732
60fe9ebae29b rhg: Sort config files when adding a directory
Simon Sapin <simon.sapin@octobus.net>
parents: 46722
diff changeset
147 let mut file_paths = entries
60fe9ebae29b rhg: Sort config files when adding a directory
Simon Sapin <simon.sapin@octobus.net>
parents: 46722
diff changeset
148 .map(|result| {
60fe9ebae29b rhg: Sort config files when adding a directory
Simon Sapin <simon.sapin@octobus.net>
parents: 46722
diff changeset
149 result.when_reading_file(path).map(|entry| entry.path())
60fe9ebae29b rhg: Sort config files when adding a directory
Simon Sapin <simon.sapin@octobus.net>
parents: 46722
diff changeset
150 })
60fe9ebae29b rhg: Sort config files when adding a directory
Simon Sapin <simon.sapin@octobus.net>
parents: 46722
diff changeset
151 .collect::<Result<Vec<_>, _>>()?;
60fe9ebae29b rhg: Sort config files when adding a directory
Simon Sapin <simon.sapin@octobus.net>
parents: 46722
diff changeset
152 file_paths.sort();
60fe9ebae29b rhg: Sort config files when adding a directory
Simon Sapin <simon.sapin@octobus.net>
parents: 46722
diff changeset
153 for file_path in &file_paths {
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
154 if file_path.extension() == Some(std::ffi::OsStr::new("rc")) {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
155 self.add_trusted_file(&file_path)?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
156 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
157 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
158 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
159 Ok(())
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
160 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
161
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
162 fn add_trusted_file(&mut self, path: &Path) -> Result<(), ConfigError> {
46599
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46598
diff changeset
163 if let Some(data) = std::fs::read(path)
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46598
diff changeset
164 .when_reading_file(path)
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46598
diff changeset
165 .io_not_found_as_none()?
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
166 {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
167 self.layers.extend(ConfigLayer::parse(path, &data)?)
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
168 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
169 Ok(())
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
170 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
171
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
172 fn add_for_environment_variable(
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
173 &mut self,
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
174 var: &str,
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
175 section: &[u8],
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
176 key: &[u8],
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
177 ) {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
178 if let Some(value) = env::var_os(var) {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
179 let origin = layer::ConfigOrigin::Environment(var.into());
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
180 let mut layer = ConfigLayer::new(origin);
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
181 layer.add(
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
182 section.to_owned(),
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
183 key.to_owned(),
46596
d2e61f00ee9d rust: Introduce a get_bytes_from_os_str utility function
Simon Sapin <simon.sapin@octobus.net>
parents: 46504
diff changeset
184 get_bytes_from_os_str(value),
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
185 None,
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
186 );
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
187 self.layers.push(layer)
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
188 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
189 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
190
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
191 #[cfg(unix)] // TODO: other platforms
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
192 fn add_system_config(&mut self) -> Result<(), ConfigError> {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
193 let mut add_for_prefix = |prefix: &Path| -> Result<(), ConfigError> {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
194 let etc = prefix.join("etc").join("mercurial");
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
195 self.add_trusted_file(&etc.join("hgrc"))?;
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
196 self.add_trusted_dir(&etc.join("hgrc.d"))
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
197 };
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
198 let root = Path::new("/");
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
199 // TODO: use `std::env::args_os().next().unwrap()` a.k.a. argv[0]
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
200 // instead? TODO: can this be a relative path?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
201 let hg = crate::utils::current_exe()?;
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
202 // TODO: this order (per-installation then per-system) matches
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
203 // `systemrcpath()` in `mercurial/scmposix.py`, but
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
204 // `mercurial/helptext/config.txt` suggests it should be reversed
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
205 if let Some(installation_prefix) = hg.parent().and_then(Path::parent) {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
206 if installation_prefix != root {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
207 add_for_prefix(&installation_prefix)?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
208 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
209 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
210 add_for_prefix(root)?;
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
211 Ok(())
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
212 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
213
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
214 #[cfg(unix)] // TODO: other plateforms
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
215 fn add_user_config(&mut self) -> Result<(), ConfigError> {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
216 let opt_home = home::home_dir();
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
217 if let Some(home) = &opt_home {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
218 self.add_trusted_file(&home.join(".hgrc"))?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
219 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
220 let darwin = cfg!(any(target_os = "macos", target_os = "ios"));
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
221 if !darwin {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
222 if let Some(config_home) = env::var_os("XDG_CONFIG_HOME")
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
223 .map(PathBuf::from)
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
224 .or_else(|| opt_home.map(|home| home.join(".config")))
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
225 {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
226 self.add_trusted_file(&config_home.join("hg").join("hgrc"))?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
227 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
228 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
229 Ok(())
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
230 }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
231
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
232 /// Loads in order, which means that the precedence is the same
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
233 /// as the order of `sources`.
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
234 pub fn load_from_explicit_sources(
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
235 sources: Vec<ConfigSource>,
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
236 ) -> Result<Self, ConfigError> {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
237 let mut layers = vec![];
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
238
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
239 for source in sources.into_iter() {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
240 match source {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
241 ConfigSource::Parsed(c) => layers.push(c),
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
242 ConfigSource::AbsPath(c) => {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
243 // TODO check if it should be trusted
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
244 // mercurial/ui.py:427
46481
0d734c0ae1cf rust: replace read_whole_file with std::fs::read
Simon Sapin <simon.sapin@octobus.net>
parents: 46447
diff changeset
245 let data = match std::fs::read(&c) {
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
246 Err(_) => continue, // same as the python code
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
247 Ok(data) => data,
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 layers.extend(ConfigLayer::parse(&c, &data)?)
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
250 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
251 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
252 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
253
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
254 Ok(Config { layers })
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
255 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
256
46486
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
257 /// Loads the per-repository config into a new `Config` which is combined
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
258 /// with `self`.
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
259 pub(crate) fn combine_with_repo(
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
260 &self,
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
261 repo_config_files: &[PathBuf],
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
262 ) -> Result<Self, ConfigError> {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
263 let (cli_layers, other_layers) = self
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
264 .layers
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
265 .iter()
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
266 .cloned()
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
267 .partition(ConfigLayer::is_from_command_line);
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
268
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
269 let mut repo_config = Self {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
270 layers: other_layers,
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
271 };
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
272 for path in repo_config_files {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
273 // TODO: check if this file should be trusted:
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
274 // `mercurial/ui.py:427`
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
275 repo_config.add_trusted_file(path)?;
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
276 }
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
277 repo_config.layers.extend(cli_layers);
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
278 Ok(repo_config)
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
279 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
280
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
281 fn get_parse<'config, T: 'config>(
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
282 &'config self,
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
283 section: &[u8],
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
284 item: &[u8],
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
285 expected_type: &'static str,
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
286 parse: impl Fn(&'config [u8]) -> Option<T>,
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
287 ) -> Result<Option<T>, ConfigValueParseError> {
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
288 match self.get_inner(&section, &item) {
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
289 Some((layer, v)) => match parse(&v.bytes) {
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
290 Some(b) => Ok(Some(b)),
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
291 None => Err(ConfigValueParseError {
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
292 origin: layer.origin.to_owned(),
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
293 line: v.line,
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
294 value: v.bytes.to_owned(),
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
295 section: section.to_owned(),
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
296 item: item.to_owned(),
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
297 expected_type,
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
298 }),
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
299 },
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
300 None => Ok(None),
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
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
304 /// Returns an `Err` if the first value found is not a valid UTF-8 string.
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
305 /// Otherwise, returns an `Ok(value)` if found, or `None`.
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
306 pub fn get_str(
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
307 &self,
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
308 section: &[u8],
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
309 item: &[u8],
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
310 ) -> Result<Option<&str>, ConfigValueParseError> {
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
311 self.get_parse(section, item, "ASCII or UTF-8 string", |value| {
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
312 str::from_utf8(value).ok()
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
313 })
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
314 }
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
315
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
316 /// Returns an `Err` if the first value found is not a valid unsigned
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
317 /// integer. Otherwise, returns an `Ok(value)` if found, or `None`.
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
318 pub fn get_u32(
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
319 &self,
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
320 section: &[u8],
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
321 item: &[u8],
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
322 ) -> Result<Option<u32>, ConfigValueParseError> {
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
323 self.get_parse(section, item, "valid integer", |value| {
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
324 str::from_utf8(value).ok()?.parse().ok()
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
325 })
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
326 }
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
327
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
328 /// Returns an `Err` if the first value found is not a valid file size
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
329 /// value such as `30` (default unit is bytes), `7 MB`, or `42.5 kb`.
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
330 /// Otherwise, returns an `Ok(value_in_bytes)` if found, or `None`.
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
331 pub fn get_byte_size(
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
332 &self,
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
333 section: &[u8],
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
334 item: &[u8],
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
335 ) -> Result<Option<u64>, ConfigValueParseError> {
46602
a687a7f27951 rust: Move config value parsing functions to a new module
Simon Sapin <simon.sapin@octobus.net>
parents: 46599
diff changeset
336 self.get_parse(section, item, "byte quantity", values::parse_byte_size)
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
337 }
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
338
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
339 /// Returns an `Err` if the first value found is not a valid boolean.
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
340 /// Otherwise, returns an `Ok(option)`, where `option` is the boolean if
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
341 /// found, or `None`.
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
342 pub fn get_option(
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
343 &self,
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
344 section: &[u8],
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
345 item: &[u8],
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
346 ) -> Result<Option<bool>, ConfigValueParseError> {
46602
a687a7f27951 rust: Move config value parsing functions to a new module
Simon Sapin <simon.sapin@octobus.net>
parents: 46599
diff changeset
347 self.get_parse(section, item, "boolean", values::parse_bool)
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
348 }
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
349
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
350 /// Returns the corresponding boolean in the config. Returns `Ok(false)`
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
351 /// if the value is not found, an `Err` if it's not a valid boolean.
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
352 pub fn get_bool(
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
353 &self,
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
354 section: &[u8],
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
355 item: &[u8],
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
356 ) -> Result<bool, ConfigValueParseError> {
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
357 Ok(self.get_option(section, item)?.unwrap_or(false))
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
358 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
359
46734
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
360 /// Returns the corresponding list-value in the config if found, or `None`.
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
361 ///
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
362 /// This is appropriate for new configuration keys. The value syntax is
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
363 /// **not** the same as most existing list-valued config, which has Python
47189
b0e92313107e parselist: move the function from config to stringutil
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46797
diff changeset
364 /// parsing implemented in `parselist()` in
b0e92313107e parselist: move the function from config to stringutil
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46797
diff changeset
365 /// `mercurial/utils/stringutil.py`. Faithfully porting that parsing
b0e92313107e parselist: move the function from config to stringutil
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46797
diff changeset
366 /// algorithm to Rust (including behavior that are arguably bugs)
b0e92313107e parselist: move the function from config to stringutil
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46797
diff changeset
367 /// turned out to be non-trivial and hasn’t been completed as of this
b0e92313107e parselist: move the function from config to stringutil
Pierre-Yves David <pierre-yves.david@octobus.net>
parents: 46797
diff changeset
368 /// writing.
46734
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
369 ///
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
370 /// Instead, the "simple" syntax is: split on comma, then trim leading and
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
371 /// trailing whitespace of each component. Quotes or backslashes are not
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
372 /// interpreted in any way. Commas are mandatory between values. Values
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
373 /// that contain a comma are not supported.
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
374 pub fn get_simple_list(
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
375 &self,
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
376 section: &[u8],
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
377 item: &[u8],
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
378 ) -> Option<impl Iterator<Item = &[u8]>> {
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
379 self.get(section, item).map(|value| {
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
380 value
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
381 .split(|&byte| byte == b',')
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
382 .map(|component| component.trim())
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
383 })
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
384 }
1a036d33bc18 rhg: Add an allow-list of ignored extensions
Simon Sapin <simon.sapin@octobus.net>
parents: 46733
diff changeset
385
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
386 /// Returns the raw value bytes of the first one found, or `None`.
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
387 pub fn get(&self, section: &[u8], item: &[u8]) -> Option<&[u8]> {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
388 self.get_inner(section, item)
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
389 .map(|(_, value)| value.bytes.as_ref())
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
390 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
391
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
392 /// Returns the layer and the value of the first one found, or `None`.
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
393 fn get_inner(
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
394 &self,
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
395 section: &[u8],
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
396 item: &[u8],
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
397 ) -> Option<(&ConfigLayer, &ConfigValue)> {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
398 for layer in self.layers.iter().rev() {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
399 if !layer.trusted {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
400 continue;
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
401 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
402 if let Some(v) = layer.get(&section, &item) {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
403 return Some((&layer, v));
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
404 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
405 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
406 None
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
407 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
408
46733
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46732
diff changeset
409 /// Return all keys defined for the given section
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46732
diff changeset
410 pub fn get_section_keys(&self, section: &[u8]) -> HashSet<&[u8]> {
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46732
diff changeset
411 self.layers
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46732
diff changeset
412 .iter()
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46732
diff changeset
413 .flat_map(|layer| layer.iter_keys(section))
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46732
diff changeset
414 .collect()
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46732
diff changeset
415 }
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46732
diff changeset
416
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
417 /// Get raw values bytes from all layers (even untrusted ones) in order
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
418 /// of precedence.
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
419 #[cfg(test)]
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
420 fn get_all(&self, section: &[u8], item: &[u8]) -> Vec<&[u8]> {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
421 let mut res = vec![];
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
422 for layer in self.layers.iter().rev() {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
423 if let Some(v) = layer.get(&section, &item) {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
424 res.push(v.bytes.as_ref());
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
425 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
426 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
427 res
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
428 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
429 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
430
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
431 #[cfg(test)]
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
432 mod tests {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
433 use super::*;
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
434 use pretty_assertions::assert_eq;
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
435 use std::fs::File;
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
436 use std::io::Write;
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
437
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
438 #[test]
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
439 fn test_include_layer_ordering() {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
440 let tmpdir = tempfile::tempdir().unwrap();
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
441 let tmpdir_path = tmpdir.path();
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
442 let mut included_file =
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
443 File::create(&tmpdir_path.join("included.rc")).unwrap();
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
444
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
445 included_file.write_all(b"[section]\nitem=value1").unwrap();
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
446 let base_config_path = tmpdir_path.join("base.rc");
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
447 let mut config_file = File::create(&base_config_path).unwrap();
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
448 let data =
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
449 b"[section]\nitem=value0\n%include included.rc\nitem=value2\n\
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
450 [section2]\ncount = 4\nsize = 1.5 KB\nnot-count = 1.5\nnot-size = 1 ub";
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
451 config_file.write_all(data).unwrap();
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
452
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
453 let sources = vec![ConfigSource::AbsPath(base_config_path)];
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
454 let config = Config::load_from_explicit_sources(sources)
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
455 .expect("expected valid config");
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
456
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
457 let (_, value) = config.get_inner(b"section", b"item").unwrap();
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
458 assert_eq!(
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
459 value,
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
460 &ConfigValue {
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
461 bytes: b"value2".to_vec(),
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
462 line: Some(4)
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
463 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
464 );
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
465
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
466 let value = config.get(b"section", b"item").unwrap();
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
467 assert_eq!(value, b"value2",);
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
468 assert_eq!(
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
469 config.get_all(b"section", b"item"),
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
470 [b"value2", b"value1", b"value0"]
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
471 );
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
472
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
473 assert_eq!(config.get_u32(b"section2", b"count").unwrap(), Some(4));
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
474 assert_eq!(
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
475 config.get_byte_size(b"section2", b"size").unwrap(),
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
476 Some(1024 + 512)
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
477 );
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
478 assert!(config.get_u32(b"section2", b"not-count").is_err());
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
479 assert!(config.get_byte_size(b"section2", b"not-size").is_err());
46187
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
480 }
95d6f31e88db hg-core: add basic config module
Rapha?l Gom?s <rgomes@octobus.net>
parents:
diff changeset
481 }