rust: replace RequirementsError with HgError
Differential Revision: https://phab.mercurial-scm.org/D9896
--- a/rust/hg-core/src/repo.rs Wed Jan 27 15:04:51 2021 +0100
+++ b/rust/hg-core/src/repo.rs Wed Jan 27 14:59:09 2021 +0100
@@ -1,3 +1,4 @@
+use crate::errors::HgError;
use crate::operations::{find_root, FindRootError};
use crate::requirements;
use memmap::{Mmap, MmapOptions};
@@ -33,9 +34,7 @@
find_root().map(Self::for_path)
}
- pub fn check_requirements(
- &self,
- ) -> Result<(), requirements::RequirementsError> {
+ pub fn check_requirements(&self) -> Result<(), HgError> {
requirements::check(self)
}
--- a/rust/hg-core/src/requirements.rs Wed Jan 27 15:04:51 2021 +0100
+++ b/rust/hg-core/src/requirements.rs Wed Jan 27 14:59:09 2021 +0100
@@ -1,19 +1,7 @@
+use crate::errors::{HgError, HgResultExt, IoResultExt};
use crate::repo::Repo;
-use std::io;
-#[derive(Debug)]
-pub enum RequirementsError {
- // TODO: include a path?
- Io(io::Error),
- /// The `requires` file is corrupted
- Corrupted,
- /// The repository requires a feature that we don't support
- Unsupported {
- feature: String,
- },
-}
-
-fn parse(bytes: &[u8]) -> Result<Vec<String>, ()> {
+fn parse(bytes: &[u8]) -> Result<Vec<String>, HgError> {
// The Python code reading this file uses `str.splitlines`
// which looks for a number of line separators (even including a couple of
// non-ASCII ones), but Python code writing it always uses `\n`.
@@ -27,16 +15,21 @@
if line[0].is_ascii_alphanumeric() && line.is_ascii() {
Ok(String::from_utf8(line.into()).unwrap())
} else {
- Err(())
+ Err(HgError::corrupted("parse error in 'requires' file"))
}
})
.collect()
}
-pub fn load(repo: &Repo) -> Result<Vec<String>, RequirementsError> {
- match repo.hg_vfs().read("requires") {
- Ok(bytes) => parse(&bytes).map_err(|()| RequirementsError::Corrupted),
-
+pub fn load(repo: &Repo) -> Result<Vec<String>, HgError> {
+ if let Some(bytes) = repo
+ .hg_vfs()
+ .read("requires")
+ .for_file("requires".as_ref())
+ .io_not_found_as_none()?
+ {
+ parse(&bytes)
+ } else {
// Treat a missing file the same as an empty file.
// From `mercurial/localrepo.py`:
// > requires file contains a newline-delimited list of
@@ -44,18 +37,19 @@
// > the repository. This file was introduced in Mercurial 0.9.2,
// > which means very old repositories may not have one. We assume
// > a missing file translates to no requirements.
- Err(error) if error.kind() == std::io::ErrorKind::NotFound => {
- Ok(Vec::new())
- }
-
- Err(error) => Err(RequirementsError::Io(error))?,
+ Ok(Vec::new())
}
}
-pub fn check(repo: &Repo) -> Result<(), RequirementsError> {
+pub fn check(repo: &Repo) -> Result<(), HgError> {
for feature in load(repo)? {
if !SUPPORTED.contains(&&*feature) {
- return Err(RequirementsError::Unsupported { feature });
+ // TODO: collect and all unknown features and include them in the
+ // error message?
+ return Err(HgError::UnsupportedFeature(format!(
+ "repository requires feature unknown to this Mercurial: {}",
+ feature
+ )));
}
}
Ok(())
--- a/rust/rhg/src/error.rs Wed Jan 27 15:04:51 2021 +0100
+++ b/rust/rhg/src/error.rs Wed Jan 27 14:59:09 2021 +0100
@@ -4,7 +4,6 @@
use format_bytes::format_bytes;
use hg::errors::HgError;
use hg::operations::FindRootError;
-use hg::requirements::RequirementsError;
use hg::revlog::revlog::RevlogError;
use hg::utils::files::get_bytes_from_path;
use std::convert::From;
@@ -17,9 +16,6 @@
RootNotFound(PathBuf),
/// The current directory cannot be found
CurrentDirNotFound(std::io::Error),
- /// `.hg/requires`
- #[from]
- RequirementsError(RequirementsError),
/// The standard output stream cannot be written to
StdoutError,
/// The standard error stream cannot be written to
@@ -38,10 +34,6 @@
match self {
CommandError::RootNotFound(_) => exitcode::ABORT,
CommandError::CurrentDirNotFound(_) => exitcode::ABORT,
- CommandError::RequirementsError(
- RequirementsError::Unsupported { .. },
- ) => exitcode::UNIMPLEMENTED_COMMAND,
- CommandError::RequirementsError(_) => exitcode::ABORT,
CommandError::StdoutError => exitcode::ABORT,
CommandError::StderrError => exitcode::ABORT,
CommandError::Abort(_) => exitcode::ABORT,
@@ -67,15 +59,9 @@
b"abort: error getting current working directory: {}\n",
e.to_string().as_bytes(),
)),
- CommandError::RequirementsError(RequirementsError::Corrupted) => {
- Some(
- "abort: .hg/requires is corrupted\n".as_bytes().to_owned(),
- )
- }
CommandError::Abort(message) => message.to_owned(),
- CommandError::RequirementsError(_)
- | CommandError::StdoutError
+ CommandError::StdoutError
| CommandError::StderrError
| CommandError::Unimplemented
| CommandError::Other(HgError::UnsupportedFeature(_)) => None,
--- a/tests/test-rhg.t Wed Jan 27 15:04:51 2021 +0100
+++ b/tests/test-rhg.t Wed Jan 27 14:59:09 2021 +0100
@@ -163,7 +163,7 @@
$ echo -e '\xFF' >> .hg/requires
$ rhg debugrequirements
- abort: .hg/requires is corrupted
+ corrupted repository: parse error in 'requires' file
[255]
Persistent nodemap