[Request] [++- ] D8612: rhg: add RootCommand using hg-core FindRoot operation to prepare `hg root`
acezar (Antoine Cezar)
phabricator at mercurial-scm.org
Fri Jun 5 14:33:03 UTC 2020
acezar created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.
REVISION SUMMARY
The println macro is not used to avoid string usage.
Dealing only with bytes allows us to be compatible with any encoding
and not just WTF8.
Later on, format macro will be made to have more readable code.
REPOSITORY
rHG Mercurial
BRANCH
default
REVISION DETAIL
https://phab.mercurial-scm.org/D8612
AFFECTED FILES
rust/Cargo.lock
rust/rhg/Cargo.toml
rust/rhg/src/commands/mod.rs
rust/rhg/src/commands/root.rs
rust/rhg/src/error.rs
rust/rhg/src/exitcode.rs
CHANGE DETAILS
diff --git a/rust/rhg/src/exitcode.rs b/rust/rhg/src/exitcode.rs
--- a/rust/rhg/src/exitcode.rs
+++ b/rust/rhg/src/exitcode.rs
@@ -1,4 +1,10 @@
pub type ExitCode = i32;
+/// Successful exit
+pub const OK: ExitCode = 0;
+
+/// Generic abort
+pub const ABORT: ExitCode = 255;
+
/// Command not implemented by rhg
pub const UNIMPLEMENTED_COMMAND: ExitCode = 252;
diff --git a/rust/rhg/src/error.rs b/rust/rhg/src/error.rs
--- a/rust/rhg/src/error.rs
+++ b/rust/rhg/src/error.rs
@@ -1,4 +1,32 @@
+use crate::exitcode;
+use std::convert::From;
+
+/// The kind of command error
+#[derive(Debug, PartialEq)]
+pub enum CommandErrorKind {
+ /// The command finished without error
+ Ok,
+ /// The root of the repository cannot be found
+ RootNotFound,
+}
+
+impl CommandErrorKind {
+ pub fn get_exit_code(&self) -> exitcode::ExitCode {
+ match self {
+ CommandErrorKind::Ok => exitcode::OK,
+ CommandErrorKind::RootNotFound => exitcode::ABORT,
+ }
+ }
+}
/// The error type for the Command trait
#[derive(Debug, PartialEq)]
-pub struct CommandError {}
+pub struct CommandError {
+ pub kind: CommandErrorKind,
+}
+
+impl From<CommandErrorKind> for CommandError {
+ fn from(kind: CommandErrorKind) -> Self {
+ CommandError { kind }
+ }
+}
diff --git a/rust/rhg/src/commands/root.rs b/rust/rhg/src/commands/root.rs
new file mode 100644
--- /dev/null
+++ b/rust/rhg/src/commands/root.rs
@@ -0,0 +1,79 @@
+use crate::commands::Command;
+use crate::error::{CommandError, CommandErrorKind};
+use hg::operations::{FindRoot, FindRootError, FindRootErrorKind, Operation};
+use hg::utils::files::get_bytes_from_path;
+use std::io::Write;
+use std::path::PathBuf;
+
+pub const HELP_TEXT: &str = "
+Print the root directory of the current repository.
+
+Returns 0 on success.
+";
+
+pub struct RootCommand;
+
+impl RootCommand {
+ fn display_found_path(path_buf: PathBuf) -> Result<(), CommandError> {
+ // TODO use formating macro
+ let mut stdout = std::io::stdout();
+ let bytes = get_bytes_from_path(path_buf);
+
+ stdout
+ .write_all(&[bytes.as_slice(), b"\n"].concat())
+ .expect("Should be able to write to stdout");
+
+ Err(CommandErrorKind::Ok.into())
+ }
+
+ fn display_error(error: FindRootError) -> Result<(), CommandError> {
+ match error.kind {
+ FindRootErrorKind::RootNotFound => {
+ let current_dir = match error.current_dir {
+ Some(path) => path,
+ None => panic!("This should not happen"),
+ };
+
+ // TODO use formating macro
+ let mut stderr = std::io::stderr();
+ let bytes = get_bytes_from_path(current_dir);
+
+ stderr
+ .write_all(
+ &[
+ b"abandon : no repository found in ",
+ bytes.as_slice(),
+ b" (.hg not found) !\n",
+ ]
+ .concat(),
+ )
+ .expect("Should be able to write to stderr");
+ }
+ FindRootErrorKind::GetCurrentDirError => {
+ // TODO use formating macro
+ let mut stderr = std::io::stderr();
+
+ stderr
+ .write_all(
+ &concat!(
+ "Current directory does not exists",
+ "or permissions are insufficient to get access to it"
+ )
+ .as_bytes(),
+ )
+ .expect("Should be able to write to stderr");
+ }
+ }
+ Err(CommandErrorKind::RootNotFound.into())
+ }
+}
+
+impl Command for RootCommand {
+ fn run() -> Result<(), CommandError> {
+ let operation = FindRoot::new();
+ match operation.run() {
+ Ok(path_buf) => RootCommand::display_found_path(path_buf),
+ Err(e) => RootCommand::display_error(e),
+ }
+ }
+}
diff --git a/rust/rhg/src/commands/mod.rs b/rust/rhg/src/commands/mod.rs
--- a/rust/rhg/src/commands/mod.rs
+++ b/rust/rhg/src/commands/mod.rs
@@ -1,3 +1,4 @@
+pub mod root;
use crate::error::CommandError;
/// The common trait for rhg commands
diff --git a/rust/rhg/Cargo.toml b/rust/rhg/Cargo.toml
--- a/rust/rhg/Cargo.toml
+++ b/rust/rhg/Cargo.toml
@@ -5,4 +5,5 @@
edition = "2018"
[dependencies]
+hg-core = { path = "../hg-core"}
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -489,6 +489,9 @@
[[package]]
name = "rhg"
version = "0.1.0"
+dependencies = [
+ "hg-core 0.1.0",
+]
[[package]]
name = "rustc_version"
To: acezar, #hg-reviewers
Cc: mercurial-patches, mercurial-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mercurial-scm.org/pipermail/mercurial-patches/attachments/20200605/432ed360/attachment-0001.html>
More information about the Mercurial-patches
mailing list