Mercurial > hg-stable
annotate rust/rhg/src/main.rs @ 46704:7284b524b441
rhg: Make configuration available as early as possible in main()
Differential Revision: https://phab.mercurial-scm.org/D10090
author | Simon Sapin <simon.sapin@octobus.net> |
---|---|
date | Mon, 01 Mar 2021 13:51:35 +0100 |
parents | 4e4c70401028 |
children | 33f2d56acc73 |
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}; |
46704
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
10 use hg::utils::files::{get_bytes_from_os_str, get_path_from_bytes}; |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
11 use hg::utils::SliceExt; |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
12 use std::ffi::OsString; |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
13 use std::path::PathBuf; |
45051
18f8d3b31baa
rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45050
diff
changeset
|
14 |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
15 mod blackbox; |
45002
bacf6c7ef01b
rhg: add Command trait for subcommands implemented by rhg
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45001
diff
changeset
|
16 mod error; |
45001 | 17 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
|
18 mod ui; |
45535
f17caf8f3fef
rhg: add a limited `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45451
diff
changeset
|
19 use error::CommandError; |
45001 | 20 |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
21 fn main_with_result( |
46704
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
22 process_start_time: &blackbox::ProcessStartTime, |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
23 ui: &ui::Ui, |
46704
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
24 repo: Result<&Repo, &NoRepoInCwdError>, |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
25 config: &Config, |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
26 ) -> Result<(), CommandError> { |
45535
f17caf8f3fef
rhg: add a limited `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45451
diff
changeset
|
27 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
|
28 .global_setting(AppSettings::AllowInvalidUtf8) |
45051
18f8d3b31baa
rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45050
diff
changeset
|
29 .setting(AppSettings::SubcommandRequired) |
18f8d3b31baa
rhg: add a limited `rhg root` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45050
diff
changeset
|
30 .setting(AppSettings::VersionlessSubcommands) |
46647
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
31 .arg( |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
32 Arg::with_name("repository") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
33 .help("repository root directory") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
34 .short("-R") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
35 .long("--repository") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
36 .value_name("REPO") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
37 .takes_value(true) |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
38 // 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
|
39 .global(true), |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
40 ) |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
41 .arg( |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
42 Arg::with_name("config") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
43 .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
|
44 .long("--config") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
45 .value_name("CONFIG") |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
46 .takes_value(true) |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
47 .global(true) |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
48 // 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
|
49 .multiple(true) |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
50 // 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
|
51 .number_of_values(1), |
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
52 ) |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
53 .version("0.0.1"); |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
54 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
|
55 |
46630
21d3b40b4c0e
rhg: Remove error message on unsupported CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46557
diff
changeset
|
56 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
|
57 |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
58 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
|
59 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
|
60 .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
|
61 let subcommand_args = subcommand_matches |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
62 .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
|
63 |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
64 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
|
65 ui, |
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
66 subcommand_args, |
46704
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
67 config, |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
68 repo, |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
69 }; |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
70 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
|
71 blackbox.log_command_start(); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
72 let result = run(&invocation); |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
73 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
|
74 result |
46630
21d3b40b4c0e
rhg: Remove error message on unsupported CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46557
diff
changeset
|
75 } |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
76 |
46630
21d3b40b4c0e
rhg: Remove error message on unsupported CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46557
diff
changeset
|
77 fn main() { |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
78 // 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
|
79 // 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
|
80 // 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
|
81 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
|
82 |
46704
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
83 env_logger::init(); |
46632
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
84 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
|
85 |
46704
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
86 let early_args = EarlyArgs::parse(std::env::args_os()); |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
87 let non_repo_config = Config::load(early_args.config) |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
88 .unwrap_or_else(|error| exit(&ui, Err(error.into()))); |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
89 |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
90 let repo_path = early_args.repo.as_deref().map(get_path_from_bytes); |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
91 let repo_result = match Repo::find(&non_repo_config, repo_path) { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
92 Ok(repo) => Ok(repo), |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
93 Err(RepoError::NotFound { at }) if repo_path.is_none() => { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
94 // Not finding a repo is not fatal yet, if `-R` was not given |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
95 Err(NoRepoInCwdError { cwd: at }) |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
96 } |
46704
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
97 Err(error) => exit(&ui, Err(error.into())), |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
98 }; |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
99 |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
100 let config = if let Ok(repo) = &repo_result { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
101 repo.config() |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
102 } else { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
103 &non_repo_config |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
104 }; |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
105 |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
106 let result = main_with_result( |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
107 &process_start_time, |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
108 &ui, |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
109 repo_result.as_ref(), |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
110 config, |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
111 ); |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
112 exit(&ui, result) |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
113 } |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
114 |
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
115 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
|
116 match result { |
46630
21d3b40b4c0e
rhg: Remove error message on unsupported CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46557
diff
changeset
|
117 Ok(()) => exitcode::OK, |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
118 Err(CommandError::Abort { .. }) => exitcode::ABORT, |
46513
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
45938
diff
changeset
|
119 |
ca3f73cc3cf4
rhg: Simplify CommandError based on its use
Simon Sapin <simon.sapin@octobus.net>
parents:
45938
diff
changeset
|
120 // 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
|
121 // 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
|
122 Err(CommandError::Unimplemented) => exitcode::UNIMPLEMENTED, |
46640
755c31a1caf9
rhg: Add support for the blackbox extension
Simon Sapin <simon.sapin@octobus.net>
parents:
46635
diff
changeset
|
123 } |
45001 | 124 } |
45535
f17caf8f3fef
rhg: add a limited `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45451
diff
changeset
|
125 |
46704
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
126 fn exit(ui: &Ui, result: Result<(), CommandError>) -> ! { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
127 if let Err(CommandError::Abort { message }) = &result { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
128 if !message.is_empty() { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
129 // Ignore errors when writing to stderr, we’re already exiting |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
130 // with failure code so there’s not much more we can do. |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
131 let _ = ui.write_stderr(&format_bytes!(b"abort: {}\n", message)); |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
132 } |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
133 } |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
134 std::process::exit(exit_code(&result)) |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
135 } |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
136 |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
137 macro_rules! subcommands { |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
138 ($( $command: ident )+) => { |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
139 mod commands { |
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 pub mod $command; |
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 } |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
144 |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
145 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
|
146 app |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
147 $( |
46647
4e4c70401028
rhg: Use clap’s support for global CLI arguments
Simon Sapin <simon.sapin@octobus.net>
parents:
46640
diff
changeset
|
148 .subcommand(commands::$command::args()) |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
149 )+ |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
150 } |
46543
a6e4e4650bac
rhg: Parse system and user configuration at program start
Simon Sapin <simon.sapin@octobus.net>
parents:
46513
diff
changeset
|
151 |
46631
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
152 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
|
153 |
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
154 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
|
155 match name { |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
156 $( |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
157 stringify!($command) => Some(commands::$command::run), |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
158 )+ |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
159 _ => None, |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
160 } |
45548
33ded2d3f4fc
rhg: add a limited `rhg cat -r` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45543
diff
changeset
|
161 } |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
162 }; |
45535
f17caf8f3fef
rhg: add a limited `rhg debugdata` subcommand
Antoine Cezar <antoine.cezar@octobus.net>
parents:
45451
diff
changeset
|
163 } |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
164 |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
165 subcommands! { |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
166 cat |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
167 debugdata |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
168 debugrequirements |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
169 files |
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
170 root |
46557
a25033eb43b5
rhg: add limited support for the `config` sub-command
Simon Sapin <simon.sapin@octobus.net>
parents:
46556
diff
changeset
|
171 config |
46554
95d37db31479
rhg: Replace subcommand boilerplate with a macro
Simon Sapin <simon.sapin@octobus.net>
parents:
46553
diff
changeset
|
172 } |
46631
80840b651721
rhg: Group values passed to every sub-command into a struct
Simon Sapin <simon.sapin@octobus.net>
parents:
46630
diff
changeset
|
173 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
|
174 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
|
175 subcommand_args: &'a ArgMatches<'a>, |
46704
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
176 config: &'a Config, |
46632
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
177 /// 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
|
178 /// `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
|
179 /// `Result` type is `Copy`. |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
180 repo: Result<&'a Repo, &'a NoRepoInCwdError>, |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
181 } |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
182 |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
183 struct NoRepoInCwdError { |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
184 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
|
185 } |
46632
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
186 |
46704
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
187 /// CLI arguments to be parsed "early" in order to be able to read |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
188 /// configuration before using Clap. Ideally we would also use Clap for this, |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
189 /// see <https://github.com/clap-rs/clap/discussions/2366>. |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
190 /// |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
191 /// These arguments are still declared when we do use Clap later, so that Clap |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
192 /// does not return an error for their presence. |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
193 struct EarlyArgs { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
194 /// Values of all `--config` arguments. (Possibly none) |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
195 config: Vec<Vec<u8>>, |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
196 /// Value of the `-R` or `--repository` argument, if any. |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
197 repo: Option<Vec<u8>>, |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
198 } |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
199 |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
200 impl EarlyArgs { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
201 fn parse(args: impl IntoIterator<Item = OsString>) -> Self { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
202 let mut args = args.into_iter().map(get_bytes_from_os_str); |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
203 let mut config = Vec::new(); |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
204 let mut repo = None; |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
205 // Use `while let` instead of `for` so that we can also call |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
206 // `args.next()` inside the loop. |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
207 while let Some(arg) = args.next() { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
208 if arg == b"--config" { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
209 if let Some(value) = args.next() { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
210 config.push(value) |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
211 } |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
212 } else if let Some(value) = arg.drop_prefix(b"--config=") { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
213 config.push(value.to_owned()) |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
214 } |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
215 |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
216 if arg == b"--repository" || arg == b"-R" { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
217 if let Some(value) = args.next() { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
218 repo = Some(value) |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
219 } |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
220 } else if let Some(value) = arg.drop_prefix(b"--repository=") { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
221 repo = Some(value.to_owned()) |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
222 } else if let Some(value) = arg.drop_prefix(b"-R") { |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
223 repo = Some(value.to_owned()) |
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
224 } |
46632
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
225 } |
46704
7284b524b441
rhg: Make configuration available as early as possible in main()
Simon Sapin <simon.sapin@octobus.net>
parents:
46647
diff
changeset
|
226 Self { config, repo } |
46632
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
227 } |
5ce2aa7c2ad5
rhg: Move `Repo` object creation into `main()`
Simon Sapin <simon.sapin@octobus.net>
parents:
46631
diff
changeset
|
228 } |