rust/hg-core/src/config/config.rs
author Simon Sapin <simon.sapin@octobus.net>
Thu, 10 Feb 2022 13:56:43 +0100
changeset 48732 d4a5c2197208
parent 48730 1aaf11e35aec
child 48733 39c447e03dbc
permissions -rw-r--r--
rhg: Add parsing for the --color global CLI argument Differential Revision: https://phab.mercurial-scm.org/D12166
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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;
46499
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
    16
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
    17
use std::collections::HashSet;
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
    18
use std::env;
46797
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
    19
use std::fmt;
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
    20
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
    21
use std::str;
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    22
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
    23
use crate::errors::{HgResultExt, IoResultExt};
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    24
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    25
/// 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
    26
/// 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
    27
#[derive(Clone)]
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    28
pub struct Config {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    29
    layers: Vec<layer::ConfigLayer>,
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
46499
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
    32
impl DisplayBytes for Config {
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
    33
    fn display_bytes(
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
    34
        &self,
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
    35
        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
    36
    ) -> std::io::Result<()> {
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    37
        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
    38
            write_bytes!(
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
    39
                out,
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
    40
                b"==== Layer {} (trusted: {}) ====\n{}",
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
    41
                index,
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
    42
                if layer.trusted {
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
    43
                    &b"yes"[..]
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
    44
                } else {
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
    45
                    &b"no"[..]
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
    46
                },
eace48b4a786 rust: Use the DisplayBytes trait in config printing
Simon Sapin <simon.sapin@octobus.net>
parents: 46486
diff changeset
    47
                layer
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    48
            )?;
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
        Ok(())
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
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    54
pub enum ConfigSource {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    55
    /// Absolute path to a config file
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    56
    AbsPath(PathBuf),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    57
    /// 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
    58
    Parsed(layer::ConfigLayer),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    59
}
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    60
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
    61
#[derive(Debug)]
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
    62
pub struct ConfigValueParseError {
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
    63
    pub origin: ConfigOrigin,
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
    64
    pub line: Option<usize>,
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
    65
    pub section: Vec<u8>,
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
    66
    pub item: Vec<u8>,
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
    67
    pub value: Vec<u8>,
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
    68
    pub expected_type: &'static str,
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
    69
}
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
    70
46797
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
    71
impl fmt::Display for ConfigValueParseError {
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
    72
    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
    73
        // 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
    74
        // corresponding python code
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
    75
        write!(
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
    76
            f,
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
    77
            "config error: {}.{} is not a {} ('{}')",
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
    78
            String::from_utf8_lossy(&self.section),
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
    79
            String::from_utf8_lossy(&self.item),
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
    80
            self.expected_type,
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
    81
            String::from_utf8_lossy(&self.value)
bcdcb4423ae3 rhg: Add more conversions between error types
Simon Sapin <simon.sapin@octobus.net>
parents: 46741
diff changeset
    82
        )
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
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
    86
impl Config {
48730
1aaf11e35aec rhg: Pass a &Config to Ui::new
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
    87
    /// The configuration to use when printing configuration-loading errors
1aaf11e35aec rhg: Pass a &Config to Ui::new
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
    88
    pub fn empty() -> Self {
1aaf11e35aec rhg: Pass a &Config to Ui::new
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
    89
        Self { layers: Vec::new() }
1aaf11e35aec rhg: Pass a &Config to Ui::new
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
    90
    }
1aaf11e35aec rhg: Pass a &Config to Ui::new
Simon Sapin <simon.sapin@octobus.net>
parents: 48451
diff changeset
    91
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
    92
    /// 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
    93
    ///
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
    94
    /// This is also affected by some environment variables.
47406
3237ed4dcda4 rhg: split non_repo_config and `--config` loading in different functions
Pulkit Goyal <7895pulkit@gmail.com>
parents: 47189
diff changeset
    95
    pub fn load_non_repo() -> Result<Self, ConfigError> {
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
    96
        let mut config = Self { layers: Vec::new() };
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
    97
        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
    98
        // HGRCPATH replaces system config
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
    99
        if opt_rc_path.is_none() {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   100
            config.add_system_config()?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   101
        }
46722
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
   102
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   103
        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
   104
        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
   105
        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
   106
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
   107
        // 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
   108
        // 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
   109
        // 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
   110
        // `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
   111
        // 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
   112
        config.add_for_environment_variable(
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
   113
            "RHG_ON_UNSUPPORTED",
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
   114
            b"rhg",
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
   115
            b"on-unsupported",
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
   116
        );
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
   117
        config.add_for_environment_variable(
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
   118
            "RHG_FALLBACK_EXECUTABLE",
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
   119
            b"rhg",
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
   120
            b"fallback-executable",
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
   121
        );
48335
b7fde9237c92 rhg: Enable `rhg status` in most tests
Simon Sapin <simon.sapin@octobus.net>
parents: 47951
diff changeset
   122
        config.add_for_environment_variable("RHG_STATUS", b"rhg", b"status");
46722
08a35cec14d4 rhg: Add environment variables for fallback configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46602
diff changeset
   123
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   124
        // HGRCPATH replaces user config
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   125
        if opt_rc_path.is_none() {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   126
            config.add_user_config()?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   127
        }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   128
        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
   129
            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
   130
                if !path.as_os_str().is_empty() {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   131
                    if path.is_dir() {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   132
                        config.add_trusted_dir(&path)?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   133
                    } else {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   134
                        config.add_trusted_file(&path)?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   135
                    }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   136
                }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   137
            }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   138
        }
47406
3237ed4dcda4 rhg: split non_repo_config and `--config` loading in different functions
Pulkit Goyal <7895pulkit@gmail.com>
parents: 47189
diff changeset
   139
        Ok(config)
3237ed4dcda4 rhg: split non_repo_config and `--config` loading in different functions
Pulkit Goyal <7895pulkit@gmail.com>
parents: 47189
diff changeset
   140
    }
3237ed4dcda4 rhg: split non_repo_config and `--config` loading in different functions
Pulkit Goyal <7895pulkit@gmail.com>
parents: 47189
diff changeset
   141
48732
d4a5c2197208 rhg: Add parsing for the --color global CLI argument
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
   142
    pub fn load_cli_args(
47406
3237ed4dcda4 rhg: split non_repo_config and `--config` loading in different functions
Pulkit Goyal <7895pulkit@gmail.com>
parents: 47189
diff changeset
   143
        &mut self,
3237ed4dcda4 rhg: split non_repo_config and `--config` loading in different functions
Pulkit Goyal <7895pulkit@gmail.com>
parents: 47189
diff changeset
   144
        cli_config_args: impl IntoIterator<Item = impl AsRef<[u8]>>,
48732
d4a5c2197208 rhg: Add parsing for the --color global CLI argument
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
   145
        color_arg: Option<Vec<u8>>,
47406
3237ed4dcda4 rhg: split non_repo_config and `--config` loading in different functions
Pulkit Goyal <7895pulkit@gmail.com>
parents: 47189
diff changeset
   146
    ) -> Result<(), ConfigError> {
46504
2e5dd18d6dc3 rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
   147
        if let Some(layer) = ConfigLayer::parse_cli_args(cli_config_args)? {
47406
3237ed4dcda4 rhg: split non_repo_config and `--config` loading in different functions
Pulkit Goyal <7895pulkit@gmail.com>
parents: 47189
diff changeset
   148
            self.layers.push(layer)
46504
2e5dd18d6dc3 rhg: Add support for --config CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents: 46499
diff changeset
   149
        }
48732
d4a5c2197208 rhg: Add parsing for the --color global CLI argument
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
   150
        if let Some(arg) = color_arg {
d4a5c2197208 rhg: Add parsing for the --color global CLI argument
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
   151
            let mut layer = ConfigLayer::new(ConfigOrigin::CommandLineColor);
d4a5c2197208 rhg: Add parsing for the --color global CLI argument
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
   152
            layer.add(b"ui"[..].into(), b"color"[..].into(), arg, None);
d4a5c2197208 rhg: Add parsing for the --color global CLI argument
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
   153
            self.layers.push(layer)
d4a5c2197208 rhg: Add parsing for the --color global CLI argument
Simon Sapin <simon.sapin@octobus.net>
parents: 48730
diff changeset
   154
        }
47406
3237ed4dcda4 rhg: split non_repo_config and `--config` loading in different functions
Pulkit Goyal <7895pulkit@gmail.com>
parents: 47189
diff changeset
   155
        Ok(())
46483
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
    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
   159
        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
   160
            .when_reading_file(path)
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   161
            .io_not_found_as_none()?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   162
        {
46732
60fe9ebae29b rhg: Sort config files when adding a directory
Simon Sapin <simon.sapin@octobus.net>
parents: 46722
diff changeset
   163
            let mut file_paths = entries
60fe9ebae29b rhg: Sort config files when adding a directory
Simon Sapin <simon.sapin@octobus.net>
parents: 46722
diff changeset
   164
                .map(|result| {
60fe9ebae29b rhg: Sort config files when adding a directory
Simon Sapin <simon.sapin@octobus.net>
parents: 46722
diff changeset
   165
                    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
   166
                })
60fe9ebae29b rhg: Sort config files when adding a directory
Simon Sapin <simon.sapin@octobus.net>
parents: 46722
diff changeset
   167
                .collect::<Result<Vec<_>, _>>()?;
60fe9ebae29b rhg: Sort config files when adding a directory
Simon Sapin <simon.sapin@octobus.net>
parents: 46722
diff changeset
   168
            file_paths.sort();
60fe9ebae29b rhg: Sort config files when adding a directory
Simon Sapin <simon.sapin@octobus.net>
parents: 46722
diff changeset
   169
            for file_path in &file_paths {
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   170
                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
   171
                    self.add_trusted_file(&file_path)?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   172
                }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   173
            }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   174
        }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   175
        Ok(())
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   176
    }
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
    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
   179
        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
   180
            .when_reading_file(path)
1f55cd5b292f rust: Add a log file rotation utility
Simon Sapin <simon.sapin@octobus.net>
parents: 46598
diff changeset
   181
            .io_not_found_as_none()?
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   182
        {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   183
            self.layers.extend(ConfigLayer::parse(path, &data)?)
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   184
        }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   185
        Ok(())
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
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   188
    fn add_for_environment_variable(
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   189
        &mut self,
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   190
        var: &str,
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   191
        section: &[u8],
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   192
        key: &[u8],
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   193
    ) {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   194
        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
   195
            let origin = layer::ConfigOrigin::Environment(var.into());
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   196
            let mut layer = ConfigLayer::new(origin);
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   197
            layer.add(
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   198
                section.to_owned(),
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   199
                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
   200
                get_bytes_from_os_str(value),
46483
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   201
                None,
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   202
            );
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   203
            self.layers.push(layer)
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   204
        }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   205
    }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   206
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   207
    #[cfg(unix)] // TODO: other platforms
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   208
    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
   209
        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
   210
            let etc = prefix.join("etc").join("mercurial");
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   211
            self.add_trusted_file(&etc.join("hgrc"))?;
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   212
            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
   213
        };
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   214
        let root = Path::new("/");
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   215
        // 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
   216
        // 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
   217
        let hg = crate::utils::current_exe()?;
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   218
        // 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
   219
        // `systemrcpath()` in `mercurial/scmposix.py`, but
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   220
        // `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
   221
        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
   222
            if installation_prefix != root {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   223
                add_for_prefix(&installation_prefix)?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   224
            }
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
        add_for_prefix(root)?;
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   227
        Ok(())
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
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   230
    #[cfg(unix)] // TODO: other plateforms
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   231
    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
   232
        let opt_home = home::home_dir();
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   233
        if let Some(home) = &opt_home {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   234
            self.add_trusted_file(&home.join(".hgrc"))?
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   235
        }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   236
        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
   237
        if !darwin {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   238
            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
   239
                .map(PathBuf::from)
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   240
                .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
   241
            {
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   242
                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
   243
            }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   244
        }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   245
        Ok(())
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   246
    }
