rhg: Parse system and user configuration at program start
authorSimon Sapin <simon.sapin@octobus.net>
Thu, 04 Feb 2021 13:17:55 +0100
changeset 46484 a6e4e4650bac
parent 46483 2845892dd489
child 46485 f031fe1c6ede
rhg: Parse system and user configuration at program start … and pass it around up to `Repo::find` Differential Revision: https://phab.mercurial-scm.org/D9962
rust/hg-core/src/repo.rs
rust/rhg/src/commands.rs
rust/rhg/src/commands/cat.rs
rust/rhg/src/commands/debugdata.rs
rust/rhg/src/commands/debugrequirements.rs
rust/rhg/src/commands/files.rs
rust/rhg/src/commands/root.rs
rust/rhg/src/error.rs
rust/rhg/src/main.rs
--- a/rust/hg-core/src/repo.rs	Thu Feb 04 13:16:21 2021 +0100
+++ b/rust/hg-core/src/repo.rs	Thu Feb 04 13:17:55 2021 +0100
@@ -1,3 +1,4 @@
+use crate::config::Config;
 use crate::errors::{HgError, IoResultExt};
 use crate::requirements;
 use crate::utils::files::get_path_from_bytes;
@@ -31,7 +32,7 @@
 impl Repo {
     /// Search the current directory and its ancestores for a repository:
     /// a working directory that contains a `.hg` sub-directory.
-    pub fn find() -> Result<Self, RepoFindError> {
+    pub fn find(_config: &Config) -> Result<Self, RepoFindError> {
         let current_directory = crate::utils::current_dir()?;
         // ancestors() is inclusive: it first yields `current_directory` as-is.
         for ancestor in current_directory.ancestors() {
--- a/rust/rhg/src/commands.rs	Thu Feb 04 13:16:21 2021 +0100
+++ b/rust/rhg/src/commands.rs	Thu Feb 04 13:17:55 2021 +0100
@@ -5,10 +5,11 @@
 pub mod root;
 use crate::error::CommandError;
 use crate::ui::Ui;
+use hg::config::Config;
 
 /// The common trait for rhg commands
 ///
 /// Normalize the interface of the commands provided by rhg
 pub trait Command {
-    fn run(&self, ui: &Ui) -> Result<(), CommandError>;
+    fn run(&self, ui: &Ui, config: &Config) -> Result<(), CommandError>;
 }
--- a/rust/rhg/src/commands/cat.rs	Thu Feb 04 13:16:21 2021 +0100
+++ b/rust/rhg/src/commands/cat.rs	Thu Feb 04 13:17:55 2021 +0100
@@ -1,6 +1,7 @@
 use crate::commands::Command;
 use crate::error::CommandError;
 use crate::ui::Ui;
+use hg::config::Config;
 use hg::operations::cat;
 use hg::repo::Repo;
 use hg::utils::hg_path::HgPathBuf;
@@ -29,8 +30,8 @@
 
 impl<'a> Command for CatCommand<'a> {
     #[timed]
-    fn run(&self, ui: &Ui) -> Result<(), CommandError> {
-        let repo = Repo::find()?;
+    fn run(&self, ui: &Ui, config: &Config) -> Result<(), CommandError> {
+        let repo = Repo::find(config)?;
         let cwd = hg::utils::current_dir()?;
 
         let mut files = vec![];
--- a/rust/rhg/src/commands/debugdata.rs	Thu Feb 04 13:16:21 2021 +0100
+++ b/rust/rhg/src/commands/debugdata.rs	Thu Feb 04 13:17:55 2021 +0100
@@ -1,6 +1,7 @@
 use crate::commands::Command;
 use crate::error::CommandError;
 use crate::ui::Ui;
+use hg::config::Config;
 use hg::operations::{debug_data, DebugDataKind};
 use hg::repo::Repo;
 use micro_timer::timed;
@@ -22,8 +23,8 @@
 
 impl<'a> Command for DebugDataCommand<'a> {
     #[timed]
-    fn run(&self, ui: &Ui) -> Result<(), CommandError> {
-        let repo = Repo::find()?;
+    fn run(&self, ui: &Ui, config: &Config) -> Result<(), CommandError> {
+        let repo = Repo::find(config)?;
         let data = debug_data(&repo, self.rev, self.kind)
             .map_err(|e| (e, self.rev))?;
 
--- a/rust/rhg/src/commands/debugrequirements.rs	Thu Feb 04 13:16:21 2021 +0100
+++ b/rust/rhg/src/commands/debugrequirements.rs	Thu Feb 04 13:17:55 2021 +0100
@@ -1,6 +1,7 @@
 use crate::commands::Command;
 use crate::error::CommandError;
 use crate::ui::Ui;
+use hg::config::Config;
 use hg::repo::Repo;
 
 pub const HELP_TEXT: &str = "
@@ -16,8 +17,8 @@
 }
 
 impl Command for DebugRequirementsCommand {
-    fn run(&self, ui: &Ui) -> Result<(), CommandError> {
-        let repo = Repo::find()?;
+    fn run(&self, ui: &Ui, config: &Config) -> Result<(), CommandError> {
+        let repo = Repo::find(config)?;
         let mut output = String::new();
         let mut requirements: Vec<_> = repo.requirements().iter().collect();
         requirements.sort();
--- a/rust/rhg/src/commands/files.rs	Thu Feb 04 13:16:21 2021 +0100
+++ b/rust/rhg/src/commands/files.rs	Thu Feb 04 13:17:55 2021 +0100
@@ -1,6 +1,7 @@
 use crate::commands::Command;
 use crate::error::CommandError;
 use crate::ui::Ui;
+use hg::config::Config;
 use hg::operations::list_rev_tracked_files;
 use hg::operations::Dirstate;
 use hg::repo::Repo;
@@ -46,8 +47,8 @@
 }
 
 impl<'a> Command for FilesCommand<'a> {
-    fn run(&self, ui: &Ui) -> Result<(), CommandError> {
-        let repo = Repo::find()?;
+    fn run(&self, ui: &Ui, config: &Config) -> Result<(), CommandError> {
+        let repo = Repo::find(config)?;
         if let Some(rev) = self.rev {
             let files =
                 list_rev_tracked_files(&repo, rev).map_err(|e| (e, rev))?;
--- a/rust/rhg/src/commands/root.rs	Thu Feb 04 13:16:21 2021 +0100
+++ b/rust/rhg/src/commands/root.rs	Thu Feb 04 13:17:55 2021 +0100
@@ -2,6 +2,7 @@
 use crate::error::CommandError;
 use crate::ui::Ui;
 use format_bytes::format_bytes;
+use hg::config::Config;
 use hg::repo::Repo;
 use hg::utils::files::get_bytes_from_path;
 
@@ -20,8 +21,8 @@
 }
 
 impl Command for RootCommand {
-    fn run(&self, ui: &Ui) -> Result<(), CommandError> {
-        let repo = Repo::find()?;
+    fn run(&self, ui: &Ui, config: &Config) -> Result<(), CommandError> {
+        let repo = Repo::find(config)?;
         let bytes = get_bytes_from_path(repo.working_directory_path());
         ui.write_stdout(&format_bytes!(b"{}\n", bytes.as_slice()))?;
         Ok(())
--- a/rust/rhg/src/error.rs	Thu Feb 04 13:16:21 2021 +0100
+++ b/rust/rhg/src/error.rs	Thu Feb 04 13:17:55 2021 +0100
@@ -1,6 +1,7 @@
 use crate::ui::utf8_to_local;
 use crate::ui::UiError;
 use format_bytes::format_bytes;
+use hg::config::{ConfigError, ConfigParseError};
 use hg::errors::HgError;
 use hg::repo::RepoFindError;
 use hg::revlog::revlog::RevlogError;
@@ -66,6 +67,36 @@
     }
 }
 
+impl From<ConfigError> for CommandError {
+    fn from(error: ConfigError) -> Self {
+        match error {
+            ConfigError::Parse(ConfigParseError {
+                origin,
+                line,
+                bytes,
+            }) => {
+                let line_message = if let Some(line_number) = line {
+                    format_bytes!(
+                        b" at line {}",
+                        line_number.to_string().into_bytes()
+                    )
+                } else {
+                    Vec::new()
+                };
+                CommandError::Abort {
+                    message: format_bytes!(
+                        b"config parse error in {}{}: '{}'",
+                        origin.to_bytes(),
+                        line_message,
+                        bytes
+                    ),
+                }
+            }
+            ConfigError::Other(error) => error.into(),
+        }
+    }
+}
+
 impl From<(RevlogError, &str)> for CommandError {
     fn from((err, rev): (RevlogError, &str)) -> CommandError {
         match err {
--- a/rust/rhg/src/main.rs	Thu Feb 04 13:16:21 2021 +0100
+++ b/rust/rhg/src/main.rs	Thu Feb 04 13:17:55 2021 +0100
@@ -123,20 +123,23 @@
     matches: ArgMatches,
     ui: &ui::Ui,
 ) -> Result<(), CommandError> {
+    let config = hg::config::Config::load()?;
+
     match matches.subcommand() {
-        ("root", _) => commands::root::RootCommand::new().run(&ui),
+        ("root", _) => commands::root::RootCommand::new().run(&ui, &config),
         ("files", Some(matches)) => {
-            commands::files::FilesCommand::try_from(matches)?.run(&ui)
+            commands::files::FilesCommand::try_from(matches)?.run(&ui, &config)
         }
         ("cat", Some(matches)) => {
-            commands::cat::CatCommand::try_from(matches)?.run(&ui)
+            commands::cat::CatCommand::try_from(matches)?.run(&ui, &config)
         }
         ("debugdata", Some(matches)) => {
-            commands::debugdata::DebugDataCommand::try_from(matches)?.run(&ui)
+            commands::debugdata::DebugDataCommand::try_from(matches)?
+                .run(&ui, &config)
         }
         ("debugrequirements", _) => {
             commands::debugrequirements::DebugRequirementsCommand::new()
-                .run(&ui)
+                .run(&ui, &config)
         }
         _ => unreachable!(), // Because of AppSettings::SubcommandRequired,
     }