native status: support HGPLAIN color suppression

Summary: Plus a minor refactoring to use the io::IsTty trait in edenfs_client::status instead of calling into libc directly.

Reviewed By: quark-zju

Differential Revision: D31156633

fbshipit-source-id: 218f06a4e64836be88b4afac98dcfa140373c730
This commit is contained in:
Muir Manders 2021-09-27 09:51:49 -07:00 committed by Facebook GitHub Bot
parent 7d4cd5f0dd
commit 8e4deea41b
4 changed files with 14 additions and 16 deletions

View File

@ -9,7 +9,6 @@ anyhow = "1.0"
byteorder = "1.3" byteorder = "1.3"
chrono = { version = "0.4", features = ["clock", "serde", "std"], default-features = false } chrono = { version = "0.4", features = ["clock", "serde", "std"], default-features = false }
clidispatch = { path = "../clidispatch" } clidispatch = { path = "../clidispatch" }
libc = "0.2.98"
sha2 = "0.8" sha2 = "0.8"
thrift-types = { path = "../thrift-types" } thrift-types = { path = "../thrift-types" }
tokio = { version = "1.10", features = ["full", "test-util", "tracing"] } tokio = { version = "1.10", features = ["full", "test-util", "tracing"] }

View File

@ -10,7 +10,10 @@ use thrift_types::edenfs as eden;
use crate::path_relativizer::PathRelativizer; use crate::path_relativizer::PathRelativizer;
use anyhow::{bail, ensure, Error, Result}; use anyhow::{bail, ensure, Error, Result};
use byteorder::{BigEndian, ByteOrder}; use byteorder::{BigEndian, ByteOrder};
use clidispatch::{errors::FallbackToPython, io::IO}; use clidispatch::{
errors::FallbackToPython,
io::{CanColor, IO},
};
use eden::client::EdenService; use eden::client::EdenService;
use eden::{GetScmStatusParams, GetScmStatusResult, ScmFileStatus, ScmStatus}; use eden::{GetScmStatusParams, GetScmStatusResult, ScmFileStatus, ScmStatus};
#[cfg(unix)] #[cfg(unix)]
@ -25,7 +28,6 @@ use std::io;
use std::io::BufReader; use std::io::BufReader;
use std::io::Read; use std::io::Read;
#[cfg(unix)] #[cfg(unix)]
use std::os::unix::io::AsRawFd;
use std::path::Path; use std::path::Path;
use std::path::PathBuf; use std::path::PathBuf;
use std::str; use std::str;
@ -119,7 +121,7 @@ async fn maybe_status_fastpath_internal(
} }
let stdout = io::stdout(); let stdout = io::stdout();
let use_color = should_colorize_output(&stdout); let use_color = stdout.can_color();
let status = get_status_helper( let status = get_status_helper(
&client, &client,
@ -199,18 +201,6 @@ fn needs_morestatus_extension(hg_dir: &Path, p2: &[u8; 20]) -> bool {
false false
} }
#[cfg(unix)]
fn should_colorize_output(stdout: &dyn AsRawFd) -> bool {
let fd = stdout.as_raw_fd();
let istty = unsafe { libc::isatty(fd as i32) } != 0;
istty
}
#[cfg(not(unix))]
fn should_colorize_output(stdout: &io::Stdout) -> bool {
false
}
fn is_unknown_method_error(error: &eden::errors::eden_service::GetScmStatusV2Error) -> bool { fn is_unknown_method_error(error: &eden::errors::eden_service::GetScmStatusV2Error) -> bool {
if let eden::errors::eden_service::GetScmStatusV2Error::ApplicationException(ref e) = error { if let eden::errors::eden_service::GetScmStatusV2Error::ApplicationException(ref e) = error {
e.type_ == ApplicationExceptionErrorCode::UnknownMethod e.type_ == ApplicationExceptionErrorCode::UnknownMethod

View File

@ -8,6 +8,7 @@ edition = "2018"
[dependencies] [dependencies]
atty = "0.2" atty = "0.2"
configmodel = { path = "../configmodel" } configmodel = { path = "../configmodel" }
configparser = { path = "../configparser" }
once_cell = "1.4" once_cell = "1.4"
parking_lot = "0.10.2" parking_lot = "0.10.2"
pipe = "0.2" pipe = "0.2"

View File

@ -90,6 +90,14 @@ pub trait IsTty {
} }
} }
pub trait CanColor: IsTty {
fn can_color(&self) -> bool {
self.is_tty() && !configparser::hg::is_plain(Some("color"))
}
}
impl<T: IsTty> CanColor for T {}
pub trait Read: io::Read + IsTty + Any + Send + Sync { pub trait Read: io::Read + IsTty + Any + Send + Sync {
fn as_any(&self) -> &dyn Any; fn as_any(&self) -> &dyn Any;