Show More
@@ -1,51 +1,73 b'' | |||||
1 | use crate::error::CommandError; |
|
1 | use crate::error::CommandError; | |
2 | use crate::ui::Ui; |
|
2 | use crate::ui::Ui; | |
|
3 | use clap::Arg; | |||
3 | use clap::ArgMatches; |
|
4 | use clap::ArgMatches; | |
4 | use hg::config::Config; |
|
5 | use hg::config::Config; | |
5 | use hg::operations::cat; |
|
6 | use hg::operations::cat; | |
6 | use hg::repo::Repo; |
|
7 | use hg::repo::Repo; | |
7 | use hg::utils::hg_path::HgPathBuf; |
|
8 | use hg::utils::hg_path::HgPathBuf; | |
8 | use micro_timer::timed; |
|
9 | use micro_timer::timed; | |
9 | use std::convert::TryFrom; |
|
10 | use std::convert::TryFrom; | |
10 |
|
11 | |||
11 | pub const HELP_TEXT: &str = " |
|
12 | pub const HELP_TEXT: &str = " | |
12 | Output the current or given revision of files |
|
13 | Output the current or given revision of files | |
13 | "; |
|
14 | "; | |
14 |
|
15 | |||
|
16 | pub fn args() -> clap::App<'static, 'static> { | |||
|
17 | clap::SubCommand::with_name("cat") | |||
|
18 | .arg( | |||
|
19 | Arg::with_name("rev") | |||
|
20 | .help("search the repository as it is in REV") | |||
|
21 | .short("-r") | |||
|
22 | .long("--revision") | |||
|
23 | .value_name("REV") | |||
|
24 | .takes_value(true), | |||
|
25 | ) | |||
|
26 | .arg( | |||
|
27 | clap::Arg::with_name("files") | |||
|
28 | .required(true) | |||
|
29 | .multiple(true) | |||
|
30 | .empty_values(false) | |||
|
31 | .value_name("FILE") | |||
|
32 | .help("Activity to start: activity@category"), | |||
|
33 | ) | |||
|
34 | .about(HELP_TEXT) | |||
|
35 | } | |||
|
36 | ||||
15 | #[timed] |
|
37 | #[timed] | |
16 | pub fn run( |
|
38 | pub fn run( | |
17 | ui: &Ui, |
|
39 | ui: &Ui, | |
18 | config: &Config, |
|
40 | config: &Config, | |
19 | args: &ArgMatches, |
|
41 | args: &ArgMatches, | |
20 | ) -> Result<(), CommandError> { |
|
42 | ) -> Result<(), CommandError> { | |
21 | let rev = args.value_of("rev"); |
|
43 | let rev = args.value_of("rev"); | |
22 | let file_args = match args.values_of("files") { |
|
44 | let file_args = match args.values_of("files") { | |
23 | Some(files) => files.collect(), |
|
45 | Some(files) => files.collect(), | |
24 | None => vec![], |
|
46 | None => vec![], | |
25 | }; |
|
47 | }; | |
26 |
|
48 | |||
27 | let repo = Repo::find(config)?; |
|
49 | let repo = Repo::find(config)?; | |
28 | let cwd = hg::utils::current_dir()?; |
|
50 | let cwd = hg::utils::current_dir()?; | |
29 |
|
51 | |||
30 | let mut files = vec![]; |
|
52 | let mut files = vec![]; | |
31 | for file in file_args.iter() { |
|
53 | for file in file_args.iter() { | |
32 | // TODO: actually normalize `..` path segments etc? |
|
54 | // TODO: actually normalize `..` path segments etc? | |
33 | let normalized = cwd.join(&file); |
|
55 | let normalized = cwd.join(&file); | |
34 | let stripped = normalized |
|
56 | let stripped = normalized | |
35 | .strip_prefix(&repo.working_directory_path()) |
|
57 | .strip_prefix(&repo.working_directory_path()) | |
36 | // TODO: error message for path arguments outside of the repo |
|
58 | // TODO: error message for path arguments outside of the repo | |
37 | .map_err(|_| CommandError::abort(""))?; |
|
59 | .map_err(|_| CommandError::abort(""))?; | |
38 | let hg_file = HgPathBuf::try_from(stripped.to_path_buf()) |
|
60 | let hg_file = HgPathBuf::try_from(stripped.to_path_buf()) | |
39 | .map_err(|e| CommandError::abort(e.to_string()))?; |
|
61 | .map_err(|e| CommandError::abort(e.to_string()))?; | |
40 | files.push(hg_file); |
|
62 | files.push(hg_file); | |
41 | } |
|
63 | } | |
42 |
|
64 | |||
43 | match rev { |
|
65 | match rev { | |
44 | Some(rev) => { |
|
66 | Some(rev) => { | |
45 | let data = cat(&repo, rev, &files).map_err(|e| (e, rev))?; |
|
67 | let data = cat(&repo, rev, &files).map_err(|e| (e, rev))?; | |
46 | ui.write_stdout(&data)?; |
|
68 | ui.write_stdout(&data)?; | |
47 | Ok(()) |
|
69 | Ok(()) | |
48 | } |
|
70 | } | |
49 | None => Err(CommandError::Unimplemented.into()), |
|
71 | None => Err(CommandError::Unimplemented.into()), | |
50 | } |
|
72 | } | |
51 | } |
|
73 | } |
@@ -1,42 +1,72 b'' | |||||
1 | use crate::error::CommandError; |
|
1 | use crate::error::CommandError; | |
2 | use crate::ui::Ui; |
|
2 | use crate::ui::Ui; | |
|
3 | use clap::Arg; | |||
|
4 | use clap::ArgGroup; | |||
3 | use clap::ArgMatches; |
|
5 | use clap::ArgMatches; | |
4 | use hg::config::Config; |
|
6 | use hg::config::Config; | |
5 | use hg::operations::{debug_data, DebugDataKind}; |
|
7 | use hg::operations::{debug_data, DebugDataKind}; | |
6 | use hg::repo::Repo; |
|
8 | use hg::repo::Repo; | |
7 | use micro_timer::timed; |
|
9 | use micro_timer::timed; | |
8 |
|
10 | |||
9 | pub const HELP_TEXT: &str = " |
|
11 | pub const HELP_TEXT: &str = " | |
10 | Dump the contents of a data file revision |
|
12 | Dump the contents of a data file revision | |
11 | "; |
|
13 | "; | |
12 |
|
14 | |||
|
15 | pub fn args() -> clap::App<'static, 'static> { | |||
|
16 | clap::SubCommand::with_name("debugdata") | |||
|
17 | .arg( | |||
|
18 | Arg::with_name("changelog") | |||
|
19 | .help("open changelog") | |||
|
20 | .short("-c") | |||
|
21 | .long("--changelog"), | |||
|
22 | ) | |||
|
23 | .arg( | |||
|
24 | Arg::with_name("manifest") | |||
|
25 | .help("open manifest") | |||
|
26 | .short("-m") | |||
|
27 | .long("--manifest"), | |||
|
28 | ) | |||
|
29 | .group( | |||
|
30 | ArgGroup::with_name("") | |||
|
31 | .args(&["changelog", "manifest"]) | |||
|
32 | .required(true), | |||
|
33 | ) | |||
|
34 | .arg( | |||
|
35 | Arg::with_name("rev") | |||
|
36 | .help("revision") | |||
|
37 | .required(true) | |||
|
38 | .value_name("REV"), | |||
|
39 | ) | |||
|
40 | .about(HELP_TEXT) | |||
|
41 | } | |||
|
42 | ||||
13 | #[timed] |
|
43 | #[timed] | |
14 | pub fn run( |
|
44 | pub fn run( | |
15 | ui: &Ui, |
|
45 | ui: &Ui, | |
16 | config: &Config, |
|
46 | config: &Config, | |
17 | args: &ArgMatches, |
|
47 | args: &ArgMatches, | |
18 | ) -> Result<(), CommandError> { |
|
48 | ) -> Result<(), CommandError> { | |
19 | let rev = args |
|
49 | let rev = args | |
20 | .value_of("rev") |
|
50 | .value_of("rev") | |
21 | .expect("rev should be a required argument"); |
|
51 | .expect("rev should be a required argument"); | |
22 | let kind = |
|
52 | let kind = | |
23 | match (args.is_present("changelog"), args.is_present("manifest")) { |
|
53 | match (args.is_present("changelog"), args.is_present("manifest")) { | |
24 | (true, false) => DebugDataKind::Changelog, |
|
54 | (true, false) => DebugDataKind::Changelog, | |
25 | (false, true) => DebugDataKind::Manifest, |
|
55 | (false, true) => DebugDataKind::Manifest, | |
26 | (true, true) => { |
|
56 | (true, true) => { | |
27 | unreachable!("Should not happen since options are exclusive") |
|
57 | unreachable!("Should not happen since options are exclusive") | |
28 | } |
|
58 | } | |
29 | (false, false) => { |
|
59 | (false, false) => { | |
30 | unreachable!("Should not happen since options are required") |
|
60 | unreachable!("Should not happen since options are required") | |
31 | } |
|
61 | } | |
32 | }; |
|
62 | }; | |
33 |
|
63 | |||
34 | let repo = Repo::find(config)?; |
|
64 | let repo = Repo::find(config)?; | |
35 | let data = debug_data(&repo, rev, kind).map_err(|e| (e, rev))?; |
|
65 | let data = debug_data(&repo, rev, kind).map_err(|e| (e, rev))?; | |
36 |
|
66 | |||
37 | let mut stdout = ui.stdout_buffer(); |
|
67 | let mut stdout = ui.stdout_buffer(); | |
38 | stdout.write_all(&data)?; |
|
68 | stdout.write_all(&data)?; | |
39 | stdout.flush()?; |
|
69 | stdout.flush()?; | |
40 |
|
70 | |||
41 | Ok(()) |
|
71 | Ok(()) | |
42 | } |
|
72 | } |
@@ -1,26 +1,30 b'' | |||||
1 | use crate::error::CommandError; |
|
1 | use crate::error::CommandError; | |
2 | use crate::ui::Ui; |
|
2 | use crate::ui::Ui; | |
3 | use clap::ArgMatches; |
|
3 | use clap::ArgMatches; | |
4 | use hg::config::Config; |
|
4 | use hg::config::Config; | |
5 | use hg::repo::Repo; |
|
5 | use hg::repo::Repo; | |
6 |
|
6 | |||
7 | pub const HELP_TEXT: &str = " |
|
7 | pub const HELP_TEXT: &str = " | |
8 | Print the current repo requirements. |
|
8 | Print the current repo requirements. | |
9 | "; |
|
9 | "; | |
10 |
|
10 | |||
|
11 | pub fn args() -> clap::App<'static, 'static> { | |||
|
12 | clap::SubCommand::with_name("debugrequirements").about(HELP_TEXT) | |||
|
13 | } | |||
|
14 | ||||
11 | pub fn run( |
|
15 | pub fn run( | |
12 | ui: &Ui, |
|
16 | ui: &Ui, | |
13 | config: &Config, |
|
17 | config: &Config, | |
14 | _args: &ArgMatches, |
|
18 | _args: &ArgMatches, | |
15 | ) -> Result<(), CommandError> { |
|
19 | ) -> Result<(), CommandError> { | |
16 | let repo = Repo::find(config)?; |
|
20 | let repo = Repo::find(config)?; | |
17 | let mut output = String::new(); |
|
21 | let mut output = String::new(); | |
18 | let mut requirements: Vec<_> = repo.requirements().iter().collect(); |
|
22 | let mut requirements: Vec<_> = repo.requirements().iter().collect(); | |
19 | requirements.sort(); |
|
23 | requirements.sort(); | |
20 | for req in requirements { |
|
24 | for req in requirements { | |
21 | output.push_str(req); |
|
25 | output.push_str(req); | |
22 | output.push('\n'); |
|
26 | output.push('\n'); | |
23 | } |
|
27 | } | |
24 | ui.write_stdout(output.as_bytes())?; |
|
28 | ui.write_stdout(output.as_bytes())?; | |
25 | Ok(()) |
|
29 | Ok(()) | |
26 | } |
|
30 | } |
@@ -1,55 +1,69 b'' | |||||
1 | use crate::error::CommandError; |
|
1 | use crate::error::CommandError; | |
2 | use crate::ui::Ui; |
|
2 | use crate::ui::Ui; | |
|
3 | use clap::Arg; | |||
3 | use clap::ArgMatches; |
|
4 | use clap::ArgMatches; | |
4 | use hg::config::Config; |
|
5 | use hg::config::Config; | |
5 | use hg::operations::list_rev_tracked_files; |
|
6 | use hg::operations::list_rev_tracked_files; | |
6 | use hg::operations::Dirstate; |
|
7 | use hg::operations::Dirstate; | |
7 | use hg::repo::Repo; |
|
8 | use hg::repo::Repo; | |
8 | use hg::utils::files::{get_bytes_from_path, relativize_path}; |
|
9 | use hg::utils::files::{get_bytes_from_path, relativize_path}; | |
9 | use hg::utils::hg_path::{HgPath, HgPathBuf}; |
|
10 | use hg::utils::hg_path::{HgPath, HgPathBuf}; | |
10 |
|
11 | |||
11 | pub const HELP_TEXT: &str = " |
|
12 | pub const HELP_TEXT: &str = " | |
12 | List tracked files. |
|
13 | List tracked files. | |
13 |
|
14 | |||
14 | Returns 0 on success. |
|
15 | Returns 0 on success. | |
15 | "; |
|
16 | "; | |
16 |
|
17 | |||
|
18 | pub fn args() -> clap::App<'static, 'static> { | |||
|
19 | clap::SubCommand::with_name("files") | |||
|
20 | .arg( | |||
|
21 | Arg::with_name("rev") | |||
|
22 | .help("search the repository as it is in REV") | |||
|
23 | .short("-r") | |||
|
24 | .long("--revision") | |||
|
25 | .value_name("REV") | |||
|
26 | .takes_value(true), | |||
|
27 | ) | |||
|
28 | .about(HELP_TEXT) | |||
|
29 | } | |||
|
30 | ||||
17 | pub fn run( |
|
31 | pub fn run( | |
18 | ui: &Ui, |
|
32 | ui: &Ui, | |
19 | config: &Config, |
|
33 | config: &Config, | |
20 | args: &ArgMatches, |
|
34 | args: &ArgMatches, | |
21 | ) -> Result<(), CommandError> { |
|
35 | ) -> Result<(), CommandError> { | |
22 | let rev = args.value_of("rev"); |
|
36 | let rev = args.value_of("rev"); | |
23 |
|
37 | |||
24 | let repo = Repo::find(config)?; |
|
38 | let repo = Repo::find(config)?; | |
25 | if let Some(rev) = rev { |
|
39 | if let Some(rev) = rev { | |
26 | let files = |
|
40 | let files = | |
27 | list_rev_tracked_files(&repo, rev).map_err(|e| (e, rev))?; |
|
41 | list_rev_tracked_files(&repo, rev).map_err(|e| (e, rev))?; | |
28 | display_files(ui, &repo, files.iter()) |
|
42 | display_files(ui, &repo, files.iter()) | |
29 | } else { |
|
43 | } else { | |
30 | let distate = Dirstate::new(&repo)?; |
|
44 | let distate = Dirstate::new(&repo)?; | |
31 | let files = distate.tracked_files()?; |
|
45 | let files = distate.tracked_files()?; | |
32 | display_files(ui, &repo, files) |
|
46 | display_files(ui, &repo, files) | |
33 | } |
|
47 | } | |
34 | } |
|
48 | } | |
35 |
|
49 | |||
36 | fn display_files<'a>( |
|
50 | fn display_files<'a>( | |
37 | ui: &Ui, |
|
51 | ui: &Ui, | |
38 | repo: &Repo, |
|
52 | repo: &Repo, | |
39 | files: impl IntoIterator<Item = &'a HgPath>, |
|
53 | files: impl IntoIterator<Item = &'a HgPath>, | |
40 | ) -> Result<(), CommandError> { |
|
54 | ) -> Result<(), CommandError> { | |
41 | let cwd = hg::utils::current_dir()?; |
|
55 | let cwd = hg::utils::current_dir()?; | |
42 | let rooted_cwd = cwd |
|
56 | let rooted_cwd = cwd | |
43 | .strip_prefix(repo.working_directory_path()) |
|
57 | .strip_prefix(repo.working_directory_path()) | |
44 | .expect("cwd was already checked within the repository"); |
|
58 | .expect("cwd was already checked within the repository"); | |
45 | let rooted_cwd = HgPathBuf::from(get_bytes_from_path(rooted_cwd)); |
|
59 | let rooted_cwd = HgPathBuf::from(get_bytes_from_path(rooted_cwd)); | |
46 |
|
60 | |||
47 | let mut stdout = ui.stdout_buffer(); |
|
61 | let mut stdout = ui.stdout_buffer(); | |
48 |
|
62 | |||
49 | for file in files { |
|
63 | for file in files { | |
50 | stdout.write_all(relativize_path(file, &rooted_cwd).as_ref())?; |
|
64 | stdout.write_all(relativize_path(file, &rooted_cwd).as_ref())?; | |
51 | stdout.write_all(b"\n")?; |
|
65 | stdout.write_all(b"\n")?; | |
52 | } |
|
66 | } | |
53 | stdout.flush()?; |
|
67 | stdout.flush()?; | |
54 | Ok(()) |
|
68 | Ok(()) | |
55 | } |
|
69 | } |
@@ -1,24 +1,28 b'' | |||||
1 | use crate::error::CommandError; |
|
1 | use crate::error::CommandError; | |
2 | use crate::ui::Ui; |
|
2 | use crate::ui::Ui; | |
3 | use clap::ArgMatches; |
|
3 | use clap::ArgMatches; | |
4 | use format_bytes::format_bytes; |
|
4 | use format_bytes::format_bytes; | |
5 | use hg::config::Config; |
|
5 | use hg::config::Config; | |
6 | use hg::repo::Repo; |
|
6 | use hg::repo::Repo; | |
7 | use hg::utils::files::get_bytes_from_path; |
|
7 | use hg::utils::files::get_bytes_from_path; | |
8 |
|
8 | |||
9 | pub const HELP_TEXT: &str = " |
|
9 | pub const HELP_TEXT: &str = " | |
10 | Print the root directory of the current repository. |
|
10 | Print the root directory of the current repository. | |
11 |
|
11 | |||
12 | Returns 0 on success. |
|
12 | Returns 0 on success. | |
13 | "; |
|
13 | "; | |
14 |
|
14 | |||
|
15 | pub fn args() -> clap::App<'static, 'static> { | |||
|
16 | clap::SubCommand::with_name("root").about(HELP_TEXT) | |||
|
17 | } | |||
|
18 | ||||
15 | pub fn run( |
|
19 | pub fn run( | |
16 | ui: &Ui, |
|
20 | ui: &Ui, | |
17 | config: &Config, |
|
21 | config: &Config, | |
18 | _args: &ArgMatches, |
|
22 | _args: &ArgMatches, | |
19 | ) -> Result<(), CommandError> { |
|
23 | ) -> Result<(), CommandError> { | |
20 | let repo = Repo::find(config)?; |
|
24 | let repo = Repo::find(config)?; | |
21 | let bytes = get_bytes_from_path(repo.working_directory_path()); |
|
25 | let bytes = get_bytes_from_path(repo.working_directory_path()); | |
22 | ui.write_stdout(&format_bytes!(b"{}\n", bytes.as_slice()))?; |
|
26 | ui.write_stdout(&format_bytes!(b"{}\n", bytes.as_slice()))?; | |
23 | Ok(()) |
|
27 | Ok(()) | |
24 | } |
|
28 | } |
@@ -1,137 +1,73 b'' | |||||
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; |
|
|||
5 | use clap::ArgGroup; |
|
|||
6 | use clap::ArgMatches; |
|
4 | use clap::ArgMatches; | |
7 | use clap::SubCommand; |
|
|||
8 | use format_bytes::format_bytes; |
|
5 | use format_bytes::format_bytes; | |
9 |
|
6 | |||
10 | mod commands; |
|
7 | mod commands; | |
11 | mod error; |
|
8 | mod error; | |
12 | mod exitcode; |
|
9 | mod exitcode; | |
13 | mod ui; |
|
10 | mod ui; | |
14 | use error::CommandError; |
|
11 | use error::CommandError; | |
15 |
|
12 | |||
16 | fn main() { |
|
13 | fn main() { | |
17 | env_logger::init(); |
|
14 | env_logger::init(); | |
18 | let app = App::new("rhg") |
|
15 | let app = App::new("rhg") | |
19 | .setting(AppSettings::AllowInvalidUtf8) |
|
16 | .setting(AppSettings::AllowInvalidUtf8) | |
20 | .setting(AppSettings::SubcommandRequired) |
|
17 | .setting(AppSettings::SubcommandRequired) | |
21 | .setting(AppSettings::VersionlessSubcommands) |
|
18 | .setting(AppSettings::VersionlessSubcommands) | |
22 | .version("0.0.1") |
|
19 | .version("0.0.1") | |
23 | .subcommand( |
|
20 | .subcommand(commands::root::args()) | |
24 | SubCommand::with_name("root").about(commands::root::HELP_TEXT), |
|
21 | .subcommand(commands::files::args()) | |
25 | ) |
|
22 | .subcommand(commands::cat::args()) | |
26 | .subcommand( |
|
23 | .subcommand(commands::debugdata::args()) | |
27 | SubCommand::with_name("files") |
|
24 | .subcommand(commands::debugrequirements::args()); | |
28 | .arg( |
|
|||
29 | Arg::with_name("rev") |
|
|||
30 | .help("search the repository as it is in REV") |
|
|||
31 | .short("-r") |
|
|||
32 | .long("--revision") |
|
|||
33 | .value_name("REV") |
|
|||
34 | .takes_value(true), |
|
|||
35 | ) |
|
|||
36 | .about(commands::files::HELP_TEXT), |
|
|||
37 | ) |
|
|||
38 | .subcommand( |
|
|||
39 | SubCommand::with_name("cat") |
|
|||
40 | .arg( |
|
|||
41 | Arg::with_name("rev") |
|
|||
42 | .help("search the repository as it is in REV") |
|
|||
43 | .short("-r") |
|
|||
44 | .long("--revision") |
|
|||
45 | .value_name("REV") |
|
|||
46 | .takes_value(true), |
|
|||
47 | ) |
|
|||
48 | .arg( |
|
|||
49 | clap::Arg::with_name("files") |
|
|||
50 | .required(true) |
|
|||
51 | .multiple(true) |
|
|||
52 | .empty_values(false) |
|
|||
53 | .value_name("FILE") |
|
|||
54 | .help("Activity to start: activity@category"), |
|
|||
55 | ) |
|
|||
56 | .about(commands::cat::HELP_TEXT), |
|
|||
57 | ) |
|
|||
58 | .subcommand( |
|
|||
59 | SubCommand::with_name("debugdata") |
|
|||
60 | .about(commands::debugdata::HELP_TEXT) |
|
|||
61 | .arg( |
|
|||
62 | Arg::with_name("changelog") |
|
|||
63 | .help("open changelog") |
|
|||
64 | .short("-c") |
|
|||
65 | .long("--changelog"), |
|
|||
66 | ) |
|
|||
67 | .arg( |
|
|||
68 | Arg::with_name("manifest") |
|
|||
69 | .help("open manifest") |
|
|||
70 | .short("-m") |
|
|||
71 | .long("--manifest"), |
|
|||
72 | ) |
|
|||
73 | .group( |
|
|||
74 | ArgGroup::with_name("") |
|
|||
75 | .args(&["changelog", "manifest"]) |
|
|||
76 | .required(true), |
|
|||
77 | ) |
|
|||
78 | .arg( |
|
|||
79 | Arg::with_name("rev") |
|
|||
80 | .help("revision") |
|
|||
81 | .required(true) |
|
|||
82 | .value_name("REV"), |
|
|||
83 | ), |
|
|||
84 | ) |
|
|||
85 | .subcommand( |
|
|||
86 | SubCommand::with_name("debugrequirements") |
|
|||
87 | .about(commands::debugrequirements::HELP_TEXT), |
|
|||
88 | ); |
|
|||
89 |
|
25 | |||
90 | let matches = app.clone().get_matches_safe().unwrap_or_else(|err| { |
|
26 | let matches = app.clone().get_matches_safe().unwrap_or_else(|err| { | |
91 | let _ = ui::Ui::new().writeln_stderr_str(&err.message); |
|
27 | let _ = ui::Ui::new().writeln_stderr_str(&err.message); | |
92 | std::process::exit(exitcode::UNIMPLEMENTED) |
|
28 | std::process::exit(exitcode::UNIMPLEMENTED) | |
93 | }); |
|
29 | }); | |
94 |
|
30 | |||
95 | let ui = ui::Ui::new(); |
|
31 | let ui = ui::Ui::new(); | |
96 |
|
32 | |||
97 | let command_result = match_subcommand(matches, &ui); |
|
33 | let command_result = match_subcommand(matches, &ui); | |
98 |
|
34 | |||
99 | let exit_code = match command_result { |
|
35 | let exit_code = match command_result { | |
100 | Ok(_) => exitcode::OK, |
|
36 | Ok(_) => exitcode::OK, | |
101 |
|
37 | |||
102 | // Exit with a specific code and no error message to let a potential |
|
38 | // Exit with a specific code and no error message to let a potential | |
103 | // wrapper script fallback to Python-based Mercurial. |
|
39 | // wrapper script fallback to Python-based Mercurial. | |
104 | Err(CommandError::Unimplemented) => exitcode::UNIMPLEMENTED, |
|
40 | Err(CommandError::Unimplemented) => exitcode::UNIMPLEMENTED, | |
105 |
|
41 | |||
106 | Err(CommandError::Abort { message }) => { |
|
42 | Err(CommandError::Abort { message }) => { | |
107 | if !message.is_empty() { |
|
43 | if !message.is_empty() { | |
108 | // Ignore errors when writing to stderr, weβre already exiting |
|
44 | // Ignore errors when writing to stderr, weβre already exiting | |
109 | // with failure code so thereβs not much more we can do. |
|
45 | // with failure code so thereβs not much more we can do. | |
110 | let _ = |
|
46 | let _ = | |
111 | ui.write_stderr(&format_bytes!(b"abort: {}\n", message)); |
|
47 | ui.write_stderr(&format_bytes!(b"abort: {}\n", message)); | |
112 | } |
|
48 | } | |
113 | exitcode::ABORT |
|
49 | exitcode::ABORT | |
114 | } |
|
50 | } | |
115 | }; |
|
51 | }; | |
116 | std::process::exit(exit_code) |
|
52 | std::process::exit(exit_code) | |
117 | } |
|
53 | } | |
118 |
|
54 | |||
119 | fn match_subcommand( |
|
55 | fn match_subcommand( | |
120 | matches: ArgMatches, |
|
56 | matches: ArgMatches, | |
121 | ui: &ui::Ui, |
|
57 | ui: &ui::Ui, | |
122 | ) -> Result<(), CommandError> { |
|
58 | ) -> Result<(), CommandError> { | |
123 | let config = hg::config::Config::load()?; |
|
59 | let config = hg::config::Config::load()?; | |
124 |
|
60 | |||
125 | match matches.subcommand() { |
|
61 | match matches.subcommand() { | |
126 | ("root", Some(matches)) => commands::root::run(ui, &config, matches), |
|
62 | ("root", Some(matches)) => commands::root::run(ui, &config, matches), | |
127 | ("files", Some(matches)) => commands::files::run(ui, &config, matches), |
|
63 | ("files", Some(matches)) => commands::files::run(ui, &config, matches), | |
128 | ("cat", Some(matches)) => commands::cat::run(ui, &config, matches), |
|
64 | ("cat", Some(matches)) => commands::cat::run(ui, &config, matches), | |
129 | ("debugdata", Some(matches)) => { |
|
65 | ("debugdata", Some(matches)) => { | |
130 | commands::debugdata::run(ui, &config, matches) |
|
66 | commands::debugdata::run(ui, &config, matches) | |
131 | } |
|
67 | } | |
132 | ("debugrequirements", Some(matches)) => { |
|
68 | ("debugrequirements", Some(matches)) => { | |
133 | commands::debugrequirements::run(ui, &config, matches) |
|
69 | commands::debugrequirements::run(ui, &config, matches) | |
134 | } |
|
70 | } | |
135 | _ => unreachable!(), // Because of AppSettings::SubcommandRequired, |
|
71 | _ => unreachable!(), // Because of AppSettings::SubcommandRequired, | |
136 | } |
|
72 | } | |
137 | } |
|
73 | } |
General Comments 0
You need to be logged in to leave comments.
Login now