diff --git a/rust/rhg/src/commands.rs b/rust/rhg/src/commands.rs --- a/rust/rhg/src/commands.rs +++ b/rust/rhg/src/commands.rs @@ -1,5 +1,6 @@ pub mod cat; pub mod debugdata; +pub mod debugrequirements; pub mod files; pub mod root; use crate::error::CommandError; diff --git a/rust/rhg/src/commands/debugrequirements.rs b/rust/rhg/src/commands/debugrequirements.rs new file mode 100644 --- /dev/null +++ b/rust/rhg/src/commands/debugrequirements.rs @@ -0,0 +1,40 @@ +use crate::commands::Command; +use crate::error::{CommandError, CommandErrorKind}; +use crate::ui::Ui; +use hg::operations::FindRoot; + +pub const HELP_TEXT: &str = " +Print the current repo requirements. +"; + +pub struct DebugRequirementsCommand {} + +impl DebugRequirementsCommand { + pub fn new() -> Self { + DebugRequirementsCommand {} + } +} + +impl Command for DebugRequirementsCommand { + fn run(&self, ui: &Ui) -> Result<(), CommandError> { + let root = FindRoot::new().run()?; + let requires = root.join(".hg").join("requires"); + let requirements = match std::fs::read(requires) { + Ok(bytes) => bytes, + + // Treat a missing file the same as an empty file. + // From `mercurial/localrepo.py`: + // > requires file contains a newline-delimited list of + // > features/capabilities the opener (us) must have in order to use + // > 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 => Vec::new(), + + Err(error) => Err(CommandErrorKind::FileError(error))?, + }; + + ui.write_stdout(&requirements)?; + Ok(()) + } +} diff --git a/rust/rhg/src/error.rs b/rust/rhg/src/error.rs --- a/rust/rhg/src/error.rs +++ b/rust/rhg/src/error.rs @@ -12,6 +12,9 @@ RootNotFound(PathBuf), /// The current directory cannot be found CurrentDirNotFound(std::io::Error), + /// Error while reading or writing a file + // TODO: add the file name/path? + FileError(std::io::Error), /// The standard output stream cannot be written to StdoutError, /// The standard error stream cannot be written to @@ -27,6 +30,7 @@ match self { CommandErrorKind::RootNotFound(_) => exitcode::ABORT, CommandErrorKind::CurrentDirNotFound(_) => exitcode::ABORT, + CommandErrorKind::FileError(_) => exitcode::ABORT, CommandErrorKind::StdoutError => exitcode::ABORT, CommandErrorKind::StderrError => exitcode::ABORT, CommandErrorKind::Abort(_) => exitcode::ABORT, diff --git a/rust/rhg/src/main.rs b/rust/rhg/src/main.rs --- a/rust/rhg/src/main.rs +++ b/rust/rhg/src/main.rs @@ -83,6 +83,10 @@ .required(true) .value_name("REV"), ), + ) + .subcommand( + SubCommand::with_name("debugrequirements") + .about(commands::debugrequirements::HELP_TEXT), ); let matches = app.clone().get_matches_safe().unwrap_or_else(|err| { @@ -124,6 +128,10 @@ ("debugdata", Some(matches)) => { commands::debugdata::DebugDataCommand::try_from(matches)?.run(&ui) } + ("debugrequirements", _) => { + commands::debugrequirements::DebugRequirementsCommand::new() + .run(&ui) + } _ => unreachable!(), // Because of AppSettings::SubcommandRequired, } } diff --git a/tests/test-rhg.t b/tests/test-rhg.t --- a/tests/test-rhg.t +++ b/tests/test-rhg.t @@ -115,3 +115,12 @@ $ hg commit -m "add copy of original" $ rhg cat -r 1 copy_of_original original content + +Requirements + $ rhg debugrequirements + dotencode + fncache + generaldelta + revlogv1 + sparserevlog + store