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 e740b2faaa
commit e67f5374be

View file

@ -47,22 +47,20 @@ extern crate libimagutil;
mod ui; mod ui;
use std::process::exit;
use std::io::Write; use std::io::Write;
use failure::Error;
use failure::Fallible as Result; use failure::Fallible as Result;
use failure::Error;
use failure::err_msg;
use clap::App; use clap::App;
use libimagerror::trace::MapErrTrace;
use libimagerror::exit::ExitUnwrap;
use libimagrt::application::ImagApplication; use libimagrt::application::ImagApplication;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagentryref::reference::Ref; use libimagentryref::reference::Ref;
use libimagentryref::reference::MutRef;
use libimagentryref::reference::RefFassade; use libimagentryref::reference::RefFassade;
use libimagentryref::hasher::default::DefaultHasher; use libimagentryref::hasher::default::DefaultHasher;
use libimagentryref::util::get_ref_config; use libimagentryref::util::get_ref_config;
use libimagentryref::reference::MutRef;
/// Marker enum for implementing ImagApplication on /// Marker enum for implementing ImagApplication on
/// ///
@ -80,15 +78,16 @@ impl ImagApplication for ImagRef {
"list-dead" => list_dead(&rt), "list-dead" => list_dead(&rt),
other => { other => {
debug!("Unknown command"); debug!("Unknown command");
let _ = rt.handle_unknown_subcommand("imag-ref", other, rt.cli()) if rt.handle_unknown_subcommand("imag-ref", other, rt.cli())?.success() {
.map_err_trace_exit_unwrap() Ok(())
.code() } else {
.map(::std::process::exit); Err(format_err!("Subcommand failed"))
}
}, },
} }
}; } else {
Ok(())
Ok(()) }
} }
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> { fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
@ -108,23 +107,18 @@ impl ImagApplication for ImagRef {
} }
} }
fn deref(rt: &Runtime) { fn deref(rt: &Runtime) -> Result<()> {
let cmd = rt.cli().subcommand_matches("deref").unwrap(); let cmd = rt.cli().subcommand_matches("deref").unwrap();
let basepath = cmd.value_of("override-basepath"); let basepath = cmd.value_of("override-basepath");
let cfg = get_ref_config(&rt, "imag-ref").map_err_trace_exit_unwrap(); let cfg = get_ref_config(&rt, "imag-ref")?;
let out = rt.stdout(); let out = rt.stdout();
let mut outlock = out.lock(); let mut outlock = out.lock();
rt rt.ids::<::ui::PathProvider>()?
.ids::<::ui::PathProvider>() .ok_or_else(|| err_msg("No ids supplied"))?
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("No ids supplied");
::std::process::exit(1);
})
.into_iter() .into_iter()
.for_each(|id| { .map(|id| {
match rt.store().get(id.clone()).map_err_trace_exit_unwrap() { match rt.store().get(id.clone())? {
Some(entry) => { Some(entry) => {
let r_entry = entry.as_ref_with_hasher::<DefaultHasher>(); let r_entry = entry.as_ref_with_hasher::<DefaultHasher>();
@ -132,89 +126,63 @@ fn deref(rt: &Runtime) {
r_entry.get_path_with_basepath_setting(&cfg, alternative_basepath) r_entry.get_path_with_basepath_setting(&cfg, alternative_basepath)
} else { } else {
r_entry.get_path(&cfg) r_entry.get_path(&cfg)
} }?
.map_err_trace_exit_unwrap()
.to_str() .to_str()
.ok_or_else(|| ::libimagerror::errors::ErrorMsg::UTF8Error) .ok_or_else(|| Error::from(::libimagerror::errors::ErrorMsg::UTF8Error))
.map_err(Error::from) .and_then(|s| writeln!(outlock, "{}", s).map_err(Error::from))?;
.and_then(|s| writeln!(outlock, "{}", s).map_err(Error::from))
.map_err_trace_exit_unwrap();
rt.report_touched(&id).unwrap_or_exit(); rt.report_touched(&id).map_err(Error::from)
},
None => {
error!("No entry for id '{}' found", id);
exit(1)
}, },
None => Err(format_err!("No entry for id '{}' found", id))
} }
}); })
.collect()
} }
fn remove(rt: &Runtime) { fn remove(rt: &Runtime) -> Result<()> {
use libimaginteraction::ask::ask_bool; use libimaginteraction::ask::ask_bool;
let cmd = rt.cli().subcommand_matches("remove").unwrap(); let cmd = rt.cli().subcommand_matches("remove").unwrap();
let yes = cmd.is_present("yes"); let yes = cmd.is_present("yes");
let mut input = rt.stdin().ok_or_else(|| err_msg("No input stream. Cannot ask for permission"))?;
let mut input = rt.stdin().unwrap_or_else(|| {
error!("No input stream. Cannot ask for permission");
exit(1);
});
let mut output = rt.stdout(); let mut output = rt.stdout();
rt rt.ids::<::ui::PathProvider>()?
.ids::<::ui::PathProvider>() .ok_or_else(|| err_msg("No ids supplied"))?
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("No ids supplied");
::std::process::exit(1);
})
.into_iter() .into_iter()
.for_each(|id| { .map(|id| {
match rt.store().get(id.clone()).map_err_trace_exit_unwrap() { match rt.store().get(id.clone())? {
None => Err(format_err!("No entry for id '{}' found", id)),
Some(mut entry) => { Some(mut entry) => {
if yes || if yes || ask_bool(&format!("Delete ref from entry '{}'", id), None, &mut input, &mut output)? {
ask_bool(&format!("Delete ref from entry '{}'", id), None, &mut input, &mut output) entry.as_ref_with_hasher_mut::<DefaultHasher>().remove_ref()
.map_err_trace_exit_unwrap()
{
entry.as_ref_with_hasher_mut::<DefaultHasher>()
.remove_ref()
.map_err_trace_exit_unwrap();
} else { } else {
info!("Aborted"); info!("Aborted");
Ok(())
} }
}, },
None => {
error!("No entry for id '{}' found", id);
exit(1)
},
} }
}); })
.collect()
} }
fn list_dead(rt: &Runtime) { fn list_dead(rt: &Runtime) -> Result<()> {
let cfg = get_ref_config(&rt, "imag-ref").map_err_trace_exit_unwrap(); let cfg = get_ref_config(&rt, "imag-ref")?;
let cmd = rt.cli().subcommand_matches("list-dead").unwrap(); // safe by main() let cmd = rt.cli().subcommand_matches("list-dead").unwrap(); // safe by main()
let list_path = cmd.is_present("list-dead-pathes"); let list_path = cmd.is_present("list-dead-pathes");
let list_id = cmd.is_present("list-dead-ids"); let list_id = cmd.is_present("list-dead-ids");
let mut output = rt.stdout(); let mut output = rt.stdout();
rt rt.ids::<crate::ui::PathProvider>()?
.ids::<crate::ui::PathProvider>() .ok_or_else(|| err_msg("No ids supplied"))?
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("No ids supplied");
::std::process::exit(1);
})
.into_iter() .into_iter()
.for_each(|id| { .map(|id| {
match rt.store().get(id.clone()).map_err_trace_exit_unwrap() { match rt.store().get(id.clone())? {
Some(entry) => { Some(entry) => {
let entry_ref = entry.as_ref_with_hasher::<DefaultHasher>(); let entry_ref = entry.as_ref_with_hasher::<DefaultHasher>();
if entry_ref.is_ref().map_err_trace_exit_unwrap() { // we only care if the entry is a ref if entry_ref.is_ref()? { // we only care if the entry is a ref
let entry_path = entry_ref.get_path(&cfg).map_err_trace_exit_unwrap(); let entry_path = entry_ref.get_path(&cfg)?;
if !entry_path.exists() { if !entry_path.exists() {
if list_id { if list_id {
@ -223,24 +191,24 @@ fn list_dead(rt: &Runtime) {
writeln!(output, "{}", entry_path.display()) writeln!(output, "{}", entry_path.display())
} else { } else {
unimplemented!() unimplemented!()
} }?;
.map_err(Error::from)
.map_err_trace_exit_unwrap();
rt.report_touched(entry.get_location()).unwrap_or_exit(); rt.report_touched(entry.get_location()).map_err(Error::from)
} else {
Ok(())
} }
} else {
Ok(())
} }
} }
None => { None => Err(format_err!("Does not exist: {}", id.local().display())),
error!("Does not exist: {}", id.local().display());
exit(1)
}
} }
}); })
.collect()
} }
fn create(_rt: &Runtime) { fn create(_rt: &Runtime) -> Result<()> {
unimplemented!() unimplemented!()
} }