rust/rhg/src/main.rs
changeset 46503 d8730ff51d5a
parent 46502 95d37db31479
child 46504 2e5dd18d6dc3
equal deleted inserted replaced
46502:95d37db31479 46503:d8730ff51d5a
     1 extern crate log;
     1 extern crate log;
     2 use clap::App;
     2 use clap::App;
     3 use clap::AppSettings;
     3 use clap::AppSettings;
       
     4 use clap::Arg;
     4 use clap::ArgMatches;
     5 use clap::ArgMatches;
     5 use format_bytes::format_bytes;
     6 use format_bytes::format_bytes;
       
     7 use std::path::Path;
     6 
     8 
     7 mod error;
     9 mod error;
     8 mod exitcode;
    10 mod exitcode;
     9 mod ui;
    11 mod ui;
    10 use error::CommandError;
    12 use error::CommandError;
       
    13 
       
    14 fn add_global_args<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
       
    15     app.arg(
       
    16         Arg::with_name("repository")
       
    17             .help("repository root directory")
       
    18             .short("-R")
       
    19             .long("--repository")
       
    20             .value_name("REPO")
       
    21             .takes_value(true),
       
    22     )
       
    23 }
    11 
    24 
    12 fn main() {
    25 fn main() {
    13     env_logger::init();
    26     env_logger::init();
    14     let app = App::new("rhg")
    27     let app = App::new("rhg")
    15         .setting(AppSettings::AllowInvalidUtf8)
    28         .setting(AppSettings::AllowInvalidUtf8)
    16         .setting(AppSettings::SubcommandRequired)
    29         .setting(AppSettings::SubcommandRequired)
    17         .setting(AppSettings::VersionlessSubcommands)
    30         .setting(AppSettings::VersionlessSubcommands)
    18         .version("0.0.1");
    31         .version("0.0.1");
       
    32     let app = add_global_args(app);
    19     let app = add_subcommand_args(app);
    33     let app = add_subcommand_args(app);
    20 
    34 
    21     let ui = ui::Ui::new();
    35     let ui = ui::Ui::new();
    22 
    36 
    23     let matches = app.clone().get_matches_safe().unwrap_or_else(|err| {
    37     let matches = app.clone().get_matches_safe().unwrap_or_else(|err| {
    24         let _ = ui.writeln_stderr_str(&err.message);
    38         let _ = ui.writeln_stderr_str(&err.message);
    25         std::process::exit(exitcode::UNIMPLEMENTED)
    39         std::process::exit(exitcode::UNIMPLEMENTED)
    26     });
    40     });
       
    41 
    27     let (subcommand_name, subcommand_matches) = matches.subcommand();
    42     let (subcommand_name, subcommand_matches) = matches.subcommand();
    28     let run = subcommand_run_fn(subcommand_name)
    43     let run = subcommand_run_fn(subcommand_name)
    29         .expect("unknown subcommand name from clap despite AppSettings::SubcommandRequired");
    44         .expect("unknown subcommand name from clap despite AppSettings::SubcommandRequired");
    30     let args = subcommand_matches
    45     let args = subcommand_matches
    31         .expect("no subcommand arguments from clap despite AppSettings::SubcommandRequired");
    46         .expect("no subcommand arguments from clap despite AppSettings::SubcommandRequired");
    32 
    47 
       
    48     // Global arguments can be in either based on e.g. `hg -R ./foo log` v.s.
       
    49     // `hg log -R ./foo`
       
    50     let global_arg =
       
    51         |name| args.value_of_os(name).or_else(|| matches.value_of_os(name));
       
    52 
       
    53     let repo_path = global_arg("repository").map(Path::new);
    33     let result = (|| -> Result<(), CommandError> {
    54     let result = (|| -> Result<(), CommandError> {
    34         let config = hg::config::Config::load()?;
    55         let config = hg::config::Config::load()?;
    35         run(&ui, &config, args)
    56         run(&ui, &config, repo_path, args)
    36     })();
    57     })();
    37 
    58 
    38     let exit_code = match result {
    59     let exit_code = match result {
    39         Ok(_) => exitcode::OK,
    60         Ok(_) => exitcode::OK,
    40 
    61 
    64         }
    85         }
    65 
    86 
    66         fn add_subcommand_args<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
    87         fn add_subcommand_args<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> {
    67             app
    88             app
    68             $(
    89             $(
    69                 .subcommand(commands::$command::args())
    90                 .subcommand(add_global_args(commands::$command::args()))
    70             )+
    91             )+
    71         }
    92         }
    72 
    93 
    73         fn subcommand_run_fn(name: &str) -> Option<fn(
    94         fn subcommand_run_fn(name: &str) -> Option<fn(
    74             &ui::Ui,
    95             &ui::Ui,
    75             &hg::config::Config,
    96             &hg::config::Config,
       
    97             Option<&Path>,
    76             &ArgMatches,
    98             &ArgMatches,
    77         ) -> Result<(), CommandError>> {
    99         ) -> Result<(), CommandError>> {
    78             match name {
   100             match name {
    79                 $(
   101                 $(
    80                     stringify!($command) => Some(commands::$command::run),
   102                     stringify!($command) => Some(commands::$command::run),