2845892dd489 rust: Parse system and user configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46481
diff changeset
   247
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   248
    /// 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
   249
    /// as the order of `sources`.
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   250
    pub fn load_from_explicit_sources(
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   251
        sources: Vec<ConfigSource>,
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   252
    ) -> Result<Self, ConfigError> {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   253
        let mut layers = vec![];
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
        for source in sources.into_iter() {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   256
            match source {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   257
                ConfigSource::Parsed(c) => layers.push(c),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   258
                ConfigSource::AbsPath(c) => {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   259
                    // TODO check if it should be trusted
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   260
                    // 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
   261
                    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
   262
                        Err(_) => continue, // same as the python code
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   263
                        Ok(data) => data,
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
                    layers.extend(ConfigLayer::parse(&c, &data)?)
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   266
                }
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
        }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   269
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   270
        Ok(Config { layers })
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   271
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   272
46486
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   273
    /// 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
   274
    /// with `self`.
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   275
    pub(crate) fn combine_with_repo(
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   276
        &self,
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   277
        repo_config_files: &[PathBuf],
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   278
    ) -> Result<Self, ConfigError> {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   279
        let (cli_layers, other_layers) = self
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   280
            .layers
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   281
            .iter()
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   282
            .cloned()
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   283
            .partition(ConfigLayer::is_from_command_line);
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   284
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   285
        let mut repo_config = Self {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   286
            layers: other_layers,
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   287
        };
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   288
        for path in repo_config_files {
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   289
            // TODO: check if this file should be trusted:
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   290
            // `mercurial/ui.py:427`
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   291
            repo_config.add_trusted_file(path)?;
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   292
        }
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   293
        repo_config.layers.extend(cli_layers);
d7685105e504 rhg: Parse per-repository configuration
Simon Sapin <simon.sapin@octobus.net>
parents: 46483
diff changeset
   294
        Ok(repo_config)
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   295
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   296
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   297
    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
   298
        &'config self,
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   299
        section: &[u8],
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   300
        item: &[u8],
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
   301
        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
   302
        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
   303
    ) -> Result<Option<T>, ConfigValueParseError> {
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   304
        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
   305
            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
   306
                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
   307
                None => Err(ConfigValueParseError {
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   308
                    origin: layer.origin.to_owned(),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   309
                    line: v.line,
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
   310
                    value: v.bytes.to_owned(),
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
   311
                    section: section.to_owned(),
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
   312
                    item: item.to_owned(),
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
   313
                    expected_type,
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   314
                }),
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
            None => Ok(None),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   317
        }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   318
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   319
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   320
    /// 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
   321
    /// 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
   322
    pub fn get_str(
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   323
        &self,
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   324
        section: &[u8],
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   325
        item: &[u8],
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
   326
    ) -> Result<Option<&str>, ConfigValueParseError> {
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
   327
        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
   328
            str::from_utf8(value).ok()
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
   329
        })
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   330
    }
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   331
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   332
    /// 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
   333
    /// 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
   334
    pub fn get_u32(
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   335
        &self,
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   336
        section: &[u8],
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   337
        item: &[u8],
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
   338
    ) -> Result<Option<u32>, ConfigValueParseError> {
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
   339
        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
   340
            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
   341
        })
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   342
    }
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   343
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   344
    /// 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
   345
    /// 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
   346
    /// 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
   347
    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
   348
        &self,
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   349
        section: &[u8],
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   350
        item: &[u8],
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
   351
    ) -> 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
   352
        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
   353
    }
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   354
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   355
    /// 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
   356
    /// 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
   357
    /// found, or `None`.
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   358
    pub fn get_option(
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   359
        &self,
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   360
        section: &[u8],
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   361
        item: &[u8],
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
   362
    ) -> 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
   363
        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
   364
    }
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   365
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   366
    /// 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
   367
    /// 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
   368
    pub fn get_bool(
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   369
        &self,
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   370
        section: &[u8],
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   371
        item: &[u8],
46598
bc08c2331f99 rust: Add a `ConfigValueParseError` variant to common errors
Simon Sapin <simon.sapin@octobus.net>
parents: 46597
diff changeset
   372
    ) -> Result<bool, ConfigValueParseError> {
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   373
        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
   374
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   375
48414
1d940d76571b rust: add function to check if an extension is enabled
Raphaël Gomès <rgomes@octobus.net>
parents: 48339
diff changeset
   376
    /// Returns `true` if the extension is enabled, `false` otherwise
1d940d76571b rust: add function to check if an extension is enabled
Raphaël Gomès <rgomes@octobus.net>
parents: 48339
diff changeset
   377
    pub fn is_extension_enabled(&self, extension: &[u8]) -> bool {
1d940d76571b rust: add function to check if an extension is enabled
Raphaël Gomès <rgomes@octobus.net>
parents: 48339
diff changeset
   378
        let value = self.get(b"extensions", extension);
1d940d76571b rust: add function to check if an extension is enabled
Raphaël Gomès <rgomes@octobus.net>
parents: 48339
diff changeset
   379
        match value {
1d940d76571b rust: add function to check if an extension is enabled
Raphaël Gomès <rgomes@octobus.net>
parents: 48339
diff changeset
   380
            Some(c) => !c.starts_with(b"!"),
1d940d76571b rust: add function to check if an extension is enabled
Raphaël Gomès <rgomes@octobus.net>
parents: 48339
diff changeset
   381
            None => false,
1d940d76571b rust: add function to check if an extension is enabled
Raphaël Gomès <rgomes@octobus.net>
parents: 48339
diff changeset
   382
        }
1d940d76571b rust: add function to check if an extension is enabled
Raphaël Gomès <rgomes@octobus.net>
parents: 48339
diff changeset
   383
    }
1d940d76571b rust: add function to check if an extension is enabled
Raphaël Gomès <rgomes@octobus.net>
parents: 48339
diff changeset
   384
47950
6961eca0b3ee rhg: Port Python’s `ui.configlist` as `Config::get_list`
Simon Sapin <simon.sapin@octobus.net>
parents: 47406
diff changeset
   385
    /// If there is an `item` value in `section`, parse and return a list of
6961eca0b3ee rhg: Port Python’s `ui.configlist` as `Config::get_list`
Simon Sapin <simon.sapin@octobus.net>
parents: 47406
diff changeset
   386
    /// byte strings.
6961eca0b3ee rhg: Port Python’s `ui.configlist` as `Config::get_list`
Simon Sapin <simon.sapin@octobus.net>
parents: 47406
diff changeset
   387
    pub fn get_list(
6961eca0b3ee rhg: Port Python’s `ui.configlist` as `Config::get_list`
Simon Sapin <simon.sapin@octobus.net>
parents: 47406
diff changeset
   388
        &self,
6961eca0b3ee rhg: Port Python’s `ui.configlist` as `Config::get_list`
Simon Sapin <simon.sapin@octobus.net>
parents: 47406
diff changeset
   389
        section: &[u8],
6961eca0b3ee rhg: Port Python’s `ui.configlist` as `Config::get_list`
Simon Sapin <simon.sapin@octobus.net>
parents: 47406
diff changeset
   390
        item: &[u8],
6961eca0b3ee rhg: Port Python’s `ui.configlist` as `Config::get_list`
Simon Sapin <simon.sapin@octobus.net>
parents: 47406
diff changeset
   391
    ) -> Option<Vec<Vec<u8>>> {
6961eca0b3ee rhg: Port Python’s `ui.configlist` as `Config::get_list`
Simon Sapin <simon.sapin@octobus.net>
parents: 47406
diff changeset
   392
        self.get(section, item).map(values::parse_list)
6961eca0b3ee rhg: Port Python’s `ui.configlist` as `Config::get_list`
Simon Sapin <simon.sapin@octobus.net>
parents: 47406
diff changeset
   393
    }
6961eca0b3ee rhg: Port Python’s `ui.configlist` as `Config::get_list`
Simon Sapin <simon.sapin@octobus.net>
parents: 47406
diff changeset
   394
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   395
    /// 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
   396
    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
   397
        self.get_inner(section, item)
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   398
            .map(|(_, value)| value.bytes.as_ref())
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   399
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   400
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   401
    /// 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
   402
    fn get_inner(
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   403
        &self,
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   404
        section: &[u8],
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   405
        item: &[u8],
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   406
    ) -> Option<(&ConfigLayer, &ConfigValue)> {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   407
        for layer in self.layers.iter().rev() {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   408
            if !layer.trusted {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   409
                continue;
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   410
            }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   411
            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
   412
                return Some((&layer, v));
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   413
            }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   414
        }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   415
        None
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   416
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   417
46733
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46732
diff changeset
   418
    /// 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
   419
    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
   420
        self.layers
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46732
diff changeset
   421
            .iter()
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46732
diff changeset
   422
            .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
   423
            .collect()
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46732
diff changeset
   424
    }
