Details
Details
- Reviewers
- None
- Group Reviewers
hg-reviewers
Diff Detail
Diff Detail
- Repository
- rHG Mercurial
- Branch
- default
- Lint
No Linters Available - Unit
No Unit Test Coverage
hg-reviewers |
No Linters Available |
No Unit Test Coverage |
Path | Packages | |||
---|---|---|---|---|
M | rust/rhg/src/commands.rs (1 line) | |||
A | M | rust/rhg/src/commands/files.rs (68 lines) | ||
M | rust/rhg/src/error.rs (4 lines) |
Commit | Parents | Author | Summary | Date |
---|---|---|---|---|
ba51e213d071 | 9cb0831d0550 | Antoine Cezar | Jul 21 2020, 10:02 AM |
pub mod files; | |||||
pub mod root; | pub mod root; | ||||
use crate::error::CommandError; | use crate::error::CommandError; | ||||
/// The common trait for rhg commands | /// The common trait for rhg commands | ||||
/// | /// | ||||
/// Normalize the interface of the commands provided by rhg | /// Normalize the interface of the commands provided by rhg | ||||
pub trait Command { | pub trait Command { | ||||
fn run(&self) -> Result<(), CommandError>; | fn run(&self) -> Result<(), CommandError>; | ||||
} | } |
use crate::commands::Command; | |||||
use crate::error::{CommandError, CommandErrorKind}; | |||||
use crate::ui::Ui; | |||||
use hg::operations::Operation; | |||||
use hg::operations::{FindRootError, FindRootErrorKind}; | |||||
use hg::operations::{ | |||||
ListTrackedFiles, ListTrackedFilesError, ListTrackedFilesErrorKind, | |||||
}; | |||||
use hg::utils::files::get_bytes_from_path; | |||||
use hg::utils::hg_path::HgPathBuf; | |||||
use std::path::PathBuf; | |||||
pub const HELP_TEXT: &str = " | |||||
List tracked files. | |||||
Returns 0 on success. | |||||
"; | |||||
pub struct FilesCommand { | |||||
ui: Ui, | |||||
} | |||||
impl FilesCommand { | |||||
pub fn new(ui: Ui) -> Self { | |||||
FilesCommand { ui } | |||||
} | |||||
} | |||||
impl Command for FilesCommand { | |||||
fn run(&self) -> Result<(), CommandError> { | |||||
let files = | |||||
ListTrackedFiles::new() | |||||
.run() | |||||
.map_err(|err| match err.kind { | |||||
ListTrackedFilesErrorKind::FindRootError(err) => { | |||||
match err.kind { | |||||
FindRootErrorKind::RootNotFound(path) => { | |||||
CommandErrorKind::RootNotFound(path) | |||||
} | |||||
FindRootErrorKind::GetCurrentDirError(e) => { | |||||
CommandErrorKind::CurrentDirNotFound(e) | |||||
} | |||||
} | |||||
} | |||||
ListTrackedFilesErrorKind::IoError(e) => { | |||||
CommandErrorKind::Abort(Some( | |||||
[b"abort: ", e.to_string().as_bytes(), b"\n"] | |||||
.concat() | |||||
.to_vec(), | |||||
)) | |||||
} | |||||
ListTrackedFilesErrorKind::ParseError(_) => { | |||||
CommandErrorKind::Abort(Some( | |||||
// TODO find a better error message | |||||
b"abort: parse error\n".to_vec(), | |||||
)) | |||||
} | |||||
})?; | |||||
for file in files { | |||||
let bytes = file.as_bytes(); | |||||
// TODO use formating macro | |||||
self.ui.write_stdout(&[bytes, b"\n"].concat())?; | |||||
} | |||||
Ok(()) | |||||
} | |||||
} |
/// The root of the repository cannot be found | /// The root of the repository cannot be found | ||||
RootNotFound(PathBuf), | RootNotFound(PathBuf), | ||||
/// The current directory cannot be found | /// The current directory cannot be found | ||||
CurrentDirNotFound(std::io::Error), | CurrentDirNotFound(std::io::Error), | ||||
/// The standard output stream cannot be written to | /// The standard output stream cannot be written to | ||||
StdoutError, | StdoutError, | ||||
/// The standard error stream cannot be written to | /// The standard error stream cannot be written to | ||||
StderrError, | StderrError, | ||||
/// The command aborted | |||||
Abort(Option<Vec<u8>>), | |||||
} | } | ||||
impl CommandErrorKind { | impl CommandErrorKind { | ||||
pub fn get_exit_code(&self) -> exitcode::ExitCode { | pub fn get_exit_code(&self) -> exitcode::ExitCode { | ||||
match self { | match self { | ||||
CommandErrorKind::RootNotFound(_) => exitcode::ABORT, | CommandErrorKind::RootNotFound(_) => exitcode::ABORT, | ||||
CommandErrorKind::CurrentDirNotFound(_) => exitcode::ABORT, | CommandErrorKind::CurrentDirNotFound(_) => exitcode::ABORT, | ||||
CommandErrorKind::StdoutError => exitcode::ABORT, | CommandErrorKind::StdoutError => exitcode::ABORT, | ||||
CommandErrorKind::StderrError => exitcode::ABORT, | CommandErrorKind::StderrError => exitcode::ABORT, | ||||
CommandErrorKind::Abort(_) => exitcode::ABORT, | |||||
} | } | ||||
} | } | ||||
pub fn get_error_message_bytes(&self) -> Option<Vec<u8>> { | pub fn get_error_message_bytes(&self) -> Option<Vec<u8>> { | ||||
match self { | match self { | ||||
// TODO use formating macro | // TODO use formating macro | ||||
CommandErrorKind::RootNotFound(path) => { | CommandErrorKind::RootNotFound(path) => { | ||||
let bytes = get_bytes_from_path(path); | let bytes = get_bytes_from_path(path); | ||||
CommandErrorKind::CurrentDirNotFound(e) => Some( | CommandErrorKind::CurrentDirNotFound(e) => Some( | ||||
[ | [ | ||||
b"abort: error getting current working directory: ", | b"abort: error getting current working directory: ", | ||||
e.to_string().as_bytes(), | e.to_string().as_bytes(), | ||||
b"\n", | b"\n", | ||||
] | ] | ||||
.concat(), | .concat(), | ||||
), | ), | ||||
CommandErrorKind::Abort(message) => message.to_owned(), | |||||
_ => None, | _ => None, | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/// The error type for the Command trait | /// The error type for the Command trait | ||||
#[derive(Debug)] | #[derive(Debug)] | ||||
pub struct CommandError { | pub struct CommandError { |