Show More
@@ -1,58 +1,119 b'' | |||||
1 | use clap::App; |
|
1 | use clap::App; | |
2 | use clap::AppSettings; |
|
2 | use clap::AppSettings; | |
|
3 | use clap::Arg; | |||
|
4 | use clap::ArgGroup; | |||
|
5 | use clap::ArgMatches; | |||
3 | use clap::SubCommand; |
|
6 | use clap::SubCommand; | |
|
7 | use hg::operations::DebugDataKind; | |||
|
8 | use std::convert::TryFrom; | |||
4 |
|
9 | |||
5 | mod commands; |
|
10 | mod commands; | |
6 | mod error; |
|
11 | mod error; | |
7 | mod exitcode; |
|
12 | mod exitcode; | |
8 | mod ui; |
|
13 | mod ui; | |
9 | use commands::Command; |
|
14 | use commands::Command; | |
|
15 | use error::CommandError; | |||
10 |
|
16 | |||
11 | fn main() { |
|
17 | fn main() { | |
12 |
let |
|
18 | let app = App::new("rhg") | |
13 | .setting(AppSettings::AllowInvalidUtf8) |
|
19 | .setting(AppSettings::AllowInvalidUtf8) | |
14 | .setting(AppSettings::SubcommandRequired) |
|
20 | .setting(AppSettings::SubcommandRequired) | |
15 | .setting(AppSettings::VersionlessSubcommands) |
|
21 | .setting(AppSettings::VersionlessSubcommands) | |
16 | .version("0.0.1") |
|
22 | .version("0.0.1") | |
17 | .subcommand( |
|
23 | .subcommand( | |
18 | SubCommand::with_name("root").about(commands::root::HELP_TEXT), |
|
24 | SubCommand::with_name("root").about(commands::root::HELP_TEXT), | |
19 | ) |
|
25 | ) | |
20 | .subcommand( |
|
26 | .subcommand( | |
21 | SubCommand::with_name("files").about(commands::files::HELP_TEXT), |
|
27 | SubCommand::with_name("files").about(commands::files::HELP_TEXT), | |
|
28 | ) | |||
|
29 | .subcommand( | |||
|
30 | SubCommand::with_name("debugdata") | |||
|
31 | .about(commands::debugdata::HELP_TEXT) | |||
|
32 | .arg( | |||
|
33 | Arg::with_name("changelog") | |||
|
34 | .help("open changelog") | |||
|
35 | .short("-c") | |||
|
36 | .long("--changelog"), | |||
|
37 | ) | |||
|
38 | .arg( | |||
|
39 | Arg::with_name("manifest") | |||
|
40 | .help("open manifest") | |||
|
41 | .short("-m") | |||
|
42 | .long("--manifest"), | |||
|
43 | ) | |||
|
44 | .group( | |||
|
45 | ArgGroup::with_name("") | |||
|
46 | .args(&["changelog", "manifest"]) | |||
|
47 | .required(true), | |||
|
48 | ) | |||
|
49 | .arg( | |||
|
50 | Arg::with_name("rev") | |||
|
51 | .help("revision") | |||
|
52 | .required(true) | |||
|
53 | .value_name("REV"), | |||
|
54 | ), | |||
22 | ); |
|
55 | ); | |
23 |
|
56 | |||
24 | let matches = app.clone().get_matches_safe().unwrap_or_else(|err| { |
|
57 | let matches = app.clone().get_matches_safe().unwrap_or_else(|err| { | |
25 | let _ = ui::Ui::new().writeln_stderr_str(&err.message); |
|
58 | let _ = ui::Ui::new().writeln_stderr_str(&err.message); | |
26 | std::process::exit(exitcode::UNIMPLEMENTED_COMMAND) |
|
59 | std::process::exit(exitcode::UNIMPLEMENTED_COMMAND) | |
27 | }); |
|
60 | }); | |
28 |
|
61 | |||
29 | let ui = ui::Ui::new(); |
|
62 | let ui = ui::Ui::new(); | |
30 |
|
63 | |||
31 |
let command_result = match |
|
64 | let command_result = match_subcommand(matches, &ui); | |
32 | Some(name) => match name { |
|
|||
33 | "root" => commands::root::RootCommand::new().run(&ui), |
|
|||
34 | "files" => commands::files::FilesCommand::new().run(&ui), |
|
|||
35 | _ => std::process::exit(exitcode::UNIMPLEMENTED_COMMAND), |
|
|||
36 | }, |
|
|||
37 | _ => { |
|
|||
38 | match app.print_help() { |
|
|||
39 | Ok(_) => std::process::exit(exitcode::OK), |
|
|||
40 | Err(_) => std::process::exit(exitcode::ABORT), |
|
|||
41 | }; |
|
|||
42 | } |
|
|||
43 | }; |
|
|||
44 |
|
65 | |||
45 | match command_result { |
|
66 | match command_result { | |
46 | Ok(_) => std::process::exit(exitcode::OK), |
|
67 | Ok(_) => std::process::exit(exitcode::OK), | |
47 | Err(e) => { |
|
68 | Err(e) => { | |
48 | let message = e.get_error_message_bytes(); |
|
69 | let message = e.get_error_message_bytes(); | |
49 | if let Some(msg) = message { |
|
70 | if let Some(msg) = message { | |
50 | match ui.write_stderr(&msg) { |
|
71 | match ui.write_stderr(&msg) { | |
51 | Ok(_) => (), |
|
72 | Ok(_) => (), | |
52 | Err(_) => std::process::exit(exitcode::ABORT), |
|
73 | Err(_) => std::process::exit(exitcode::ABORT), | |
53 | }; |
|
74 | }; | |
54 | }; |
|
75 | }; | |
55 | e.exit() |
|
76 | e.exit() | |
56 | } |
|
77 | } | |
57 | } |
|
78 | } | |
58 | } |
|
79 | } | |
|
80 | ||||
|
81 | fn match_subcommand( | |||
|
82 | matches: ArgMatches, | |||
|
83 | ui: &ui::Ui, | |||
|
84 | ) -> Result<(), CommandError> { | |||
|
85 | match matches.subcommand() { | |||
|
86 | ("root", _) => commands::root::RootCommand::new().run(&ui), | |||
|
87 | ("files", _) => commands::files::FilesCommand::new().run(&ui), | |||
|
88 | ("debugdata", Some(matches)) => { | |||
|
89 | commands::debugdata::DebugDataCommand::try_from(matches)?.run(&ui) | |||
|
90 | } | |||
|
91 | _ => unreachable!(), // Because of AppSettings::SubcommandRequired, | |||
|
92 | } | |||
|
93 | } | |||
|
94 | ||||
|
95 | impl<'a> TryFrom<&'a ArgMatches<'_>> | |||
|
96 | for commands::debugdata::DebugDataCommand<'a> | |||
|
97 | { | |||
|
98 | type Error = CommandError; | |||
|
99 | ||||
|
100 | fn try_from(args: &'a ArgMatches) -> Result<Self, Self::Error> { | |||
|
101 | let rev = args | |||
|
102 | .value_of("rev") | |||
|
103 | .expect("rev should be a required argument"); | |||
|
104 | let kind = match ( | |||
|
105 | args.is_present("changelog"), | |||
|
106 | args.is_present("manifest"), | |||
|
107 | ) { | |||
|
108 | (true, false) => DebugDataKind::Changelog, | |||
|
109 | (false, true) => DebugDataKind::Manifest, | |||
|
110 | (true, true) => { | |||
|
111 | unreachable!("Should not happen since options are exclusive") | |||
|
112 | } | |||
|
113 | (false, false) => { | |||
|
114 | unreachable!("Should not happen since options are required") | |||
|
115 | } | |||
|
116 | }; | |||
|
117 | Ok(commands::debugdata::DebugDataCommand::new(rev, kind)) | |||
|
118 | } | |||
|
119 | } |
@@ -1,70 +1,92 b'' | |||||
1 | #require rust |
|
1 | #require rust | |
2 |
|
2 | |||
3 | Define an rhg function that will only run if rhg exists |
|
3 | Define an rhg function that will only run if rhg exists | |
4 | $ rhg() { |
|
4 | $ rhg() { | |
5 | > if [ -f "$RUNTESTDIR/../rust/target/debug/rhg" ]; then |
|
5 | > if [ -f "$RUNTESTDIR/../rust/target/debug/rhg" ]; then | |
6 | > "$RUNTESTDIR/../rust/target/debug/rhg" "$@" |
|
6 | > "$RUNTESTDIR/../rust/target/debug/rhg" "$@" | |
7 | > else |
|
7 | > else | |
8 | > echo "skipped: Cannot find rhg. Try to run cargo build in rust/rhg." |
|
8 | > echo "skipped: Cannot find rhg. Try to run cargo build in rust/rhg." | |
9 | > exit 80 |
|
9 | > exit 80 | |
10 | > fi |
|
10 | > fi | |
11 | > } |
|
11 | > } | |
12 |
|
12 | |||
13 | Unimplemented command |
|
13 | Unimplemented command | |
14 | $ rhg unimplemented-command |
|
14 | $ rhg unimplemented-command | |
15 | error: Found argument 'unimplemented-command' which wasn't expected, or isn't valid in this context |
|
15 | error: Found argument 'unimplemented-command' which wasn't expected, or isn't valid in this context | |
16 |
|
16 | |||
17 | USAGE: |
|
17 | USAGE: | |
18 | rhg <SUBCOMMAND> |
|
18 | rhg <SUBCOMMAND> | |
19 |
|
19 | |||
20 | For more information try --help |
|
20 | For more information try --help | |
21 | [252] |
|
21 | [252] | |
22 |
|
22 | |||
23 | Finding root |
|
23 | Finding root | |
24 | $ rhg root |
|
24 | $ rhg root | |
25 | abort: no repository found in '$TESTTMP' (.hg not found)! |
|
25 | abort: no repository found in '$TESTTMP' (.hg not found)! | |
26 | [255] |
|
26 | [255] | |
27 |
|
27 | |||
28 | $ hg init repository |
|
28 | $ hg init repository | |
29 | $ cd repository |
|
29 | $ cd repository | |
30 | $ rhg root |
|
30 | $ rhg root | |
31 | $TESTTMP/repository |
|
31 | $TESTTMP/repository | |
32 |
|
32 | |||
33 | Unwritable file descriptor |
|
33 | Unwritable file descriptor | |
34 | $ rhg root > /dev/full |
|
34 | $ rhg root > /dev/full | |
35 | abort: No space left on device (os error 28) |
|
35 | abort: No space left on device (os error 28) | |
36 | [255] |
|
36 | [255] | |
37 |
|
37 | |||
38 | Deleted repository |
|
38 | Deleted repository | |
39 | $ rm -rf `pwd` |
|
39 | $ rm -rf `pwd` | |
40 | $ rhg root |
|
40 | $ rhg root | |
41 | abort: error getting current working directory: $ENOENT$ |
|
41 | abort: error getting current working directory: $ENOENT$ | |
42 | [255] |
|
42 | [255] | |
43 |
|
43 | |||
44 | Listing tracked files |
|
44 | Listing tracked files | |
45 | $ cd $TESTTMP |
|
45 | $ cd $TESTTMP | |
46 | $ hg init repository |
|
46 | $ hg init repository | |
47 | $ cd repository |
|
47 | $ cd repository | |
48 | $ for i in 1 2 3; do |
|
48 | $ for i in 1 2 3; do | |
49 | > echo $i >> file$i |
|
49 | > echo $i >> file$i | |
50 | > hg add file$i |
|
50 | > hg add file$i | |
51 | > done |
|
51 | > done | |
52 | > hg commit -m "commit $i" -q |
|
52 | > hg commit -m "commit $i" -q | |
53 |
|
53 | |||
54 | Listing tracked files from root |
|
54 | Listing tracked files from root | |
55 | $ rhg files |
|
55 | $ rhg files | |
56 | file1 |
|
56 | file1 | |
57 | file2 |
|
57 | file2 | |
58 | file3 |
|
58 | file3 | |
59 |
|
59 | |||
60 | Listing tracked files from subdirectory |
|
60 | Listing tracked files from subdirectory | |
61 | $ mkdir -p path/to/directory |
|
61 | $ mkdir -p path/to/directory | |
62 | $ cd path/to/directory |
|
62 | $ cd path/to/directory | |
63 | $ rhg files |
|
63 | $ rhg files | |
64 | ../../../file1 |
|
64 | ../../../file1 | |
65 | ../../../file2 |
|
65 | ../../../file2 | |
66 | ../../../file3 |
|
66 | ../../../file3 | |
67 |
|
67 | |||
68 | Listing tracked files through broken pipe |
|
68 | Listing tracked files through broken pipe | |
69 | $ rhg files | head -n 1 |
|
69 | $ rhg files | head -n 1 | |
70 | ../../../file1 |
|
70 | ../../../file1 | |
|
71 | ||||
|
72 | Debuging data in inline index | |||
|
73 | $ cd $TESTTMP | |||
|
74 | $ rm -rf repository | |||
|
75 | $ hg init repository | |||
|
76 | $ cd repository | |||
|
77 | $ for i in 1 2 3; do | |||
|
78 | > echo $i >> file$i | |||
|
79 | > hg add file$i | |||
|
80 | > hg commit -m "commit $i" -q | |||
|
81 | > done | |||
|
82 | $ rhg debugdata -c 2 | |||
|
83 | e36fa63d37a576b27a69057598351db6ee5746bd | |||
|
84 | test | |||
|
85 | 0 0 | |||
|
86 | file3 | |||
|
87 | ||||
|
88 | commit 3 (no-eol) | |||
|
89 | $ rhg debugdata -m 2 | |||
|
90 | file1\x00b8e02f6433738021a065f94175c7cd23db5f05be (esc) | |||
|
91 | file2\x005d9299349fc01ddd25d0070d149b124d8f10411e (esc) | |||
|
92 | file3\x002661d26c649684b482d10f91960cc3db683c38b4 (esc) |
General Comments 0
You need to be logged in to leave comments.
Login now