##// END OF EJS Templates
rhg: Make `files` work on repo-relative paths when possible...
rhg: Make `files` work on repo-relative paths when possible When the current directory is outside of the repository we need to turn everything into absolute filesystem paths in order to compute correct relative paths. This was previously done unconditionally, but is not necessary when the current directory is inside the repository. With this change `rhg files > /dev/null` at the root of a mozilla-central snapshot goes from ~150 ms to ~70 ms. My repository is located at a somewhat long path though (93 bytes). The effect may not be as pronounced at a shorter path. Differential Revision: https://phab.mercurial-scm.org/D10200

File last commit:

r47577:e8ae91b1 default
r47687:b5e8bf10 default
Show More
error.rs
195 lines | 5.9 KiB | application/rls-services+xml | RustLexer
Pulkit Goyal
rhg: add support for detailed exit code for ConfigParseError...
r47576 use crate::exitcode;
Simon Sapin
rhg: replace `map_*_error` functions with `From` impls...
r47165 use crate::ui::utf8_to_local;
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 use crate::ui::UiError;
Simon Sapin
rhg: Move `Repo` object creation into `main()`...
r47335 use crate::NoRepoInCwdError;
Simon Sapin
rust: Fold find_root and check_requirements into Repo::find...
r47175 use format_bytes::format_bytes;
Simon Sapin
rhg: Add more conversions between error types...
r47555 use hg::config::{ConfigError, ConfigParseError, ConfigValueParseError};
Simon Sapin
rust: Fold find_root and check_requirements into Repo::find...
r47175 use hg::errors::HgError;
Simon Sapin
rhg: Parse per-repository configuration...
r47215 use hg::repo::RepoError;
Simon Sapin
rust: remove three enums that were identical to `RevlogError`...
r47166 use hg::revlog::revlog::RevlogError;
Simon Sapin
rust: Fold find_root and check_requirements into Repo::find...
r47175 use hg::utils::files::get_bytes_from_path;
Simon Sapin
rhg: Add more conversions between error types...
r47555 use hg::{DirstateError, DirstateMapError, StatusError};
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 use std::convert::From;
/// The kind of command error
Simon Sapin
rhg: Simplify CommandError based on its use...
r47174 #[derive(Debug)]
Simon Sapin
rust: remove `FooError` structs with only `kind: FooErrorKind` enum field...
r47163 pub enum CommandError {
Simon Sapin
rhg: Simplify CommandError based on its use...
r47174 /// Exit with an error message and "standard" failure exit code.
Pulkit Goyal
rhg: add support for detailed exit code for ConfigParseError...
r47576 Abort {
message: Vec<u8>,
detailed_exit_code: exitcode::ExitCode,
},
Simon Sapin
rhg: Simplify CommandError based on its use...
r47174
Simon Sapin
rhg: `cat` command: print error messages for missing files...
r47478 /// Exit with a failure exit code but no message.
Unsuccessful,
Simon Sapin
rhg: Add a `rhg.on-unsupported` configuration key...
r47424 /// Encountered something (such as a CLI argument, repository layout, …)
/// not supported by this version of `rhg`. Depending on configuration
/// `rhg` may attempt to silently fall back to Python-based `hg`, which
/// may or may not support this feature.
UnsupportedFeature { message: Vec<u8> },
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 }
Simon Sapin
rust: remove `FooError` structs with only `kind: FooErrorKind` enum field...
r47163 impl CommandError {
Simon Sapin
rhg: Simplify CommandError based on its use...
r47174 pub fn abort(message: impl AsRef<str>) -> Self {
Pulkit Goyal
rhg: add support for detailed exit code for ConfigParseError...
r47576 CommandError::abort_with_exit_code(message, exitcode::ABORT)
}
pub fn abort_with_exit_code(
message: impl AsRef<str>,
detailed_exit_code: exitcode::ExitCode,
) -> Self {
Simon Sapin
rhg: Simplify CommandError based on its use...
r47174 CommandError::Abort {
// TODO: bytes-based (instead of Unicode-based) formatting
// of error messages to handle non-UTF-8 filenames etc:
// https://www.mercurial-scm.org/wiki/EncodingStrategy#Mixing_output
message: utf8_to_local(message.as_ref()).into(),
Pulkit Goyal
rhg: add support for detailed exit code for ConfigParseError...
r47576 detailed_exit_code: detailed_exit_code,
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 }
}
Simon Sapin
rhg: Add a `rhg.on-unsupported` configuration key...
r47424
pub fn unsupported(message: impl AsRef<str>) -> Self {
CommandError::UnsupportedFeature {
message: utf8_to_local(message.as_ref()).into(),
}
}
Simon Sapin
rhg: Simplify CommandError based on its use...
r47174 }
Antoine Cezar
rhg: ask the error message from `CommandError`...
r45920
Simon Sapin
rhg: Remove error message on unsupported CLI arguments...
r47333 /// For now we don’t differenciate between invalid CLI args and valid for `hg`
/// but not supported yet by `rhg`.
impl From<clap::Error> for CommandError {
Simon Sapin
rhg: Add a `rhg.on-unsupported` configuration key...
r47424 fn from(error: clap::Error) -> Self {
CommandError::unsupported(error.to_string())
Simon Sapin
rhg: Remove error message on unsupported CLI arguments...
r47333 }
}
Simon Sapin
rhg: Simplify CommandError based on its use...
r47174 impl From<HgError> for CommandError {
fn from(error: HgError) -> Self {
match error {
Simon Sapin
rhg: Add a `rhg.on-unsupported` configuration key...
r47424 HgError::UnsupportedFeature(message) => {
CommandError::unsupported(message)
}
Simon Sapin
rhg: Simplify CommandError based on its use...
r47174 _ => CommandError::abort(error.to_string()),
Antoine Cezar
rhg: ask the error message from `CommandError`...
r45920 }
}
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 }
Simon Sapin
rhg: Add more conversions between error types...
r47555 impl From<ConfigValueParseError> for CommandError {
fn from(error: ConfigValueParseError) -> Self {
Pulkit Goyal
rhg: add support for detailed exit code for ConfigParseError...
r47576 CommandError::abort_with_exit_code(
error.to_string(),
exitcode::CONFIG_ERROR_ABORT,
)
Simon Sapin
rhg: Add more conversions between error types...
r47555 }
}
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 impl From<UiError> for CommandError {
Simon Sapin
rhg: Simplify CommandError based on its use...
r47174 fn from(_error: UiError) -> Self {
// If we already failed writing to stdout or stderr,
// writing an error message to stderr about it would be likely to fail
// too.
CommandError::abort("")
Antoine Cezar
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`...
r45592 }
}
Antoine Cezar
rhg: simplify `FindRootError` handling...
r45922
Simon Sapin
rhg: Parse per-repository configuration...
r47215 impl From<RepoError> for CommandError {
fn from(error: RepoError) -> Self {
Simon Sapin
rust: Fold find_root and check_requirements into Repo::find...
r47175 match error {
Simon Sapin
rhg: Add support for -R and --repository command-line arguments...
r47253 RepoError::NotFound { at } => CommandError::Abort {
Simon Sapin
rust: Fold find_root and check_requirements into Repo::find...
r47175 message: format_bytes!(
Simon Sapin
rhg: Align with Python on some more error messages...
r47469 b"abort: repository {} not found",
Simon Sapin
rhg: Add support for -R and --repository command-line arguments...
r47253 get_bytes_from_path(at)
Simon Sapin
rust: Fold find_root and check_requirements into Repo::find...
r47175 ),
Pulkit Goyal
rhg: add support for detailed exit code for ConfigParseError...
r47576 detailed_exit_code: exitcode::ABORT,
Simon Sapin
rust: Fold find_root and check_requirements into Repo::find...
r47175 },
Simon Sapin
rhg: Parse per-repository configuration...
r47215 RepoError::ConfigParseError(error) => error.into(),
RepoError::Other(error) => error.into(),
Antoine Cezar
rhg: simplify `FindRootError` handling...
r45922 }
}
}
Simon Sapin
rhg: replace `map_*_error` functions with `From` impls...
r47165
Simon Sapin
rhg: Move `Repo` object creation into `main()`...
r47335 impl<'a> From<&'a NoRepoInCwdError> for CommandError {
fn from(error: &'a NoRepoInCwdError) -> Self {
let NoRepoInCwdError { cwd } = error;
CommandError::Abort {
message: format_bytes!(
Simon Sapin
rhg: Align config file parse error formatting with Python...
r47465 b"abort: no repository found in '{}' (.hg not found)!",
Simon Sapin
rhg: Move `Repo` object creation into `main()`...
r47335 get_bytes_from_path(cwd)
),
Pulkit Goyal
rhg: add support for detailed exit code for ConfigParseError...
r47576 detailed_exit_code: exitcode::ABORT,
Simon Sapin
rhg: Move `Repo` object creation into `main()`...
r47335 }
}
}
Simon Sapin
rhg: Parse system and user configuration at program start...
r47213 impl From<ConfigError> for CommandError {
fn from(error: ConfigError) -> Self {
match error {
Simon Sapin
rhg: Parse per-repository configuration...
r47215 ConfigError::Parse(error) => error.into(),
Simon Sapin
rhg: Parse system and user configuration at program start...
r47213 ConfigError::Other(error) => error.into(),
}
}
}
Simon Sapin
rhg: Parse per-repository configuration...
r47215 impl From<ConfigParseError> for CommandError {
fn from(error: ConfigParseError) -> Self {
let ConfigParseError {
origin,
line,
Simon Sapin
rhg: Align config file parse error formatting with Python...
r47465 message,
Simon Sapin
rhg: Parse per-repository configuration...
r47215 } = error;
let line_message = if let Some(line_number) = line {
Simon Sapin
rhg: Align config file parse error formatting with Python...
r47465 format_bytes!(b":{}", line_number.to_string().into_bytes())
Simon Sapin
rhg: Parse per-repository configuration...
r47215 } else {
Vec::new()
};
CommandError::Abort {
message: format_bytes!(
Simon Sapin
rhg: Align config file parse error formatting with Python...
r47465 b"config error at {}{}: {}",
Simon Sapin
rust: Use the DisplayBytes trait in config printing...
r47249 origin,
Simon Sapin
rhg: Parse per-repository configuration...
r47215 line_message,
Simon Sapin
rhg: Align config file parse error formatting with Python...
r47465 message
Simon Sapin
rhg: Parse per-repository configuration...
r47215 ),
Pulkit Goyal
rhg: add support for detailed exit code for ConfigParseError...
r47576 detailed_exit_code: exitcode::CONFIG_ERROR_ABORT,
Simon Sapin
rhg: Parse per-repository configuration...
r47215 }
}
}
Simon Sapin
rust: remove three enums that were identical to `RevlogError`...
r47166 impl From<(RevlogError, &str)> for CommandError {
fn from((err, rev): (RevlogError, &str)) -> CommandError {
Simon Sapin
rhg: replace `map_*_error` functions with `From` impls...
r47165 match err {
Pulkit Goyal
rhg: raise wdir specific error for `hg debugdata`...
r47577 RevlogError::WDirUnsupported => CommandError::abort(
"abort: working directory revision cannot be specified",
),
Simon Sapin
rhg: Simplify CommandError based on its use...
r47174 RevlogError::InvalidRevision => CommandError::abort(format!(
Simon Sapin
rhg: Align config file parse error formatting with Python...
r47465 "abort: invalid revision identifier: {}",
Simon Sapin
rhg: Simplify CommandError based on its use...
r47174 rev
Simon Sapin
rhg: replace `map_*_error` functions with `From` impls...
r47165 )),
Simon Sapin
rhg: Simplify CommandError based on its use...
r47174 RevlogError::AmbiguousPrefix => CommandError::abort(format!(
Simon Sapin
rhg: Align config file parse error formatting with Python...
r47465 "abort: ambiguous revision identifier: {}",
Simon Sapin
rhg: Simplify CommandError based on its use...
r47174 rev
Simon Sapin
rhg: replace `map_*_error` functions with `From` impls...
r47165 )),
Simon Sapin
rhg: Simplify CommandError based on its use...
r47174 RevlogError::Other(error) => error.into(),
Simon Sapin
rhg: replace `map_*_error` functions with `From` impls...
r47165 }
}
}
Simon Sapin
rhg: Add more conversions between error types...
r47555
impl From<StatusError> for CommandError {
fn from(error: StatusError) -> Self {
CommandError::abort(format!("{}", error))
}
}
impl From<DirstateMapError> for CommandError {
fn from(error: DirstateMapError) -> Self {
CommandError::abort(format!("{}", error))
}
}
impl From<DirstateError> for CommandError {
fn from(error: DirstateError) -> Self {
match error {
DirstateError::Common(error) => error.into(),
DirstateError::Map(error) => error.into(),
}
}
}