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 @@ -1,15 +1,21 @@ use clap::App; use clap::AppSettings; +use clap::Arg; +use clap::ArgGroup; +use clap::ArgMatches; use clap::SubCommand; +use hg::operations::DebugDataKind; +use std::convert::TryFrom; mod commands; mod error; mod exitcode; mod ui; use commands::Command; +use error::CommandError; fn main() { - let mut app = App::new("rhg") + let app = App::new("rhg") .setting(AppSettings::AllowInvalidUtf8) .setting(AppSettings::SubcommandRequired) .setting(AppSettings::VersionlessSubcommands) @@ -19,6 +25,33 @@ ) .subcommand( SubCommand::with_name("files").about(commands::files::HELP_TEXT), + ) + .subcommand( + SubCommand::with_name("debugdata") + .about(commands::debugdata::HELP_TEXT) + .arg( + Arg::with_name("changelog") + .help("open changelog") + .short("-c") + .long("--changelog"), + ) + .arg( + Arg::with_name("manifest") + .help("open manifest") + .short("-m") + .long("--manifest"), + ) + .group( + ArgGroup::with_name("") + .args(&["changelog", "manifest"]) + .required(true), + ) + .arg( + Arg::with_name("rev") + .help("revision") + .required(true) + .value_name("REV"), + ), ); let matches = app.clone().get_matches_safe().unwrap_or_else(|err| { @@ -28,19 +61,7 @@ let ui = ui::Ui::new(); - let command_result = match matches.subcommand_name() { - Some(name) => match name { - "root" => commands::root::RootCommand::new().run(&ui), - "files" => commands::files::FilesCommand::new().run(&ui), - _ => std::process::exit(exitcode::UNIMPLEMENTED_COMMAND), - }, - _ => { - match app.print_help() { - Ok(_) => std::process::exit(exitcode::OK), - Err(_) => std::process::exit(exitcode::ABORT), - }; - } - }; + let command_result = match_subcommand(matches, &ui); match command_result { Ok(_) => std::process::exit(exitcode::OK), @@ -56,3 +77,43 @@ } } } + +fn match_subcommand( + matches: ArgMatches, + ui: &ui::Ui, +) -> Result<(), CommandError> { + match matches.subcommand() { + ("root", _) => commands::root::RootCommand::new().run(&ui), + ("files", _) => commands::files::FilesCommand::new().run(&ui), + ("debugdata", Some(matches)) => { + commands::debugdata::DebugDataCommand::try_from(matches)?.run(&ui) + } + _ => unreachable!(), // Because of AppSettings::SubcommandRequired, + } +} + +impl<'a> TryFrom<&'a ArgMatches<'_>> + for commands::debugdata::DebugDataCommand<'a> +{ + type Error = CommandError; + + fn try_from(args: &'a ArgMatches) -> Result { + let rev = args + .value_of("rev") + .expect("rev should be a required argument"); + let kind = match ( + args.is_present("changelog"), + args.is_present("manifest"), + ) { + (true, false) => DebugDataKind::Changelog, + (false, true) => DebugDataKind::Manifest, + (true, true) => { + unreachable!("Should not happen since options are exclusive") + } + (false, false) => { + unreachable!("Should not happen since options are required") + } + }; + Ok(commands::debugdata::DebugDataCommand::new(rev, kind)) + } +} diff --git a/tests/test-rhg.t b/tests/test-rhg.t --- a/tests/test-rhg.t +++ b/tests/test-rhg.t @@ -68,3 +68,25 @@ Listing tracked files through broken pipe $ rhg files | head -n 1 ../../../file1 + +Debuging data in inline index + $ cd $TESTTMP + $ rm -rf repository + $ hg init repository + $ cd repository + $ for i in 1 2 3; do + > echo $i >> file$i + > hg add file$i + > hg commit -m "commit $i" -q + > done + $ rhg debugdata -c 2 + e36fa63d37a576b27a69057598351db6ee5746bd + test + 0 0 + file3 + + commit 3 (no-eol) + $ rhg debugdata -m 2 + file1\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc) + file2\x005d9299349fc01ddd25d0070d149b124d8f10411e (esc) + file3\x002661d26c649684b482d10f91960cc3db683c38b4 (esc)