rhg: support tweakdefaults
authorArseniy Alekseyev <aalekseyev@janestreet.com>
Tue, 20 Sep 2022 18:28:25 -0400
changeset 49514 e37416d432e9
parent 49513 467d9df98c68
child 49515 e84064e88e5d
rhg: support tweakdefaults
rust/hg-core/src/config/config.rs
rust/hg-core/src/config/layer.rs
rust/rhg/src/commands/status.rs
rust/rhg/src/main.rs
--- a/rust/hg-core/src/config/config.rs	Thu Sep 22 17:16:54 2022 -0400
+++ b/rust/hg-core/src/config/config.rs	Tue Sep 20 18:28:25 2022 -0400
@@ -463,13 +463,23 @@
     ) -> 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, &section, &item) {
-            return None;
-        }
+        let should_ignore = should_ignore(&self.plain, &section, &item);
         for layer in self.layers.iter().rev() {
             if !layer.trusted {
                 continue;
             }
+            //The [PLAIN] config should not affect the defaults.
+            //
+            // However, PLAIN should also affect the "tweaked" defaults (unless
+            // "tweakdefault" is part of "HGPLAINEXCEPT").
+            //
+            // In practice the tweak-default layer is only added when it is
+            // relevant, so we can safely always take it into
+            // account here.
+            if should_ignore && !(layer.origin == ConfigOrigin::Tweakdefaults)
+            {
+                continue;
+            }
             if let Some(v) = layer.get(&section, &item) {
                 return Some((&layer, v));
             }
@@ -557,6 +567,38 @@
         }
         res
     }
+
+    // a config layer that's introduced by ui.tweakdefaults
+    fn tweakdefaults_layer() -> ConfigLayer {
+        let mut layer = ConfigLayer::new(ConfigOrigin::Tweakdefaults);
+
+        let mut add = |section: &[u8], item: &[u8], value: &[u8]| {
+            layer.add(
+                section[..].into(),
+                item[..].into(),
+                value[..].into(),
+                None,
+            );
+        };
+        // duplication of [tweakrc] from [ui.py]
+        add(b"ui", b"rollback", b"False");
+        add(b"ui", b"statuscopies", b"yes");
+        add(b"ui", b"interface", b"curses");
+        add(b"ui", b"relative-paths", b"yes");
+        add(b"commands", b"grep.all-files", b"True");
+        add(b"commands", b"update.check", b"noconflict");
+        add(b"commands", b"status.verbose", b"True");
+        add(b"commands", b"resolve.explicit-re-merge", b"True");
+        add(b"git", b"git", b"1");
+        add(b"git", b"showfunc", b"1");
+        add(b"git", b"word-diff", b"1");
+        return layer;
+    }
+
+    // introduce the tweaked defaults as implied by ui.tweakdefaults
+    pub fn tweakdefaults<'a>(&mut self) -> () {
+        self.layers.insert(0, Config::tweakdefaults_layer());
+    }
 }
 
 #[cfg(test)]
--- a/rust/hg-core/src/config/layer.rs	Thu Sep 22 17:16:54 2022 -0400
+++ b/rust/hg-core/src/config/layer.rs	Tue Sep 20 18:28:25 2022 -0400
@@ -300,6 +300,8 @@
 pub enum ConfigOrigin {
     /// From a configuration file
     File(PathBuf),
+    /// From [ui.tweakdefaults]
+    Tweakdefaults,
     /// From a `--config` CLI argument
     CommandLine,
     /// From a `--color` CLI argument
@@ -322,6 +324,9 @@
             ConfigOrigin::CommandLine => out.write_all(b"--config"),
             ConfigOrigin::CommandLineColor => out.write_all(b"--color"),
             ConfigOrigin::Environment(e) => write_bytes!(out, b"${}", e),
+            ConfigOrigin::Tweakdefaults => {
+                write_bytes!(out, b"ui.tweakdefaults")
+            }
         }
     }
 }
--- a/rust/rhg/src/commands/status.rs	Thu Sep 22 17:16:54 2022 -0400
+++ b/rust/rhg/src/commands/status.rs	Tue Sep 20 18:28:25 2022 -0400
@@ -185,11 +185,6 @@
 
 pub fn run(invocation: &crate::CliInvocation) -> Result<(), CommandError> {
     // TODO: lift these limitations
-    if invocation.config.get_bool(b"ui", b"tweakdefaults")? {
-        return Err(CommandError::unsupported(
-            "ui.tweakdefaults is not yet supported with rhg status",
-        ));
-    }
     if invocation.config.get_bool(b"ui", b"statuscopies")? {
         return Err(CommandError::unsupported(
             "ui.statuscopies is not yet supported with rhg status",
--- a/rust/rhg/src/main.rs	Thu Sep 22 17:16:54 2022 -0400
+++ b/rust/rhg/src/main.rs	Tue Sep 20 18:28:25 2022 -0400
@@ -330,8 +330,26 @@
 
     let mut config_cow = Cow::Borrowed(config);
     config_cow.to_mut().apply_plain(PlainInfo::from_env());
+    if !ui::plain(Some("tweakdefaults"))
+        && config_cow
+            .as_ref()
+            .get_bool(b"ui", b"tweakdefaults")
+            .unwrap_or_else(|error| {
+                exit(
+                    &argv,
+                    &initial_current_dir,
+                    &Ui::new_infallible(&config),
+                    OnUnsupported::from_config(&config),
+                    Err(error.into()),
+                    config
+                        .get_bool(b"ui", b"detailed-exit-code")
+                        .unwrap_or(false),
+                )
+            })
+    {
+        config_cow.to_mut().tweakdefaults()
+    };
     let config = config_cow.as_ref();
-
     let ui = Ui::new(&config).unwrap_or_else(|error| {
         exit(
             &argv,