Mercurial > hg-stable
annotate rust/rhg/src/main.rs @ 46647:4e4c70401028
rhg: Use clap’s support for global CLI arguments
By default, clap only accepts app-level arguments (as opposed to sub-command
level) to be specified before a sub-command: `rhg -R ./foo log`. Specifying
them after would be rejected: `rhg log -R ./foo`.
Previously we worked around that by registering global arguments both
at the app level and on each sub-command, but that required looking
for their value in two places. It turns out that Clap has built-in support
for what we want to do, so let’s use it.
Also, Clap "settings" turn out to be either global or not too.
Let’s make `AllowInvalidUtf8` apply to sub-commands too.
Differential Revision: https://phab.mercurial-scm.org/D10080
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Fri, 26 Feb 2021 12:16:43 +0100 |
parents | 755c31a1caf9 |
children | 7284b524b441 |
rev | line source |
---|---|
45536
b1cea0dc9db0
rhg: Add debug timing
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45535
diff
changeset
|
1 extern crate log; |
46631
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
2 use crate::ui::Ui; |
45051
18f8d3b31baa
rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45050
diff
changeset
|
3 use clap::App; |
18f8d3b31baa
rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45050
diff
changeset
|
4 use clap::AppSettings; |
46555
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46554
diff
changeset
|
5 use clap::Arg; |
45535
f17caf8f3fef
rhg: add a limited `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45451
diff
changeset
|
6 use clap::ArgMatches; |
46513
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
45938
diff
changeset
|
7 use format_bytes::format_bytes; |
46631
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
8 use hg::config::Config; |
46632
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
9 use hg::repo::{Repo, RepoError}; |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
10 use std::path::{Path, PathBuf}; |
45051
18f8d3b31baa
rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45050
diff
changeset
|
11 |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
12 mod blackbox; |
45002
bacf6c7ef01b
rhg: add Command trait for subcommands implemented by rhg
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45001
diff
changeset
|
13 mod error; |
45001 | 14 mod exitcode; |
45050
513b3ef277a3
rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45002
diff
changeset
|
15 mod ui; |
45535
f17caf8f3fef
rhg: add a limited `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45451
diff
changeset
|
16 use error::CommandError; |
45001 | 17 |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
18 fn main_with_result( |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
19 ui: &ui::Ui, |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
20 process_start_time: &blackbox::ProcessStartTime, |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
21 ) -> Result<(), CommandError> { |
45536
b1cea0dc9db0
rhg: Add debug timing
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45535
diff
changeset
|
22 env_logger::init(); |
45535
f17caf8f3fef
rhg: add a limited `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45451
diff
changeset
|
23 let app = App::new("rhg") |
46647
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
24 .global_setting(AppSettings::AllowInvalidUtf8) |
45051
18f8d3b31baa
rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45050
diff
changeset
|
25 .setting(AppSettings::SubcommandRequired) |
18f8d3b31baa
rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45050
diff
changeset
|
26 .setting(AppSettings::VersionlessSubcommands) |
46647
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
27 .arg( |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
28 Arg::with_name("repository") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
29 .help("repository root directory") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
30 .short("-R") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
31 .long("--repository") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
32 .value_name("REPO") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
33 .takes_value(true) |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
34 // Both ok: `hg -R ./foo log` or `hg log -R ./foo` |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
35 .global(true), |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
36 ) |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
37 .arg( |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
38 Arg::with_name("config") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
39 .help("set/override config option (use 'section.name=value')") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
40 .long("--config") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
41 .value_name("CONFIG") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
42 .takes_value(true) |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
43 .global(true) |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
44 // Ok: `--config section.key1=val --config section.key2=val2` |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
45 .multiple(true) |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
46 // Not ok: `--config section.key1=val section.key2=val2` |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
47 .number_of_values(1), |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
48 ) |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
49 .version("0.0.1"); |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
50 let app = add_subcommand_args(app); |
45051
18f8d3b31baa
rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45050
diff
changeset
|
51 |
46630
21d3b40b4c0e
rhg: Remove error message on unsupported CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46557
diff
changeset
|
52 let matches = app.clone().get_matches_safe()?; |
46555
d8730ff51d5a
rhg: Add support for -R and --repository command-line arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46554
diff
changeset
|
53 |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
54 let (subcommand_name, subcommand_matches) = matches.subcommand(); |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
55 let run = subcommand_run_fn(subcommand_name) |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
56 .expect("unknown subcommand name from clap despite AppSettings::SubcommandRequired"); |
46631
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
57 let subcommand_args = subcommand_matches |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
58 .expect("no subcommand arguments from clap despite AppSettings::SubcommandRequired"); |
45051
18f8d3b31baa
rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45050
diff
changeset
|
59 |
46647
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
60 let config_args = matches |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
61 .values_of_os("config") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
62 // Turn `Option::None` into an empty iterator: |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
63 .into_iter() |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
64 .flatten() |
46635
d2e61f00ee9d
rust: Introduce a get_bytes_from_os_str utility function
Simon Sapin <simon.sapin@octobus.net>
parents:
46632
diff
changeset
|
65 .map(hg::utils::files::get_bytes_from_os_str); |
46631
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
66 let non_repo_config = &hg::config::Config::load(config_args)?; |
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
67 |
46647
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
68 let repo_path = matches.value_of_os("repository").map(Path::new); |
46632
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
69 let repo = match Repo::find(non_repo_config, repo_path) { |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
70 Ok(repo) => Ok(repo), |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
71 Err(RepoError::NotFound { at }) if repo_path.is_none() => { |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
72 // Not finding a repo is not fatal yet, if `-R` was not given |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
73 Err(NoRepoInCwdError { cwd: at }) |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
74 } |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
75 Err(error) => return Err(error.into()), |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
76 }; |
46631
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
77 |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
78 let invocation = CliInvocation { |
46631
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
79 ui, |
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
80 subcommand_args, |
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
81 non_repo_config, |
46632
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
82 repo: repo.as_ref(), |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
83 }; |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
84 let blackbox = blackbox::Blackbox::new(&invocation, process_start_time)?; |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
85 blackbox.log_command_start(); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
86 let result = run(&invocation); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
87 blackbox.log_command_end(exit_code(&result)); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
88 result |
46630
21d3b40b4c0e
rhg: Remove error message on unsupported CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46557
diff
changeset
|
89 } |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
90 |
46630
21d3b40b4c0e
rhg: Remove error message on unsupported CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46557
diff
changeset
|
91 fn main() { |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
92 // Run this first, before we find out if the blackbox extension is even |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
93 // enabled, in order to include everything in-between in the duration |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
94 // measurements. Reading config files can be slow if they’re on NFS. |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
95 let process_start_time = blackbox::ProcessStartTime::now(); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
96 |
46632
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
97 let ui = ui::Ui::new(); |
46630
21d3b40b4c0e
rhg: Remove error message on unsupported CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46557
diff
changeset
|
98 |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
99 let result = main_with_result(&ui, &process_start_time); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
100 if let Err(CommandError::Abort { message }) = &result { |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
101 if !message.is_empty() { |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
102 // Ignore errors when writing to stderr, we’re already exiting |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
103 // with failure code so there’s not much more we can do. |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
104 let _ = ui.write_stderr(&format_bytes!(b"abort: {}\n", message)); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
105 } |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
106 } |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
107 std::process::exit(exit_code(&result)) |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
108 } |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
109 |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
110 fn exit_code(result: &Result<(), CommandError>) -> i32 { |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
111 match result { |
46630
21d3b40b4c0e
rhg: Remove error message on unsupported CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46557
diff
changeset
|
112 Ok(()) => exitcode::OK, |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
113 Err(CommandError::Abort { .. }) => exitcode::ABORT, |
46513
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
45938
diff
changeset
|
114 |
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
45938
diff
changeset
|
115 // Exit with a specific code and no error message to let a potential |
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
45938
diff
changeset
|
116 // wrapper script fallback to Python-based Mercurial. |
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
45938
diff
changeset
|
117 Err(CommandError::Unimplemented) => exitcode::UNIMPLEMENTED, |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
118 } |
45001 | 119 } |
45535
f17caf8f3fef
rhg: add a limited `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45451
diff
changeset
|
120 |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
121 macro_rules! subcommands { |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
122 ($( $command: ident )+) => { |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
123 mod commands { |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
124 $( |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
125 pub mod $command; |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
126 )+ |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
127 } |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
128 |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
129 fn add_subcommand_args<'a, 'b>(app: App<'a, 'b>) -> App<'a, 'b> { |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
130 app |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
131 $( |
46647
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
132 .subcommand(commands::$command::args()) |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
133 )+ |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
134 } |
46543
a6e4e4650bac
rhg: Parse system and user configuration at program start
Simon Sapin <simon.sapin@octobus.net>
parents:
46513
diff
changeset
|
135 |
46631
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
136 pub type RunFn = fn(&CliInvocation) -> Result<(), CommandError>; |
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
137 |
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
138 fn subcommand_run_fn(name: &str) -> Option<RunFn> { |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
139 match name { |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
140 $( |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
141 stringify!($command) => Some(commands::$command::run), |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
142 )+ |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
143 _ => None, |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
144 } |
45548
33ded2d3f4fc
rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45543
diff
changeset
|
145 } |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
146 }; |
45535
f17caf8f3fef
rhg: add a limited `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45451
diff
changeset
|
147 } |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
148 |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
149 subcommands! { |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
150 cat |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
151 debugdata |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
152 debugrequirements |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
153 files |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
154 root |
46557
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46556
diff
changeset
|
155 config |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
156 } |
46631
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
157 pub struct CliInvocation<'a> { |
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
158 ui: &'a Ui, |
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
159 subcommand_args: &'a ArgMatches<'a>, |
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
160 non_repo_config: &'a Config, |
46632
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
161 /// References inside `Result` is a bit peculiar but allow |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
162 /// `invocation.repo?` to work out with `&CliInvocation` since this |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
163 /// `Result` type is `Copy`. |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
164 repo: Result<&'a Repo, &'a NoRepoInCwdError>, |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
165 } |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
166 |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
167 struct NoRepoInCwdError { |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
168 cwd: PathBuf, |
46631
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
169 } |
46632
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
170 |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
171 impl CliInvocation<'_> { |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
172 fn config(&self) -> &Config { |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
173 if let Ok(repo) = self.repo { |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
174 repo.config() |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
175 } else { |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
176 self.non_repo_config |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
177 } |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
178 } |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
179 } |