Implement pipe magic in libimagrt
When we merged the changes in libimagrt so that it automatically detects whether stdin/stdout is a TTY and provides the user with stderr in case stdout is not a TTY, we forgot that things like imag foo | grep bar becomes impossible with that, because imag detects that stdout is not a tty and automatically uses stderr for output. But in this case, we don't want that. The output has to be stdout in this case. With this change, we have a flag in the runtime ("--pipe-magic" or "-P", globally available) which turns on "pipe magic". The expected behaviour is the following, if "-P" is passed: * If stdout is a TTY, we print to stdout * If stdout is not a TTY, we print to stderr * If stdin is not a TTY, we do not provide it If "-P" is not passed, we allow the user of libimagrt to use stdin for interactive stuff (the interactive stuff is not yet implemented). Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
parent
a0b989efdf
commit
ce0bd9298a
1 changed files with 22 additions and 6 deletions
|
@ -49,6 +49,7 @@ pub struct Runtime<'a> {
|
||||||
configuration: Option<Value>,
|
configuration: Option<Value>,
|
||||||
cli_matches: ArgMatches<'a>,
|
cli_matches: ArgMatches<'a>,
|
||||||
store: Store,
|
store: Store,
|
||||||
|
use_pipe_magic: bool,
|
||||||
stdin_is_tty: bool,
|
stdin_is_tty: bool,
|
||||||
stdout_is_tty: bool,
|
stdout_is_tty: bool,
|
||||||
}
|
}
|
||||||
|
@ -148,12 +149,15 @@ impl<'a> Runtime<'a> {
|
||||||
Store::new(storepath, &config)
|
Store::new(storepath, &config)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let pipe_magic = matches.is_present(Runtime::pipe_magic_name());
|
||||||
|
|
||||||
store_result.map(|store| {
|
store_result.map(|store| {
|
||||||
Runtime {
|
Runtime {
|
||||||
cli_matches: matches,
|
cli_matches: matches,
|
||||||
configuration: config,
|
configuration: config,
|
||||||
rtp: rtp,
|
rtp: rtp,
|
||||||
store: store,
|
store: store,
|
||||||
|
use_pipe_magic: pipe_magic,
|
||||||
stdout_is_tty: ::atty::is(::atty::Stream::Stdout),
|
stdout_is_tty: ::atty::is(::atty::Stream::Stdout),
|
||||||
stdin_is_tty: ::atty::is(::atty::Stream::Stdin),
|
stdin_is_tty: ::atty::is(::atty::Stream::Stdin),
|
||||||
}
|
}
|
||||||
|
@ -249,6 +253,13 @@ impl<'a> Runtime<'a> {
|
||||||
.takes_value(true)
|
.takes_value(true)
|
||||||
.value_name("LOGDESTS"))
|
.value_name("LOGDESTS"))
|
||||||
|
|
||||||
|
.arg(Arg::with_name(Runtime::pipe_magic_name())
|
||||||
|
.long(Runtime::pipe_magic_name())
|
||||||
|
.short("P")
|
||||||
|
.help("Use pipe-detection. With this flag, imag expects a JSON store on STDIN if stdin is not a TTY and prints the store to STDOUT if it is not a TTY.")
|
||||||
|
.required(false)
|
||||||
|
.takes_value(false))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the argument names of the Runtime which are available
|
/// Get the argument names of the Runtime which are available
|
||||||
|
@ -338,6 +349,11 @@ impl<'a> Runtime<'a> {
|
||||||
"logging-destinations"
|
"logging-destinations"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the argument name for pipe magic
|
||||||
|
pub fn pipe_magic_name() -> &'static str {
|
||||||
|
"pipe-magic"
|
||||||
|
}
|
||||||
|
|
||||||
/// Initialize the internal logger
|
/// Initialize the internal logger
|
||||||
fn init_logger(matches: &ArgMatches, config: Option<&Value>) {
|
fn init_logger(matches: &ArgMatches, config: Option<&Value>) {
|
||||||
use log::set_max_level;
|
use log::set_max_level;
|
||||||
|
@ -446,10 +462,10 @@ impl<'a> Runtime<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stdout(&self) -> OutputProxy {
|
pub fn stdout(&self) -> OutputProxy {
|
||||||
if self.stdout_is_tty {
|
if self.use_pipe_magic && !self.stdout_is_tty {
|
||||||
OutputProxy::Out(::std::io::stdout())
|
|
||||||
} else {
|
|
||||||
OutputProxy::Err(::std::io::stderr())
|
OutputProxy::Err(::std::io::stderr())
|
||||||
|
} else {
|
||||||
|
OutputProxy::Out(::std::io::stdout())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,10 +474,10 @@ impl<'a> Runtime<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stdin(&self) -> Option<Stdin> {
|
pub fn stdin(&self) -> Option<Stdin> {
|
||||||
if self.stdin_is_tty {
|
if self.use_pipe_magic && !self.stdin_is_tty {
|
||||||
Some(::std::io::stdin())
|
|
||||||
} else {
|
|
||||||
None
|
None
|
||||||
|
} else {
|
||||||
|
Some(::std::io::stdin())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue