##// END OF EJS Templates
rhg: pass `ui` to `Command` `run`...
Antoine Cezar -
r46009:ed95ccc9 default
parent child Browse files
Show More
@@ -1,10 +1,11 b''
1 pub mod files;
1 pub mod files;
2 pub mod root;
2 pub mod root;
3 use crate::error::CommandError;
3 use crate::error::CommandError;
4 use crate::ui::Ui;
4
5
5 /// The common trait for rhg commands
6 /// The common trait for rhg commands
6 ///
7 ///
7 /// Normalize the interface of the commands provided by rhg
8 /// Normalize the interface of the commands provided by rhg
8 pub trait Command<'a> {
9 pub trait Command {
9 fn run(&self) -> Result<(), CommandError>;
10 fn run(&self, ui: &Ui) -> Result<(), CommandError>;
10 }
11 }
@@ -1,60 +1,58 b''
1 use crate::commands::Command;
1 use crate::commands::Command;
2 use crate::error::{CommandError, CommandErrorKind};
2 use crate::error::{CommandError, CommandErrorKind};
3 use crate::ui::Ui;
3 use crate::ui::Ui;
4 use hg::operations::{ListTrackedFiles, ListTrackedFilesErrorKind};
4 use hg::operations::{ListTrackedFiles, ListTrackedFilesErrorKind};
5 use hg::utils::files::{get_bytes_from_path, relativize_path};
5 use hg::utils::files::{get_bytes_from_path, relativize_path};
6 use hg::utils::hg_path::HgPathBuf;
6 use hg::utils::hg_path::HgPathBuf;
7
7
8 pub const HELP_TEXT: &str = "
8 pub const HELP_TEXT: &str = "
9 List tracked files.
9 List tracked files.
10
10
11 Returns 0 on success.
11 Returns 0 on success.
12 ";
12 ";
13
13
14 pub struct FilesCommand<'a> {
14 pub struct FilesCommand {}
15 ui: &'a Ui,
16 }
17
15
18 impl<'a> FilesCommand<'a> {
16 impl FilesCommand {
19 pub fn new(ui: &'a Ui) -> Self {
17 pub fn new() -> Self {
20 FilesCommand { ui }
18 FilesCommand {}
21 }
19 }
22 }
20 }
23
21
24 impl<'a> Command<'a> for FilesCommand<'a> {
22 impl Command for FilesCommand {
25 fn run(&self) -> Result<(), CommandError> {
23 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
26 let operation_builder = ListTrackedFiles::new()?;
24 let operation_builder = ListTrackedFiles::new()?;
27 let operation = operation_builder.load().map_err(|err| {
25 let operation = operation_builder.load().map_err(|err| {
28 CommandErrorKind::Abort(Some(
26 CommandErrorKind::Abort(Some(
29 [b"abort: ", err.to_string().as_bytes(), b"\n"]
27 [b"abort: ", err.to_string().as_bytes(), b"\n"]
30 .concat()
28 .concat()
31 .to_vec(),
29 .to_vec(),
32 ))
30 ))
33 })?;
31 })?;
34 let files = operation.run().map_err(|err| match err.kind {
32 let files = operation.run().map_err(|err| match err.kind {
35 ListTrackedFilesErrorKind::ParseError(_) => {
33 ListTrackedFilesErrorKind::ParseError(_) => {
36 CommandErrorKind::Abort(Some(
34 CommandErrorKind::Abort(Some(
37 // TODO find a better error message
35 // TODO find a better error message
38 b"abort: parse error\n".to_vec(),
36 b"abort: parse error\n".to_vec(),
39 ))
37 ))
40 }
38 }
41 })?;
39 })?;
42
40
43 let cwd = std::env::current_dir()
41 let cwd = std::env::current_dir()
44 .or_else(|e| Err(CommandErrorKind::CurrentDirNotFound(e)))?;
42 .or_else(|e| Err(CommandErrorKind::CurrentDirNotFound(e)))?;
45 let rooted_cwd = cwd
43 let rooted_cwd = cwd
46 .strip_prefix(operation_builder.get_root())
44 .strip_prefix(operation_builder.get_root())
47 .expect("cwd was already checked within the repository");
45 .expect("cwd was already checked within the repository");
48 let rooted_cwd = HgPathBuf::from(get_bytes_from_path(rooted_cwd));
46 let rooted_cwd = HgPathBuf::from(get_bytes_from_path(rooted_cwd));
49
47
50 let mut stdout = self.ui.stdout_buffer();
48 let mut stdout = ui.stdout_buffer();
51
49
52 for file in files {
50 for file in files {
53 stdout.write_all(relativize_path(file, &rooted_cwd).as_ref())?;
51 stdout.write_all(relativize_path(file, &rooted_cwd).as_ref())?;
54 stdout.write_all(b"\n")?;
52 stdout.write_all(b"\n")?;
55 }
53 }
56 stdout.flush()?;
54 stdout.flush()?;
57
55
58 Ok(())
56 Ok(())
59 }
57 }
60 }
58 }
@@ -1,34 +1,32 b''
1 use crate::commands::Command;
1 use crate::commands::Command;
2 use crate::error::CommandError;
2 use crate::error::CommandError;
3 use crate::ui::Ui;
3 use crate::ui::Ui;
4 use hg::operations::FindRoot;
4 use hg::operations::FindRoot;
5 use hg::utils::files::get_bytes_from_path;
5 use hg::utils::files::get_bytes_from_path;
6
6
7 pub const HELP_TEXT: &str = "
7 pub const HELP_TEXT: &str = "
8 Print the root directory of the current repository.
8 Print the root directory of the current repository.
9
9
10 Returns 0 on success.
10 Returns 0 on success.
11 ";
11 ";
12
12
13 pub struct RootCommand<'a> {
13 pub struct RootCommand {}
14 ui: &'a Ui,
15 }
16
14
17 impl<'a> RootCommand<'a> {
15 impl RootCommand {
18 pub fn new(ui: &'a Ui) -> Self {
16 pub fn new() -> Self {
19 RootCommand { ui }
17 RootCommand {}
20 }
18 }
21 }
19 }
22
20
23 impl<'a> Command<'a> for RootCommand<'a> {
21 impl Command for RootCommand {
24 fn run(&self) -> Result<(), CommandError> {
22 fn run(&self, ui: &Ui) -> Result<(), CommandError> {
25 let path_buf = FindRoot::new().run()?;
23 let path_buf = FindRoot::new().run()?;
26
24
27 let bytes = get_bytes_from_path(path_buf);
25 let bytes = get_bytes_from_path(path_buf);
28
26
29 // TODO use formating macro
27 // TODO use formating macro
30 self.ui.write_stdout(&[bytes.as_slice(), b"\n"].concat())?;
28 ui.write_stdout(&[bytes.as_slice(), b"\n"].concat())?;
31
29
32 Ok(())
30 Ok(())
33 }
31 }
34 }
32 }
@@ -1,57 +1,57 b''
1 use clap::App;
1 use clap::App;
2 use clap::AppSettings;
2 use clap::AppSettings;
3 use clap::SubCommand;
3 use clap::SubCommand;
4
4
5 mod commands;
5 mod commands;
6 mod error;
6 mod error;
7 mod exitcode;
7 mod exitcode;
8 mod ui;
8 mod ui;
9 use commands::Command;
9 use commands::Command;
10
10
11 fn main() {
11 fn main() {
12 let mut app = App::new("rhg")
12 let mut app = App::new("rhg")
13 .setting(AppSettings::AllowInvalidUtf8)
13 .setting(AppSettings::AllowInvalidUtf8)
14 .setting(AppSettings::SubcommandRequired)
14 .setting(AppSettings::SubcommandRequired)
15 .setting(AppSettings::VersionlessSubcommands)
15 .setting(AppSettings::VersionlessSubcommands)
16 .version("0.0.1")
16 .version("0.0.1")
17 .subcommand(
17 .subcommand(
18 SubCommand::with_name("root").about(commands::root::HELP_TEXT),
18 SubCommand::with_name("root").about(commands::root::HELP_TEXT),
19 )
19 )
20 .subcommand(
20 .subcommand(
21 SubCommand::with_name("files").about(commands::files::HELP_TEXT),
21 SubCommand::with_name("files").about(commands::files::HELP_TEXT),
22 );
22 );
23
23
24 let matches = app.clone().get_matches_safe().unwrap_or_else(|_| {
24 let matches = app.clone().get_matches_safe().unwrap_or_else(|_| {
25 std::process::exit(exitcode::UNIMPLEMENTED_COMMAND)
25 std::process::exit(exitcode::UNIMPLEMENTED_COMMAND)
26 });
26 });
27
27
28 let ui = ui::Ui::new();
28 let ui = ui::Ui::new();
29
29
30 let command_result = match matches.subcommand_name() {
30 let command_result = match matches.subcommand_name() {
31 Some(name) => match name {
31 Some(name) => match name {
32 "root" => commands::root::RootCommand::new(&ui).run(),
32 "root" => commands::root::RootCommand::new().run(&ui),
33 "files" => commands::files::FilesCommand::new(&ui).run(),
33 "files" => commands::files::FilesCommand::new().run(&ui),
34 _ => std::process::exit(exitcode::UNIMPLEMENTED_COMMAND),
34 _ => std::process::exit(exitcode::UNIMPLEMENTED_COMMAND),
35 },
35 },
36 _ => {
36 _ => {
37 match app.print_help() {
37 match app.print_help() {
38 Ok(_) => std::process::exit(exitcode::OK),
38 Ok(_) => std::process::exit(exitcode::OK),
39 Err(_) => std::process::exit(exitcode::ABORT),
39 Err(_) => std::process::exit(exitcode::ABORT),
40 };
40 };
41 }
41 }
42 };
42 };
43
43
44 match command_result {
44 match command_result {
45 Ok(_) => std::process::exit(exitcode::OK),
45 Ok(_) => std::process::exit(exitcode::OK),
46 Err(e) => {
46 Err(e) => {
47 let message = e.get_error_message_bytes();
47 let message = e.get_error_message_bytes();
48 if let Some(msg) = message {
48 if let Some(msg) = message {
49 match ui.write_stderr(&msg) {
49 match ui.write_stderr(&msg) {
50 Ok(_) => (),
50 Ok(_) => (),
51 Err(_) => std::process::exit(exitcode::ABORT),
51 Err(_) => std::process::exit(exitcode::ABORT),
52 };
52 };
53 };
53 };
54 e.exit()
54 e.exit()
55 }
55 }
56 }
56 }
57 }
57 }
General Comments 0
You need to be logged in to leave comments. Login now