##// END OF EJS Templates
rhg: central treatment of PLAIN and PLAINEXCEPT
Arseniy Alekseyev -
r50407:6939d5ed default
parent child Browse files
Show More
@@ -12,5 +12,5 b''
12 mod config;
12 mod config;
13 mod layer;
13 mod layer;
14 mod values;
14 mod values;
15 pub use config::{Config, ConfigSource, ConfigValueParseError};
15 pub use config::{Config, ConfigSource, ConfigValueParseError, PlainInfo};
16 pub use layer::{ConfigError, ConfigOrigin, ConfigParseError};
16 pub use layer::{ConfigError, ConfigOrigin, ConfigParseError};
@@ -22,11 +22,20 b' 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 {
@@ -83,17 +92,65 b' impl fmt::Display for ConfigValueParseEr'
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() {
@@ -266,7 +323,10 b' impl Config {'
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
@@ -283,6 +343,7 b' impl Config {'
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:
@@ -293,6 +354,10 b' impl Config {'
293 Ok(repo_config)
354 Ok(repo_config)
294 }
355 }
295
356
357 pub fn apply_plain(&mut self, plain: PlainInfo) {
358 self.plain = plain;
359 }
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],
@@ -413,6 +478,9 b' impl Config {'
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;
@@ -209,8 +209,7 b' pub fn run(invocation: &crate::CliInvoca'
209 let config = invocation.config;
209 let config = invocation.config;
210 let args = invocation.subcommand_args;
210 let args = invocation.subcommand_args;
211
211
212 let verbose = !ui.plain(None)
212 let verbose = !args.is_present("print0")
213 && !args.is_present("print0")
214 && (args.is_present("verbose")
213 && (args.is_present("verbose")
215 || config.get_bool(b"ui", b"verbose")?
214 || config.get_bool(b"ui", b"verbose")?
216 || config.get_bool(b"commands", b"status.verbose")?);
215 || config.get_bool(b"commands", b"status.verbose")?);
@@ -315,10 +314,9 b' pub fn run(invocation: &crate::CliInvoca'
315 }
314 }
316 }
315 }
317 }
316 }
318 let relative_paths = (!ui.plain(None))
317 let relative_paths = config
319 && config
318 .get_option(b"commands", b"status.relative")?
320 .get_option(b"commands", b"status.relative")?
319 .unwrap_or(config.get_bool(b"ui", b"relative-paths")?);
321 .unwrap_or(config.get_bool(b"ui", b"relative-paths")?);
322 let output = DisplayStatusPaths {
320 let output = DisplayStatusPaths {
323 ui,
321 ui,
324 no_status,
322 no_status,
@@ -6,11 +6,12 b' use clap::AppSettings;'
6 use clap::Arg;
6 use clap::Arg;
7 use clap::ArgMatches;
7 use clap::ArgMatches;
8 use format_bytes::{format_bytes, join};
8 use format_bytes::{format_bytes, join};
9 use hg::config::{Config, ConfigSource};
9 use hg::config::{Config, ConfigSource, PlainInfo};
10 use hg::repo::{Repo, RepoError};
10 use hg::repo::{Repo, RepoError};
11 use hg::utils::files::{get_bytes_from_os_str, get_path_from_bytes};
11 use hg::utils::files::{get_bytes_from_os_str, get_path_from_bytes};
12 use hg::utils::SliceExt;
12 use hg::utils::SliceExt;
13 use hg::{exit_codes, requirements};
13 use hg::{exit_codes, requirements};
14 use std::borrow::Cow;
14 use std::collections::HashSet;
15 use std::collections::HashSet;
15 use std::ffi::OsString;
16 use std::ffi::OsString;
16 use std::os::unix::prelude::CommandExt;
17 use std::os::unix::prelude::CommandExt;
@@ -326,6 +327,18 b' fn rhg_main(argv: Vec<OsString>) -> ! {'
326 } else {
327 } else {
327 &non_repo_config
328 &non_repo_config
328 };
329 };
330
331 let mut config_cow = Cow::Borrowed(config);
332 if ui::plain(None) {
333 config_cow.to_mut().apply_plain(PlainInfo {
334 plain: true,
335 plainalias: ui::plain(Some("alias")),
336 plainrevsetalias: ui::plain(Some("revsetalias")),
337 plaintemplatealias: ui::plain(Some("templatealias")),
338 })
339 };
340 let config = config_cow.as_ref();
341
329 let ui = Ui::new(&config).unwrap_or_else(|error| {
342 let ui = Ui::new(&config).unwrap_or_else(|error| {
330 exit(
343 exit(
331 &argv,
344 &argv,
@@ -127,26 +127,22 b' impl Ui {'
127 }
127 }
128 stdout.flush()
128 stdout.flush()
129 }
129 }
130
131 /// Return whether plain mode is active.
132 ///
133 /// Plain mode means that all configuration variables which affect
134 /// the behavior and output of Mercurial should be
135 /// ignored. Additionally, the output should be stable,
136 /// reproducible and suitable for use in scripts or applications.
137 ///
138 /// The only way to trigger plain mode is by setting either the
139 /// `HGPLAIN' or `HGPLAINEXCEPT' environment variables.
140 ///
141 /// The return value can either be
142 /// - False if HGPLAIN is not set, or feature is in HGPLAINEXCEPT
143 /// - False if feature is disabled by default and not included in HGPLAIN
144 /// - True otherwise
145 pub fn plain(&self, feature: Option<&str>) -> bool {
146 plain(feature)
147 }
148 }
130 }
149
131
132 /// Return whether plain mode is active.
133 ///
134 /// Plain mode means that all configuration variables which affect
135 /// the behavior and output of Mercurial should be
136 /// ignored. Additionally, the output should be stable,
137 /// reproducible and suitable for use in scripts or applications.
138 ///
139 /// The only way to trigger plain mode is by setting either the
140 /// `HGPLAIN' or `HGPLAINEXCEPT' environment variables.
141 ///
142 /// The return value can either be
143 /// - False if HGPLAIN is not set, or feature is in HGPLAINEXCEPT
144 /// - False if feature is disabled by default and not included in HGPLAIN
145 /// - True otherwise
150 pub fn plain(opt_feature: Option<&str>) -> bool {
146 pub fn plain(opt_feature: Option<&str>) -> bool {
151 if let Some(except) = env::var_os("HGPLAINEXCEPT") {
147 if let Some(except) = env::var_os("HGPLAINEXCEPT") {
152 opt_feature.map_or(true, |feature| {
148 opt_feature.map_or(true, |feature| {
General Comments 0
You need to be logged in to leave comments. Login now