main.rs
177 lines
| 5.6 KiB
| application/rls-services+xml
|
RustLexer
|
r46101 | extern crate log; | ||
|
r45593 | use clap::App; | ||
use clap::AppSettings; | ||||
|
r46100 | use clap::Arg; | ||
use clap::ArgGroup; | ||||
use clap::ArgMatches; | ||||
|
r45593 | use clap::SubCommand; | ||
|
r46100 | use hg::operations::DebugDataKind; | ||
use std::convert::TryFrom; | ||||
|
r45593 | |||
|
r45515 | mod commands; | ||
mod error; | ||||
|
r45503 | mod exitcode; | ||
|
r45592 | mod ui; | ||
|
r45593 | use commands::Command; | ||
|
r46100 | use error::CommandError; | ||
|
r45503 | |||
fn main() { | ||||
|
r46101 | env_logger::init(); | ||
|
r46100 | let app = App::new("rhg") | ||
|
r45593 | .setting(AppSettings::AllowInvalidUtf8) | ||
.setting(AppSettings::SubcommandRequired) | ||||
.setting(AppSettings::VersionlessSubcommands) | ||||
.version("0.0.1") | ||||
.subcommand( | ||||
SubCommand::with_name("root").about(commands::root::HELP_TEXT), | ||||
|
r45924 | ) | ||
.subcommand( | ||||
|
r46108 | SubCommand::with_name("files") | ||
.arg( | ||||
Arg::with_name("rev") | ||||
.help("search the repository as it is in REV") | ||||
.short("-r") | ||||
.long("--revision") | ||||
.value_name("REV") | ||||
.takes_value(true), | ||||
) | ||||
.about(commands::files::HELP_TEXT), | ||||
|
r46100 | ) | ||
.subcommand( | ||||
|
r46113 | SubCommand::with_name("cat") | ||
.arg( | ||||
Arg::with_name("rev") | ||||
.help("search the repository as it is in REV") | ||||
.short("-r") | ||||
.long("--revision") | ||||
.value_name("REV") | ||||
.takes_value(true), | ||||
) | ||||
.arg( | ||||
clap::Arg::with_name("files") | ||||
.required(true) | ||||
.multiple(true) | ||||
.empty_values(false) | ||||
.value_name("FILE") | ||||
.help("Activity to start: activity@category"), | ||||
) | ||||
.about(commands::cat::HELP_TEXT), | ||||
) | ||||
.subcommand( | ||||
|
r46100 | 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"), | ||||
), | ||||
|
r45593 | ); | ||
|
r46011 | let matches = app.clone().get_matches_safe().unwrap_or_else(|err| { | ||
let _ = ui::Ui::new().writeln_stderr_str(&err.message); | ||||
|
r45593 | std::process::exit(exitcode::UNIMPLEMENTED_COMMAND) | ||
}); | ||||
|
r45920 | let ui = ui::Ui::new(); | ||
|
r46100 | let command_result = match_subcommand(matches, &ui); | ||
|
r45593 | |||
match command_result { | ||||
Ok(_) => std::process::exit(exitcode::OK), | ||||
|
r45920 | Err(e) => { | ||
let message = e.get_error_message_bytes(); | ||||
if let Some(msg) = message { | ||||
match ui.write_stderr(&msg) { | ||||
Ok(_) => (), | ||||
Err(_) => std::process::exit(exitcode::ABORT), | ||||
}; | ||||
}; | ||||
e.exit() | ||||
} | ||||
|
r45593 | } | ||
|
r45503 | } | ||
|
r46100 | |||
fn match_subcommand( | ||||
matches: ArgMatches, | ||||
ui: &ui::Ui, | ||||
) -> Result<(), CommandError> { | ||||
match matches.subcommand() { | ||||
("root", _) => commands::root::RootCommand::new().run(&ui), | ||||
|
r46108 | ("files", Some(matches)) => { | ||
commands::files::FilesCommand::try_from(matches)?.run(&ui) | ||||
} | ||||
|
r46113 | ("cat", Some(matches)) => { | ||
commands::cat::CatCommand::try_from(matches)?.run(&ui) | ||||
} | ||||
|
r46100 | ("debugdata", Some(matches)) => { | ||
commands::debugdata::DebugDataCommand::try_from(matches)?.run(&ui) | ||||
} | ||||
_ => unreachable!(), // Because of AppSettings::SubcommandRequired, | ||||
} | ||||
} | ||||
|
r46108 | impl<'a> TryFrom<&'a ArgMatches<'_>> for commands::files::FilesCommand<'a> { | ||
type Error = CommandError; | ||||
fn try_from(args: &'a ArgMatches) -> Result<Self, Self::Error> { | ||||
let rev = args.value_of("rev"); | ||||
Ok(commands::files::FilesCommand::new(rev)) | ||||
} | ||||
} | ||||
|
r46113 | impl<'a> TryFrom<&'a ArgMatches<'_>> for commands::cat::CatCommand<'a> { | ||
type Error = CommandError; | ||||
fn try_from(args: &'a ArgMatches) -> Result<Self, Self::Error> { | ||||
let rev = args.value_of("rev"); | ||||
let files = match args.values_of("files") { | ||||
Some(files) => files.collect(), | ||||
None => vec![], | ||||
}; | ||||
Ok(commands::cat::CatCommand::new(rev, files)) | ||||
} | ||||
} | ||||
|
r46100 | impl<'a> TryFrom<&'a ArgMatches<'_>> | ||
for commands::debugdata::DebugDataCommand<'a> | ||||
{ | ||||
type Error = CommandError; | ||||
fn try_from(args: &'a ArgMatches) -> Result<Self, Self::Error> { | ||||
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)) | ||||
} | ||||
} | ||||