rust/hg-core/src/config/config.rs
changeset 49512 6939d5ed20e0
parent 48735 29eb80d190b2
child 49513 467d9df98c68
equal deleted inserted replaced
49511:117dcc4a0e67 49512:6939d5ed20e0
    20 use std::path::{Path, PathBuf};
    20 use std::path::{Path, PathBuf};
    21 use std::str;
    21 use std::str;
    22 
    22 
    23 use crate::errors::{HgResultExt, IoResultExt};
    23 use crate::errors::{HgResultExt, IoResultExt};
    24 
    24 
       
    25 #[derive(Clone)]
       
    26 pub struct PlainInfo {
       
    27     pub plain: bool,
       
    28     pub plainalias: bool,
       
    29     pub plainrevsetalias: bool,
       
    30     pub plaintemplatealias: bool,
       
    31 }
       
    32 
    25 /// Holds the config values for the current repository
    33 /// Holds the config values for the current repository
    26 /// TODO update this docstring once we support more sources
    34 /// TODO update this docstring once we support more sources
    27 #[derive(Clone)]
    35 #[derive(Clone)]
    28 pub struct Config {
    36 pub struct Config {
    29     layers: Vec<layer::ConfigLayer>,
    37     layers: Vec<layer::ConfigLayer>,
       
    38     plain: PlainInfo,
    30 }
    39 }
    31 
    40 
    32 impl DisplayBytes for Config {
    41 impl DisplayBytes for Config {
    33     fn display_bytes(
    42     fn display_bytes(
    34         &self,
    43         &self,
    81             String::from_utf8_lossy(&self.value)
    90             String::from_utf8_lossy(&self.value)
    82         )
    91         )
    83     }
    92     }
    84 }
    93 }
    85 
    94 
       
    95 fn should_ignore(plain: &PlainInfo, section: &[u8], item: &[u8]) -> bool {
       
    96     // duplication with [_applyconfig] in [ui.py],
       
    97     if !plain.plain {
       
    98         return false;
       
    99     }
       
   100     if section == b"alias" {
       
   101         return plain.plainalias;
       
   102     }
       
   103     if section == b"revsetalias" {
       
   104         return plain.plainrevsetalias;
       
   105     }
       
   106     if section == b"templatealias" {
       
   107         return plain.plaintemplatealias;
       
   108     }
       
   109 
       
   110     if section == b"ui" {
       
   111         let to_delete: &[&[u8]] = &[
       
   112             b"debug",
       
   113             b"fallbackencoding",
       
   114             b"quiet",
       
   115             b"slash",
       
   116             b"logtemplate",
       
   117             b"message-output",
       
   118             b"statuscopies",
       
   119             b"style",
       
   120             b"traceback",
       
   121             b"verbose",
       
   122         ];
       
   123         return to_delete.contains(&item);
       
   124     }
       
   125     let sections_to_delete: &[&[u8]] =
       
   126         &[b"defaults", b"commands", b"command-templates"];
       
   127     return sections_to_delete.contains(&section);
       
   128 }
       
   129 
       
   130 impl PlainInfo {
       
   131     pub fn empty() -> Self {
       
   132         Self {
       
   133             plain: false,
       
   134             plainalias: false,
       
   135             plainrevsetalias: false,
       
   136             plaintemplatealias: false,
       
   137         }
       
   138     }
       
   139 }
    86 impl Config {
   140 impl Config {
    87     /// The configuration to use when printing configuration-loading errors
   141     /// The configuration to use when printing configuration-loading errors
    88     pub fn empty() -> Self {
   142     pub fn empty() -> Self {
    89         Self { layers: Vec::new() }
   143         Self {
       
   144             layers: Vec::new(),
       
   145             plain: PlainInfo::empty(),
       
   146         }
    90     }
   147     }
    91 
   148 
    92     /// Load system and user configuration from various files.
   149     /// Load system and user configuration from various files.
    93     ///
   150     ///
    94     /// This is also affected by some environment variables.
   151     /// This is also affected by some environment variables.
    95     pub fn load_non_repo() -> Result<Self, ConfigError> {
   152     pub fn load_non_repo() -> Result<Self, ConfigError> {
    96         let mut config = Self { layers: Vec::new() };
   153         let mut config = Self::empty();
    97         let opt_rc_path = env::var_os("HGRCPATH");
   154         let opt_rc_path = env::var_os("HGRCPATH");
    98         // HGRCPATH replaces system config
   155         // HGRCPATH replaces system config
    99         if opt_rc_path.is_none() {
   156         if opt_rc_path.is_none() {
   100             config.add_system_config()?
   157             config.add_system_config()?
   101         }
   158         }
   264                     layers.extend(ConfigLayer::parse(&c, &data)?)
   321                     layers.extend(ConfigLayer::parse(&c, &data)?)
   265                 }
   322                 }
   266             }
   323             }
   267         }
   324         }
   268 
   325 
   269         Ok(Config { layers })
   326         Ok(Config {
       
   327             layers,
       
   328             plain: PlainInfo::empty(),
       
   329         })
   270     }
   330     }
   271 
   331 
   272     /// Loads the per-repository config into a new `Config` which is combined
   332     /// Loads the per-repository config into a new `Config` which is combined
   273     /// with `self`.
   333     /// with `self`.
   274     pub(crate) fn combine_with_repo(
   334     pub(crate) fn combine_with_repo(
   281             .cloned()
   341             .cloned()
   282             .partition(ConfigLayer::is_from_command_line);
   342             .partition(ConfigLayer::is_from_command_line);
   283 
   343 
   284         let mut repo_config = Self {
   344         let mut repo_config = Self {
   285             layers: other_layers,
   345             layers: other_layers,
       
   346             plain: PlainInfo::empty(),
   286         };
   347         };
   287         for path in repo_config_files {
   348         for path in repo_config_files {
   288             // TODO: check if this file should be trusted:
   349             // TODO: check if this file should be trusted:
   289             // `mercurial/ui.py:427`
   350             // `mercurial/ui.py:427`
   290             repo_config.add_trusted_file(path)?;
   351             repo_config.add_trusted_file(path)?;
   291         }
   352         }
   292         repo_config.layers.extend(cli_layers);
   353         repo_config.layers.extend(cli_layers);
   293         Ok(repo_config)
   354         Ok(repo_config)
       
   355     }
       
   356 
       
   357     pub fn apply_plain(&mut self, plain: PlainInfo) {
       
   358         self.plain = plain;
   294     }
   359     }
   295 
   360 
   296     fn get_parse<'config, T: 'config>(
   361     fn get_parse<'config, T: 'config>(
   297         &'config self,
   362         &'config self,
   298         section: &[u8],
   363         section: &[u8],
   411     fn get_inner(
   476     fn get_inner(
   412         &self,
   477         &self,
   413         section: &[u8],
   478         section: &[u8],
   414         item: &[u8],
   479         item: &[u8],
   415     ) -> Option<(&ConfigLayer, &ConfigValue)> {
   480     ) -> Option<(&ConfigLayer, &ConfigValue)> {
       
   481         if should_ignore(&self.plain, &section, &item) {
       
   482             return None;
       
   483         }
   416         for layer in self.layers.iter().rev() {
   484         for layer in self.layers.iter().rev() {
   417             if !layer.trusted {
   485             if !layer.trusted {
   418                 continue;
   486                 continue;
   419             }
   487             }
   420             if let Some(v) = layer.get(&section, &item) {
   488             if let Some(v) = layer.get(&section, &item) {