--- a/rust/hg-core/src/config.rs Tue Sep 20 18:16:50 2022 -0400
+++ b/rust/hg-core/src/config.rs Thu Sep 22 17:16:54 2022 -0400
@@ -11,6 +11,8 @@
mod config;
mod layer;
+mod plain_info;
mod values;
-pub use config::{Config, ConfigSource, ConfigValueParseError, PlainInfo};
+pub use config::{Config, ConfigSource, ConfigValueParseError};
pub use layer::{ConfigError, ConfigOrigin, ConfigParseError};
+pub use plain_info::PlainInfo;
--- a/rust/hg-core/src/config/config.rs Tue Sep 20 18:16:50 2022 -0400
+++ b/rust/hg-core/src/config/config.rs Thu Sep 22 17:16:54 2022 -0400
@@ -12,6 +12,7 @@
use crate::config::layer::{
ConfigError, ConfigLayer, ConfigOrigin, ConfigValue,
};
+use crate::config::plain_info::PlainInfo;
use crate::utils::files::get_bytes_from_os_str;
use format_bytes::{write_bytes, DisplayBytes};
use std::collections::HashSet;
@@ -22,14 +23,6 @@
use crate::errors::{HgResultExt, IoResultExt};
-#[derive(Clone)]
-pub struct PlainInfo {
- pub plain: bool,
- pub plainalias: bool,
- pub plainrevsetalias: bool,
- pub plaintemplatealias: bool,
-}
-
/// Holds the config values for the current repository
/// TODO update this docstring once we support more sources
#[derive(Clone)]
@@ -92,21 +85,21 @@
}
}
+/// Returns true if the config item is disabled by PLAIN or PLAINEXCEPT
fn should_ignore(plain: &PlainInfo, section: &[u8], item: &[u8]) -> bool {
// duplication with [_applyconfig] in [ui.py],
- if !plain.plain {
+ if !plain.is_plain() {
return false;
}
if section == b"alias" {
- return plain.plainalias;
+ return plain.plainalias();
}
if section == b"revsetalias" {
- return plain.plainrevsetalias;
+ return plain.plainrevsetalias();
}
if section == b"templatealias" {
- return plain.plaintemplatealias;
+ return plain.plaintemplatealias();
}
-
if section == b"ui" {
let to_delete: &[&[u8]] = &[
b"debug",
@@ -127,16 +120,6 @@
return sections_to_delete.contains(§ion);
}
-impl PlainInfo {
- pub fn empty() -> Self {
- Self {
- plain: false,
- plainalias: false,
- plainrevsetalias: false,
- plaintemplatealias: false,
- }
- }
-}
impl Config {
/// The configuration to use when printing configuration-loading errors
pub fn empty() -> Self {
@@ -478,6 +461,8 @@
section: &[u8],
item: &[u8],
) -> Option<(&ConfigLayer, &ConfigValue)> {
+ // Filter out the config items that are hidden by [PLAIN].
+ // This differs from python hg where we delete them from the config.
if should_ignore(&self.plain, §ion, &item) {
return None;
}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/rust/hg-core/src/config/plain_info.rs Thu Sep 22 17:16:54 2022 -0400
@@ -0,0 +1,79 @@
+use crate::utils::files::get_bytes_from_os_string;
+use std::env;
+
+/// Keeps information on whether plain mode is active.
+///
+/// Plain mode means that all configuration variables which affect
+/// the behavior and output of Mercurial should be
+/// ignored. Additionally, the output should be stable,
+/// reproducible and suitable for use in scripts or applications.
+///
+/// The only way to trigger plain mode is by setting either the
+/// `HGPLAIN' or `HGPLAINEXCEPT' environment variables.
+///
+/// The return value can either be
+/// - False if HGPLAIN is not set, or feature is in HGPLAINEXCEPT
+/// - False if feature is disabled by default and not included in HGPLAIN
+/// - True otherwise
+#[derive(Clone)]
+pub struct PlainInfo {
+ is_plain: bool,
+ except: Vec<Vec<u8>>,
+}
+
+impl PlainInfo {
+ fn plain_except(except: Vec<Vec<u8>>) -> Self {
+ PlainInfo {
+ is_plain: true,
+ except,
+ }
+ }
+
+ pub fn empty() -> PlainInfo {
+ PlainInfo {
+ is_plain: false,
+ except: vec![],
+ }
+ }
+
+ pub fn from_env() -> PlainInfo {
+ if let Some(except) = env::var_os("HGPLAINEXCEPT") {
+ PlainInfo::plain_except(
+ get_bytes_from_os_string(except)
+ .split(|&byte| byte == b',')
+ .map(|x| x.to_vec())
+ .collect(),
+ )
+ } else {
+ PlainInfo {
+ is_plain: env::var_os("HGPLAIN").is_some(),
+ except: vec![],
+ }
+ }
+ }
+
+ pub fn is_feature_plain(&self, feature: &str) -> bool {
+ return self.is_plain
+ && !self
+ .except
+ .iter()
+ .any(|exception| exception.as_slice() == feature.as_bytes());
+ }
+
+ pub fn is_plain(&self) -> bool {
+ self.is_plain
+ }
+
+ pub fn plainalias(&self) -> bool {
+ self.is_feature_plain("alias")
+ }
+ pub fn plainrevsetalias(&self) -> bool {
+ self.is_feature_plain("revsetalias")
+ }
+ pub fn plaintemplatealias(&self) -> bool {
+ self.is_feature_plain("templatealias")
+ }
+ pub fn plaintweakdefaults(&self) -> bool {
+ self.is_feature_plain("tweakdefaults")
+ }
+}
--- a/rust/rhg/src/main.rs Tue Sep 20 18:16:50 2022 -0400
+++ b/rust/rhg/src/main.rs Thu Sep 22 17:16:54 2022 -0400
@@ -329,14 +329,7 @@
};
let mut config_cow = Cow::Borrowed(config);
- if ui::plain(None) {
- config_cow.to_mut().apply_plain(PlainInfo {
- plain: true,
- plainalias: ui::plain(Some("alias")),
- plainrevsetalias: ui::plain(Some("revsetalias")),
- plaintemplatealias: ui::plain(Some("templatealias")),
- })
- };
+ config_cow.to_mut().apply_plain(PlainInfo::from_env());
let config = config_cow.as_ref();
let ui = Ui::new(&config).unwrap_or_else(|error| {
--- a/rust/rhg/src/ui.rs Tue Sep 20 18:16:50 2022 -0400
+++ b/rust/rhg/src/ui.rs Thu Sep 22 17:16:54 2022 -0400
@@ -3,10 +3,9 @@
use format_bytes::format_bytes;
use format_bytes::write_bytes;
use hg::config::Config;
+use hg::config::PlainInfo;
use hg::errors::HgError;
-use hg::utils::files::get_bytes_from_os_string;
use std::borrow::Cow;
-use std::env;
use std::io;
use std::io::{ErrorKind, Write};
@@ -129,29 +128,13 @@
}
}
-/// Return whether plain mode is active.
-///
-/// Plain mode means that all configuration variables which affect
-/// the behavior and output of Mercurial should be
-/// ignored. Additionally, the output should be stable,
-/// reproducible and suitable for use in scripts or applications.
-///
-/// The only way to trigger plain mode is by setting either the
-/// `HGPLAIN' or `HGPLAINEXCEPT' environment variables.
-///
-/// The return value can either be
-/// - False if HGPLAIN is not set, or feature is in HGPLAINEXCEPT
-/// - False if feature is disabled by default and not included in HGPLAIN
-/// - True otherwise
+// TODO: pass the PlainInfo to call sites directly and
+// delete this function
pub fn plain(opt_feature: Option<&str>) -> bool {
- if let Some(except) = env::var_os("HGPLAINEXCEPT") {
- opt_feature.map_or(true, |feature| {
- get_bytes_from_os_string(except)
- .split(|&byte| byte == b',')
- .all(|exception| exception != feature.as_bytes())
- })
- } else {
- env::var_os("HGPLAIN").is_some()
+ let plain_info = PlainInfo::from_env();
+ match opt_feature {
+ None => plain_info.is_plain(),
+ Some(feature) => plain_info.is_feature_plain(feature),
}
}