summaryrefslogtreecommitdiffstats
path: root/lib/core/libimagrt
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2018-09-27 14:19:55 +0200
committerMatthias Beyer <mail@beyermatthias.de>2018-11-06 20:33:00 +0100
commitdb4e83f18f032b531b09e59f75d857541cdea919 (patch)
tree5f45ff328cbb98e0852533a3669d68b827bb14b7 /lib/core/libimagrt
parent8552843796de9628386e317b1c1452c5ef87c500 (diff)
Implement ID reporting
This patch adds the id reporting feature to libimagrt::runtime::Runtime, where processed ("touched") ids can be reported to the Runtime and then get printed to stdout if stdout is a pipe. Other output is automatically redirected to stderr if stdout is a pipe now.
Diffstat (limited to 'lib/core/libimagrt')
-rw-r--r--lib/core/libimagrt/src/runtime.rs54
1 files changed, 52 insertions, 2 deletions
diff --git a/lib/core/libimagrt/src/runtime.rs b/lib/core/libimagrt/src/runtime.rs
index 83876ec9..e00a93f6 100644
--- a/lib/core/libimagrt/src/runtime.rs
+++ b/lib/core/libimagrt/src/runtime.rs
@@ -23,6 +23,8 @@ use std::env;
use std::process::exit;
use std::io::Stdin;
use std::sync::Arc;
+use std::io::StdoutLock;
+use std::borrow::Borrow;
pub use clap::App;
use clap::AppSettings;
@@ -42,9 +44,11 @@ use io::OutputProxy;
use libimagerror::errors::ErrorMsg as EM;
use libimagerror::trace::*;
use libimagstore::store::Store;
+use libimagstore::storeid::StoreId;
use libimagstore::file_abstraction::InMemoryFileAbstraction;
use libimagutil::debug_result::DebugResult;
use spec::CliSpec;
+use atty;
/// The Runtime object
///
@@ -55,6 +59,9 @@ pub struct Runtime<'a> {
configuration: Option<Value>,
cli_matches: ArgMatches<'a>,
store: Store,
+
+ has_output_pipe: bool,
+ has_input_pipe: bool,
}
impl<'a> Runtime<'a> {
@@ -142,6 +149,9 @@ impl<'a> Runtime<'a> {
configuration: config,
rtp: rtp,
store: store,
+
+ has_output_pipe: !atty::is(atty::Stream::Stdout),
+ has_input_pipe: !atty::is(atty::Stream::Stdin),
})
.context(err_msg("Cannot instantiate runtime"))
.map_err(Error::from)
@@ -415,7 +425,11 @@ impl<'a> Runtime<'a> {
}
pub fn stdout(&self) -> OutputProxy {
- OutputProxy::Out(::std::io::stdout())
+ if self.has_output_pipe {
+ OutputProxy::Err(::std::io::stderr())
+ } else {
+ OutputProxy::Out(::std::io::stdout())
+ }
}
pub fn stderr(&self) -> OutputProxy {
@@ -423,7 +437,11 @@ impl<'a> Runtime<'a> {
}
pub fn stdin(&self) -> Option<Stdin> {
- Some(::std::io::stdin())
+ if self.has_input_pipe {
+ None
+ } else {
+ Some(::std::io::stdin())
+ }
}
/// Helper for handling subcommands which are not available.
@@ -504,6 +522,38 @@ impl<'a> Runtime<'a> {
.context(EM::IO)
.map_err(Error::from)
}
+
+ pub fn report_touched(&self, id: &StoreId) -> Result<()> {
+ let out = ::std::io::stdout();
+ let mut lock = out.lock();
+
+ self.report_touched_id(id, &mut lock)
+ }
+
+ pub fn report_all_touched<ID, I>(&self, ids: I) -> Result<()>
+ where ID: Borrow<StoreId> + Sized,
+ I: Iterator<Item = ID>
+ {
+ let out = ::std::io::stdout();
+ let mut lock = out.lock();
+
+ for id in ids {
+ self.report_touched_id(id.borrow(), &mut lock)?;
+ }
+
+ Ok(())
+ }
+
+ #[inline]
+ fn report_touched_id(&self, id: &StoreId, output: &mut StdoutLock) -> Result<()> {
+ use std::io::Write;
+
+ if self.has_output_pipe {
+ writeln!(output, "{}", id)?;
+ }
+
+ Ok(())
+ }
}
/// Exported for the `imag` command, you probably do not want to use that.