1bac7764ceef rhg: Fall back to Python if unsupported extensions are enabled
Simon Sapin <simon.sapin@octobus.net>
parents: 46732
diff changeset
   425
48339
a2e278b5e265 rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48335
diff changeset
   426
    /// Returns whether any key is defined in the given section
a2e278b5e265 rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48335
diff changeset
   427
    pub fn has_non_empty_section(&self, section: &[u8]) -> bool {
a2e278b5e265 rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48335
diff changeset
   428
        self.layers
a2e278b5e265 rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48335
diff changeset
   429
            .iter()
a2e278b5e265 rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48335
diff changeset
   430
            .any(|layer| layer.has_non_empty_section(section))
a2e278b5e265 rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48335
diff changeset
   431
    }
a2e278b5e265 rhg: [encode] and [decode] config sections are not supported
Simon Sapin <simon.sapin@octobus.net>
parents: 48335
diff changeset
   432
48451
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   433
    /// Yields (key, value) pairs for everything in the given section
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   434
    pub fn iter_section<'a>(
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   435
        &'a self,
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   436
        section: &'a [u8],
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   437
    ) -> impl Iterator<Item = (&[u8], &[u8])> + 'a {
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   438
        // TODO: Use `Iterator`’s `.peekable()` when its `peek_mut` is
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   439
        // available:
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   440
        // https://doc.rust-lang.org/nightly/std/iter/struct.Peekable.html#method.peek_mut
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   441
        struct Peekable<I: Iterator> {
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   442
            iter: I,
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   443
            /// Remember a peeked value, even if it was None.
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   444
            peeked: Option<Option<I::Item>>,
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   445
        }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   446
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   447
        impl<I: Iterator> Peekable<I> {
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   448
            fn new(iter: I) -> Self {
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   449
                Self { iter, peeked: None }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   450
            }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   451
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   452
            fn next(&mut self) {
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   453
                self.peeked = None
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   454
            }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   455
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   456
            fn peek_mut(&mut self) -> Option<&mut I::Item> {
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   457
                let iter = &mut self.iter;
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   458
                self.peeked.get_or_insert_with(|| iter.next()).as_mut()
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   459
            }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   460
        }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   461
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   462
        // Deduplicate keys redefined in multiple layers
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   463
        let mut keys_already_seen = HashSet::new();
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   464
        let mut key_is_new =
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   465
            move |&(key, _value): &(&'a [u8], &'a [u8])| -> bool {
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   466
                keys_already_seen.insert(key)
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   467
            };
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   468
        // This is similar to `flat_map` + `filter_map`, except with a single
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   469
        // closure that owns `key_is_new` (and therefore the
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   470
        // `keys_already_seen` set):
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   471
        let mut layer_iters = Peekable::new(
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   472
            self.layers
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   473
                .iter()
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   474
                .rev()
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   475
                .map(move |layer| layer.iter_section(section)),
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   476
        );
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   477
        std::iter::from_fn(move || loop {
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   478
            if let Some(pair) = layer_iters.peek_mut()?.find(&mut key_is_new) {
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   479
                return Some(pair);
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   480
            } else {
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   481
                layer_iters.next();
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   482
            }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   483
        })
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   484
    }
