##// END OF EJS Templates
rhg: ask the error message from `CommandError`...
Antoine Cezar -
r45920:47997afa default
parent child Browse files
Show More
@@ -4,6 +4,6 b' use crate::error::CommandError;'
4 4 /// The common trait for rhg commands
5 5 ///
6 6 /// Normalize the interface of the commands provided by rhg
7 pub trait Command {
7 pub trait Command<'a> {
8 8 fn run(&self) -> Result<(), CommandError>;
9 9 }
@@ -1,9 +1,8 b''
1 1 use crate::commands::Command;
2 2 use crate::error::{CommandError, CommandErrorKind};
3 3 use crate::ui::Ui;
4 use hg::operations::{FindRoot, FindRootError, FindRootErrorKind};
4 use hg::operations::{FindRoot, FindRootErrorKind};
5 5 use hg::utils::files::get_bytes_from_path;
6 use std::path::PathBuf;
7 6
8 7 pub const HELP_TEXT: &str = "
9 8 Print the root directory of the current repository.
@@ -11,19 +10,28 b' Print the root directory of the current '
11 10 Returns 0 on success.
12 11 ";
13 12
14 pub struct RootCommand {
15 ui: Ui,
13 pub struct RootCommand<'a> {
14 ui: &'a Ui,
15 }
16
17 impl<'a> RootCommand<'a> {
18 pub fn new(ui: &'a Ui) -> Self {
19 RootCommand { ui }
20 }
16 21 }
17 22
18 impl RootCommand {
19 pub fn new() -> Self {
20 RootCommand { ui: Ui::new() }
23 impl<'a> Command<'a> for RootCommand<'a> {
24 fn run(&self) -> Result<(), CommandError> {
25 let path_buf =
26 FindRoot::new().run().map_err(|err| match err.kind {
27 FindRootErrorKind::RootNotFound(path) => {
28 CommandErrorKind::RootNotFound(path)
21 29 }
30 FindRootErrorKind::GetCurrentDirError(e) => {
31 CommandErrorKind::CurrentDirNotFound(e)
32 }
33 })?;
22 34
23 fn display_found_path(
24 &self,
25 path_buf: PathBuf,
26 ) -> Result<(), CommandError> {
27 35 let bytes = get_bytes_from_path(path_buf);
28 36
29 37 // TODO use formating macro
@@ -31,46 +39,4 b' impl RootCommand {'
31 39
32 40 Ok(())
33 41 }
34
35 fn display_error(&self, error: FindRootError) -> Result<(), CommandError> {
36 match error.kind {
37 FindRootErrorKind::RootNotFound(path) => {
38 let bytes = get_bytes_from_path(path);
39
40 // TODO use formating macro
41 self.ui.write_stderr(
42 &[
43 b"abort: no repository found in '",
44 bytes.as_slice(),
45 b"' (.hg not found)!\n",
46 ]
47 .concat(),
48 )?;
49
50 Err(CommandErrorKind::RootNotFound.into())
51 42 }
52 FindRootErrorKind::GetCurrentDirError(e) => {
53 // TODO use formating macro
54 self.ui.write_stderr(
55 &[
56 b"abort: error getting current working directory: ",
57 e.to_string().as_bytes(),
58 b"\n",
59 ]
60 .concat(),
61 )?;
62
63 Err(CommandErrorKind::CurrentDirNotFound.into())
64 }
65 }
66 }
67 }
68
69 impl Command for RootCommand {
70 fn run(&self) -> Result<(), CommandError> {
71 match FindRoot::new().run() {
72 Ok(path_buf) => self.display_found_path(path_buf),
73 Err(e) => self.display_error(e),
74 }
75 }
76 }
@@ -1,14 +1,16 b''
1 1 use crate::exitcode;
2 2 use crate::ui::UiError;
3 use hg::utils::files::get_bytes_from_path;
3 4 use std::convert::From;
5 use std::path::PathBuf;
4 6
5 7 /// The kind of command error
6 #[derive(Debug, PartialEq)]
8 #[derive(Debug)]
7 9 pub enum CommandErrorKind {
8 10 /// The root of the repository cannot be found
9 RootNotFound,
11 RootNotFound(PathBuf),
10 12 /// The current directory cannot be found
11 CurrentDirNotFound,
13 CurrentDirNotFound(std::io::Error),
12 14 /// The standard output stream cannot be written to
13 15 StdoutError,
14 16 /// The standard error stream cannot be written to
@@ -18,16 +20,44 b' pub enum CommandErrorKind {'
18 20 impl CommandErrorKind {
19 21 pub fn get_exit_code(&self) -> exitcode::ExitCode {
20 22 match self {
21 CommandErrorKind::RootNotFound => exitcode::ABORT,
22 CommandErrorKind::CurrentDirNotFound => exitcode::ABORT,
23 CommandErrorKind::RootNotFound(_) => exitcode::ABORT,
24 CommandErrorKind::CurrentDirNotFound(_) => exitcode::ABORT,
23 25 CommandErrorKind::StdoutError => exitcode::ABORT,
24 26 CommandErrorKind::StderrError => exitcode::ABORT,
25 27 }
26 28 }
29
30 /// Return the message corresponding to the error kind if any
31 pub fn get_error_message_bytes(&self) -> Option<Vec<u8>> {
32 match self {
33 // TODO use formating macro
34 CommandErrorKind::RootNotFound(path) => {
35 let bytes = get_bytes_from_path(path);
36 Some(
37 [
38 b"abort: no repository found in '",
39 bytes.as_slice(),
40 b"' (.hg not found)!\n",
41 ]
42 .concat(),
43 )
44 }
45 // TODO use formating macro
46 CommandErrorKind::CurrentDirNotFound(e) => Some(
47 [
48 b"abort: error getting current working directory: ",
49 e.to_string().as_bytes(),
50 b"\n",
51 ]
52 .concat(),
53 ),
54 _ => None,
55 }
56 }
27 57 }
28 58
29 59 /// The error type for the Command trait
30 #[derive(Debug, PartialEq)]
60 #[derive(Debug)]
31 61 pub struct CommandError {
32 62 pub kind: CommandErrorKind,
33 63 }
@@ -37,6 +67,11 b' impl CommandError {'
37 67 pub fn exit(&self) -> () {
38 68 std::process::exit(self.kind.get_exit_code())
39 69 }
70
71 /// Return the message corresponding to the command error if any
72 pub fn get_error_message_bytes(&self) -> Option<Vec<u8>> {
73 self.kind.get_error_message_bytes()
74 }
40 75 }
41 76
42 77 impl From<CommandErrorKind> for CommandError {
@@ -22,9 +22,11 b' fn main() {'
22 22 std::process::exit(exitcode::UNIMPLEMENTED_COMMAND)
23 23 });
24 24
25 let ui = ui::Ui::new();
26
25 27 let command_result = match matches.subcommand_name() {
26 28 Some(name) => match name {
27 "root" => commands::root::RootCommand::new().run(),
29 "root" => commands::root::RootCommand::new(&ui).run(),
28 30 _ => std::process::exit(exitcode::UNIMPLEMENTED_COMMAND),
29 31 },
30 32 _ => {
@@ -37,6 +39,15 b' fn main() {'
37 39
38 40 match command_result {
39 41 Ok(_) => std::process::exit(exitcode::OK),
40 Err(e) => e.exit(),
42 Err(e) => {
43 let message = e.get_error_message_bytes();
44 if let Some(msg) = message {
45 match ui.write_stderr(&msg) {
46 Ok(_) => (),
47 Err(_) => std::process::exit(exitcode::ABORT),
48 };
49 };
50 e.exit()
41 51 }
42 52 }
53 }
General Comments 0
You need to be logged in to leave comments. Login now