Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 44 additions & 14 deletions src/cargo/core/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,27 +147,57 @@ impl MultiShell {
}

impl Shell {
pub fn create(out: Box<Write + Send>, config: ShellConfig) -> Shell {
pub fn create<T: FnMut() -> Box<Write + Send>>(mut out_fn: T, config: ShellConfig) -> Shell {
let term = match Shell::get_term(out_fn()) {
Ok(t) => t,
Err(_) => NoColor(out_fn())
};

Shell {
terminal: term,
config: config,
}
}

#[cfg(any(windows))]
fn get_term(out: Box<Write + Send>) -> CargoResult<AdequateTerminal> {
// Check if the creation of a console will succeed
if ::term::WinConsole::new(vec![0u8; 0]).is_ok() {
let t = try!(::term::WinConsole::new(out));
if !t.supports_color() {
Ok(NoColor(Box::new(t)))
} else {
Ok(Colored(Box::new(t)))
}
} else {
// If we fail to get a windows console, we try to get a `TermInfo` one
Ok(Shell::get_terminfo_term(out))
}
}

#[cfg(any(unix))]
fn get_term(out: Box<Write + Send>) -> CargoResult<AdequateTerminal> {
Ok(Shell::get_terminfo_term(out))
}

fn get_terminfo_term(out: Box<Write + Send>) -> AdequateTerminal {
// Use `TermInfo::from_env()` and `TerminfoTerminal::supports_color()`
// to determine if creation of a TerminfoTerminal is possible regardless
// of the tty status. --color options are parsed after Shell creation so
// always try to create a terminal that supports color output. Fall back
// to a no-color terminal regardless of whether or not a tty is present
// and if color output is not possible.
Shell {
terminal: match ::term::terminfo::TermInfo::from_env() {
Ok(ti) => {
let term = TerminfoTerminal::new_with_terminfo(out, ti);
if !term.supports_color() {
NoColor(term.into_inner())
} else {
// Color output is possible.
Colored(Box::new(term))
}
},
Err(_) => NoColor(out),
match ::term::terminfo::TermInfo::from_env() {
Ok(ti) => {
let term = TerminfoTerminal::new_with_terminfo(out, ti);
if !term.supports_color() {
NoColor(term.into_inner())
} else {
// Color output is possible.
Colored(Box::new(term))
}
},
config: config,
Err(_) => NoColor(out),
}
}

Expand Down
8 changes: 3 additions & 5 deletions src/cargo/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use core::shell::Verbosity::{Verbose};
use core::shell::ColorConfig::{Auto};
use term::color::{BLACK};

pub use util::{CargoError, CliError, CliResult, human, Config, ChainError};
pub use util::{CargoError, CargoResult, CliError, CliResult, human, Config, ChainError};

macro_rules! bail {
($($fmt:tt)*) => (
Expand Down Expand Up @@ -137,16 +137,14 @@ pub fn shell(verbosity: Verbosity, color_config: ColorConfig) -> MultiShell {
}

let tty = isatty(Output::Stderr);
let stderr = Box::new(io::stderr());

let config = ShellConfig { color_config: color_config, tty: tty };
let err = Shell::create(stderr, config);
let err = Shell::create(|| Box::new(io::stderr()), config);

let tty = isatty(Output::Stdout);
let stdout = Box::new(io::stdout());

let config = ShellConfig { color_config: color_config, tty: tty };
let out = Shell::create(stdout, config);
let out = Shell::create(|| Box::new(io::stdout()), config);

return MultiShell::new(out, err, verbosity);

Expand Down
8 changes: 4 additions & 4 deletions tests/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fn non_tty() {
let config = ShellConfig { color_config: Auto, tty: false };
let a = Arc::new(Mutex::new(Vec::new()));

Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| {
Shell::create(|| Box::new(Sink(a.clone())), config).tap(|shell| {
shell.say("Hey Alex", color::RED).unwrap();
});
let buf = a.lock().unwrap().clone();
Expand All @@ -43,7 +43,7 @@ fn color_explicitly_disabled() {
let config = ShellConfig { color_config: Never, tty: true };
let a = Arc::new(Mutex::new(Vec::new()));

Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| {
Shell::create(|| Box::new(Sink(a.clone())), config).tap(|shell| {
shell.say("Hey Alex", color::RED).unwrap();
});
let buf = a.lock().unwrap().clone();
Expand All @@ -58,7 +58,7 @@ fn colored_shell() {
let config = ShellConfig { color_config: Auto, tty: true };
let a = Arc::new(Mutex::new(Vec::new()));

Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| {
Shell::create(|| Box::new(Sink(a.clone())), config).tap(|shell| {
shell.say("Hey Alex", color::RED).unwrap();
});
let buf = a.lock().unwrap().clone();
Expand All @@ -75,7 +75,7 @@ fn color_explicitly_enabled() {
let config = ShellConfig { color_config: Always, tty: false };
let a = Arc::new(Mutex::new(Vec::new()));

Shell::create(Box::new(Sink(a.clone())), config).tap(|shell| {
Shell::create(|| Box::new(Sink(a.clone())), config).tap(|shell| {
shell.say("Hey Alex", color::RED).unwrap();
});
let buf = a.lock().unwrap().clone();
Expand Down