Remove calls to exit() and replace them with error propagation up to main()

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
Matthias Beyer 2019-10-19 08:54:57 +02:00
parent 9b8faec86e
commit eb8912ffe6
2 changed files with 36 additions and 41 deletions

View file

@ -24,6 +24,7 @@ log = "0.4.6"
toml = "0.5.1" toml = "0.5.1"
toml-query = "0.9.2" toml-query = "0.9.2"
failure = "0.1.5" failure = "0.1.5"
resiter = "0.3.0"
libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagstore" } libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagstore" }
libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" } libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" }

View file

@ -39,6 +39,7 @@ extern crate clap;
extern crate toml; extern crate toml;
extern crate toml_query; extern crate toml_query;
#[macro_use] extern crate failure; #[macro_use] extern crate failure;
extern crate resiter;
#[cfg(test)] #[cfg(test)]
extern crate env_logger; extern crate env_logger;
@ -48,18 +49,17 @@ extern crate libimagstore;
extern crate libimagrt; extern crate libimagrt;
use std::io::Write; use std::io::Write;
use std::result::Result as RResult;
use failure::Fallible as Result; use failure::Fallible as Result;
use failure::err_msg;
use failure::Error;
use resiter::Map;
use resiter::AndThen;
use clap::App; use clap::App;
use libimagstore::storeid::StoreId; use libimagstore::storeid::StoreId;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::application::ImagApplication; use libimagrt::application::ImagApplication;
use libimagerror::trace::MapErrTrace;
use libimagerror::iter::TraceIterator;
use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode;
mod ui; mod ui;
@ -72,48 +72,42 @@ impl ImagApplication for ImagIds {
fn run(rt: Runtime) -> Result<()> { fn run(rt: Runtime) -> Result<()> {
let print_storepath = rt.cli().is_present("print-storepath"); let print_storepath = rt.cli().is_present("print-storepath");
let iterator = if rt.ids_from_stdin() {
debug!("Fetching IDs from stdin...");
let ids = rt
.ids::<crate::ui::PathProvider>()
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("No ids supplied");
::std::process::exit(1);
});
Box::new(ids.into_iter().map(Ok))
as Box<dyn Iterator<Item = RResult<StoreId, _>>>
} else {
Box::new(rt.store().entries().map_err_trace_exit_unwrap())
as Box<dyn Iterator<Item = RResult<StoreId, _>>>
}
.trace_unwrap_exit()
.map(|id| if print_storepath {
(Some(rt.store().path()), id)
} else {
(None, id)
});
let mut stdout = rt.stdout(); let mut stdout = rt.stdout();
trace!("Got output: {:?}", stdout); trace!("Got output: {:?}", stdout);
iterator.for_each(|(storepath, id)| { let mut process = |iter: &mut dyn Iterator<Item = Result<StoreId>>| -> Result<()> {
rt.report_touched(&id).unwrap_or_exit(); iter.map_ok(|id| if print_storepath {
if !rt.output_is_pipe() { (Some(rt.store().path()), id)
let id = id.to_str().map_err_trace_exit_unwrap(); } else {
trace!("Writing to {:?}", stdout); (None, id)
}).and_then_ok(|(storepath, id)| {
if !rt.output_is_pipe() {
let id = id.to_str()?;
trace!("Writing to {:?}", stdout);
let result = if let Some(store) = storepath { if let Some(store) = storepath {
writeln!(stdout, "{}/{}", store.display(), id) writeln!(stdout, "{}/{}", store.display(), id)?;
} else { } else {
writeln!(stdout, "{}", id) writeln!(stdout, "{}", id)?;
}; }
}
result.to_exit_code().unwrap_or_exit(); rt.report_touched(&id).map_err(Error::from)
} })
}); .collect::<Result<()>>()
};
Ok(()) if rt.ids_from_stdin() {
debug!("Fetching IDs from stdin...");
let mut iter = rt.ids::<crate::ui::PathProvider>()?
.ok_or_else(|| err_msg("No ids supplied"))?
.into_iter()
.map(Ok);
process(&mut iter)
} else {
process(&mut rt.store().entries()?)
}
} }
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> { fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {