# HG changeset patch # User Simon Sapin # Date 1606227118 -3600 # Node ID ead435aa5294160ece2b61f835a52a3e33bd7122 # Parent 37bcd7f5a543ae3e8c7be759034e3bdfb0bd024b rhg: add a `debugrequirements` subcommand For now it only prints the contents of `.hg/requires` as-is, without parsing. Differential Revision: https://phab.mercurial-scm.org/D9397 diff -r 37bcd7f5a543 -r ead435aa5294 rust/rhg/src/commands.rs --- a/rust/rhg/src/commands.rs Wed Nov 25 11:08:28 2020 -0500 +++ b/rust/rhg/src/commands.rs Tue Nov 24 15:11:58 2020 +0100 @@ -1,5 +1,6 @@ pub mod cat; pub mod debugdata; +pub mod debugrequirements; pub mod files; pub mod root; use crate::error::CommandError; diff -r 37bcd7f5a543 -r ead435aa5294 rust/rhg/src/commands/debugrequirements.rs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rust/rhg/src/commands/debugrequirements.rs Tue Nov 24 15:11:58 2020 +0100 @@ -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 -r 37bcd7f5a543 -r ead435aa5294 rust/rhg/src/error.rs --- a/rust/rhg/src/error.rs Wed Nov 25 11:08:28 2020 -0500 +++ b/rust/rhg/src/error.rs Tue Nov 24 15:11:58 2020 +0100 @@ -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 -r 37bcd7f5a543 -r ead435aa5294 rust/rhg/src/main.rs --- a/rust/rhg/src/main.rs Wed Nov 25 11:08:28 2020 -0500 +++ b/rust/rhg/src/main.rs Tue Nov 24 15:11:58 2020 +0100 @@ -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 -r 37bcd7f5a543 -r ead435aa5294 tests/test-rhg.t --- a/tests/test-rhg.t Wed Nov 25 11:08:28 2020 -0500 +++ b/tests/test-rhg.t Tue Nov 24 15:11:58 2020 +0100 @@ -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