rust-pathauditor: match more of Python's behavior and display messages
authorRaphaël Gomès <rgomes@octobus.net>
Wed, 02 Oct 2024 20:29:48 +0200
changeset 52050 de317a87ea6a
parent 52049 a8cf6a852f11
child 52051 503b7688f057
rust-pathauditor: match more of Python's behavior and display messages We will make use of the path auditor when running our update fast-path, and we want to output of it to be close enough.
rust/hg-core/src/errors.rs
rust/hg-core/src/utils/hg_path.rs
rust/hg-cpython/src/utils.rs
--- a/rust/hg-core/src/errors.rs	Wed Oct 02 18:31:32 2024 +0200
+++ b/rust/hg-core/src/errors.rs	Wed Oct 02 20:29:48 2024 +0200
@@ -1,5 +1,6 @@
 use crate::config::ConfigValueParseError;
 use crate::exit_codes;
+use crate::utils::hg_path::HgPathError;
 use std::fmt;
 
 /// Common error cases that can happen in many different APIs
@@ -49,6 +50,8 @@
     /// A race condition has been detected. This *must* be handled locally
     /// and not directly surface to the user.
     RaceDetected(String),
+    /// An invalid path was found
+    Path(HgPathError),
 }
 
 /// Details about where an I/O error happened
@@ -117,6 +120,7 @@
             HgError::RaceDetected(context) => {
                 write!(f, "encountered a race condition {context}")
             }
+            HgError::Path(hg_path_error) => write!(f, "{}", hg_path_error),
         }
     }
 }
--- a/rust/hg-core/src/utils/hg_path.rs	Wed Oct 02 18:31:32 2024 +0200
+++ b/rust/hg-core/src/utils/hg_path.rs	Wed Oct 02 20:29:48 2024 +0200
@@ -5,6 +5,7 @@
 // This software may be used and distributed according to the terms of the
 // GNU General Public License version 2 or any later version.
 
+use crate::errors::HgError;
 use crate::utils::SliceExt;
 use std::borrow::Borrow;
 use std::borrow::Cow;
@@ -48,6 +49,12 @@
     },
 }
 
+impl From<HgPathError> for HgError {
+    fn from(value: HgPathError) -> Self {
+        HgError::Path(value)
+    }
+}
+
 impl fmt::Display for HgPathError {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
@@ -76,41 +83,34 @@
                 bytes
             ),
             HgPathError::EndsWithSlash(path) => {
-                write!(f, "Audit failed for '{}': ends with a slash.", path)
+                write!(f, "path '{}': ends with a slash", path)
             }
-            HgPathError::ContainsIllegalComponent(path) => write!(
-                f,
-                "Audit failed for '{}': contains an illegal component.",
-                path
-            ),
-            HgPathError::InsideDotHg(path) => write!(
-                f,
-                "Audit failed for '{}': is inside the '.hg' folder.",
-                path
-            ),
+            HgPathError::ContainsIllegalComponent(path) => {
+                write!(f, "path contains illegal component: {}", path)
+            }
+            HgPathError::InsideDotHg(path) => {
+                write!(f, "path '{}' is inside the '.hg' folder", path)
+            }
             HgPathError::IsInsideNestedRepo {
                 path,
                 nested_repo: nested,
             } => {
-                write!(f,
-                "Audit failed for '{}': is inside a nested repository '{}'.",
-                path, nested
-            )
+                write!(f, "path '{}' is inside nested repo '{}'", path, nested)
             }
             HgPathError::TraversesSymbolicLink { path, symlink } => write!(
                 f,
-                "Audit failed for '{}': traverses symbolic link '{}'.",
+                "path '{}' traverses symbolic link '{}'",
                 path, symlink
             ),
             HgPathError::NotFsCompliant(path) => write!(
                 f,
-                "Audit failed for '{}': cannot be turned into a \
-                 filesystem path.",
+                "path '{}' cannot be turned into a \
+                 filesystem path",
                 path
             ),
             HgPathError::NotUnderRoot { path, root } => write!(
                 f,
-                "Audit failed for '{}': not under root {}.",
+                "path '{}' not under root {}",
                 path.display(),
                 root.display()
             ),
--- a/rust/hg-cpython/src/utils.rs	Wed Oct 02 18:31:32 2024 +0200
+++ b/rust/hg-cpython/src/utils.rs	Wed Oct 02 20:29:48 2024 +0200
@@ -1,5 +1,8 @@
 use cpython::exc::ValueError;
-use cpython::{PyBytes, PyDict, PyErr, PyObject, PyResult, PyTuple, Python};
+use cpython::{
+    ObjectProtocol, PyBytes, PyDict, PyErr, PyObject, PyResult, PyTuple,
+    Python, ToPyObject,
+};
 use hg::config::Config;
 use hg::errors::HgError;
 use hg::repo::{Repo, RepoError};
@@ -36,6 +39,17 @@
         HgError::RaceDetected(_) => {
             unreachable!("must not surface to the user")
         }
+        HgError::Path(path_error) => {
+            let msg = PyBytes::new(py, path_error.to_string().as_bytes());
+            let cls = py
+                .import("mercurial.error")
+                .and_then(|m| m.get(py, "InputError"))
+                .unwrap();
+            PyErr::from_instance(
+                py,
+                cls.call(py, (msg,), None).ok().into_py_object(py),
+            )
+        }
         e => PyErr::new::<cpython::exc::RuntimeError, _>(py, e.to_string()),
     })
 }