~matthiasbeyer/imag

7108f686dbc5ced63b372792f620bd035c00c50d — Matthias Beyer 1 year, 17 days ago 4e04612 + 9dedd71
Merge branch 'blackhole-stdout-when-piping' into master

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
M lib/core/libimagrt/Cargo.toml => lib/core/libimagrt/Cargo.toml +1 -0
@@ 27,6 27,7 @@ itertools = "0.8.0"
ansi_term = "0.12"
atty = "0.2.11"
anyhow = "1"
indoc = "0.3"

serde_derive = "1.0.94"
serde = "1.0.94"

M lib/core/libimagrt/src/io.rs => lib/core/libimagrt/src/io.rs +1 -1
@@ 86,7 86,7 @@ impl<'a> Write for LockedOutputProxy<'a> {
        match *self {
            LockedOutputProxy::Out(ref mut r) => r.write(buf),
            LockedOutputProxy::Err(ref mut r) => r.write(buf),
            LockedOutputProxy::Sink   => Ok(0),
            LockedOutputProxy::Sink   => Ok(buf.len()),
        }
    }


M lib/core/libimagrt/src/lib.rs => lib/core/libimagrt/src/lib.rs +1 -0
@@ 44,6 44,7 @@ extern crate handlebars;
extern crate serde;
#[macro_use] extern crate anyhow;
#[macro_use] extern crate toml_query;
#[macro_use] extern crate indoc;

extern crate clap;
extern crate toml;

M lib/core/libimagrt/src/runtime.rs => lib/core/libimagrt/src/runtime.rs +30 -5
@@ 61,6 61,7 @@ pub struct Runtime<'a> {

    input_data: bool,
    output_data: bool,
    blackhole_stdout: bool,
}

impl<'a> Runtime<'a> {


@@ 138,15 139,17 @@ impl<'a> Runtime<'a> {
            Store::new(storepath, &config)
        };

        let has_output_pipe = !atty::is(atty::Stream::Stdout);
        let has_input_pipe  = !atty::is(atty::Stream::Stdin);
        let input_data      = matches.is_present("input-pipe-data");
        let output_data     = matches.is_present("output-pipe-data");
        let has_output_pipe  = !atty::is(atty::Stream::Stdout);
        let has_input_pipe   = !atty::is(atty::Stream::Stdin);
        let input_data       = matches.is_present("input-pipe-data");
        let output_data      = matches.is_present("output-pipe-data");
        let blackhole_stdout = matches.is_present("blackhole-stdout");

        debug!("has output pipe  = {}", has_output_pipe);
        debug!("has input pipe   = {}", has_input_pipe);
        debug!("input pipe data  = {}", input_data);
        debug!("output pipe data = {}", output_data);
        debug!("blackhole output = {}", blackhole_stdout);

        store_result.map(|store| Runtime {
            cli_matches: matches,


@@ 158,6 161,7 @@ impl<'a> Runtime<'a> {
            has_input_pipe,
            input_data,
            output_data,
            blackhole_stdout,
        })
        .context(anyhow!("Cannot instantiate runtime"))
        .map_err(Error::from)


@@ 257,7 261,22 @@ impl<'a> Runtime<'a> {
                 .takes_value(false)
                 .multiple(false)
                 .help("Do not print imag ids to stdout if stdout is a pipe.")
                 )
            )

            .arg(Arg::with_name("blackhole-stdout")
                 .long("blackhole")
                 .short("B")
                 .required(false)
                 .takes_value(false)
                 .multiple(false)
                 .help("Do not print normal output")
                 .long_help(indoc!(r#"
                 This flag can be used to ignore output.
                 For example, if imag is used in a piping context, which pipes the Store IDs, the
                 normal output is automatically redirected to stderr. To ignore the normal output
                 instead, this flag can be passed.
                 "#))
             )

    }



@@ 420,6 439,10 @@ impl<'a> Runtime<'a> {
        self.has_input_pipe
    }

    pub fn output_is_blackholed(&self) -> bool {
        self.blackhole_stdout
    }

    /// Check whether the runtime expects imag ids from stdin
    pub fn ids_from_stdin(&self) -> bool {
        self.input_is_pipe() && !self.input_data


@@ 438,6 461,8 @@ impl<'a> Runtime<'a> {
    pub fn stdout(&self) -> OutputProxy {
        if self.output_is_pipe() && self.output_data {
            OutputProxy::Out(::std::io::stdout())
        } else if self.output_is_blackholed() {
            OutputProxy::Sink
        } else {
            OutputProxy::Err(::std::io::stderr())
        }