4a983b69e519 rhg: Add support for ui.ignore and ui.ignore.* config
Simon Sapin <simon.sapin@octobus.net>
parents: 48414
diff changeset
   485
46187
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   486
    /// 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
   487
    /// of precedence.
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   488
    #[cfg(test)]
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   489
    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
   490
        let mut res = vec![];
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   491
        for layer in self.layers.iter().rev() {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   492
            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
   493
                res.push(v.bytes.as_ref());
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   494
            }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   495
        }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   496
        res
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   497
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   498
}
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   499
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   500
#[cfg(test)]
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   501
mod tests {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   502
    use super::*;
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   503
    use pretty_assertions::assert_eq;
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   504
    use std::fs::File;
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   505
    use std::io::Write;
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   506
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   507
    #[test]
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   508
    fn test_include_layer_ordering() {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   509
        let tmpdir = tempfile::tempdir().unwrap();
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   510
        let tmpdir_path = tmpdir.path();
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   511
        let mut included_file =
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   512
            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
   513
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   514
        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
   515
        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
   516
        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
   517
        let data =
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   518
            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
   519
              [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
   520
        config_file.write_all(data).unwrap();
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   521
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   522
        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
   523
        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
   524
            .expect("expected valid config");
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   525
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   526
        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
   527
        assert_eq!(
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   528
            value,
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   529
            &ConfigValue {
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   530
                bytes: b"value2".to_vec(),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   531
                line: Some(4)
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   532
            }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   533
        );
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   534
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   535
        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
   536
        assert_eq!(value, b"value2",);
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   537
        assert_eq!(
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   538
            config.get_all(b"section", b"item"),
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   539
            [b"value2", b"value1", b"value0"]
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   540
        );
46597
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   541
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   542
        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
   543
        assert_eq!(
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   544
            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
   545
            Some(1024 + 512)
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   546
        );
305d74c262de rust: Add config parsing support for more value types
Simon Sapin <simon.sapin@octobus.net>
parents: 46596
diff changeset
   547
        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
   548
        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
   549
    }
95d6f31e88db hg-core: add basic config module
Raphaël Gomès <rgomes@octobus.net>
parents:
diff changeset
   550
}