Transform imag-bookmark to not call exit() but propagate errors to main()
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
parent
b6facfff6b
commit
641c6c7761
2 changed files with 79 additions and 108 deletions
|
@ -24,6 +24,7 @@ log = "0.4.6"
|
|||
toml = "0.5.1"
|
||||
toml-query = "0.9.2"
|
||||
failure = "0.1.5"
|
||||
resiter = "0.4.0"
|
||||
|
||||
libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" }
|
||||
libimagerror = { version = "0.10.0", path = "../../../lib/core/libimagerror" }
|
||||
|
|
|
@ -39,6 +39,7 @@ extern crate clap;
|
|||
extern crate toml;
|
||||
extern crate toml_query;
|
||||
#[macro_use] extern crate failure;
|
||||
extern crate resiter;
|
||||
|
||||
extern crate libimagbookmark;
|
||||
extern crate libimagrt;
|
||||
|
@ -47,12 +48,13 @@ extern crate libimagutil;
|
|||
extern crate libimagentrylink;
|
||||
|
||||
use std::io::Write;
|
||||
use std::process::exit;
|
||||
use std::ops::DerefMut;
|
||||
|
||||
use toml_query::read::TomlValueReadTypeExt;
|
||||
use failure::Error;
|
||||
use failure::err_msg;
|
||||
use failure::Fallible as Result;
|
||||
use resiter::AndThen;
|
||||
use clap::App;
|
||||
|
||||
use libimagrt::runtime::Runtime;
|
||||
|
@ -60,10 +62,6 @@ use libimagrt::application::ImagApplication;
|
|||
use libimagbookmark::collection::BookmarkCollection;
|
||||
use libimagbookmark::collection::BookmarkCollectionStore;
|
||||
use libimagbookmark::link::Link as BookmarkLink;
|
||||
use libimagerror::trace::{MapErrTrace, trace_error};
|
||||
use libimagerror::io::ToExitCode;
|
||||
use libimagerror::exit::ExitUnwrap;
|
||||
use libimagutil::debug_result::DebugResult;
|
||||
use libimagentrylink::linkable::Linkable;
|
||||
|
||||
mod ui;
|
||||
|
@ -75,26 +73,22 @@ mod ui;
|
|||
pub enum ImagBookmark {}
|
||||
impl ImagApplication for ImagBookmark {
|
||||
fn run(rt: Runtime) -> Result<()> {
|
||||
if let Some(name) = rt.cli().subcommand_name() {
|
||||
debug!("Call {}", name);
|
||||
match name {
|
||||
match rt.cli().subcommand_name().ok_or_else(|| err_msg("No subcommand called"))? {
|
||||
"add" => add(&rt),
|
||||
"collection" => collection(&rt),
|
||||
"list" => list(&rt),
|
||||
"remove" => remove(&rt),
|
||||
other => {
|
||||
debug!("Unknown command");
|
||||
let _ = rt.handle_unknown_subcommand("imag-bookmark", other, rt.cli())
|
||||
.map_err_trace_exit_unwrap()
|
||||
.code()
|
||||
.map(::std::process::exit);
|
||||
if rt.handle_unknown_subcommand("imag-bookmark", other, rt.cli())?.success() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(err_msg("Failed to handle unknown subcommand"))
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
|
||||
ui::build_ui(app)
|
||||
}
|
||||
|
@ -112,131 +106,107 @@ impl ImagApplication for ImagBookmark {
|
|||
}
|
||||
}
|
||||
|
||||
fn add(rt: &Runtime) {
|
||||
fn add(rt: &Runtime) -> Result<()> {
|
||||
let scmd = rt.cli().subcommand_matches("add").unwrap();
|
||||
let coll = get_collection_name(rt, "add", "collection");
|
||||
let coll = get_collection_name(rt, "add", "collection")?;
|
||||
|
||||
let mut collection = BookmarkCollectionStore::get(rt.store(), &coll)
|
||||
.map_err_trace_exit_unwrap()
|
||||
.ok_or_else(|| format_err!("No bookmark collection '{}' found", coll))
|
||||
.map_err_trace_exit_unwrap();
|
||||
let mut collection = BookmarkCollectionStore::get(rt.store(), &coll)?
|
||||
.ok_or_else(|| format_err!("No bookmark collection '{}' found", coll))?;
|
||||
|
||||
rt.report_touched(collection.get_location()).unwrap_or_exit();
|
||||
rt.report_touched(collection.get_location())?;
|
||||
|
||||
for url in scmd.values_of("urls").unwrap() { // unwrap saved by clap
|
||||
let new_ids = BookmarkCollection::add_link(collection.deref_mut(), rt.store(), BookmarkLink::from(url))
|
||||
.map_err_trace_exit_unwrap();
|
||||
|
||||
rt.report_all_touched(new_ids.into_iter()).unwrap_or_exit();
|
||||
scmd.values_of("urls")
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|url| {
|
||||
let new_ids = BookmarkCollection::add_link(collection.deref_mut(), rt.store(), BookmarkLink::from(url))?;
|
||||
rt.report_all_touched(new_ids.into_iter()).map_err(Error::from)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
info!("Ready");
|
||||
}
|
||||
|
||||
fn collection(rt: &Runtime) {
|
||||
fn collection(rt: &Runtime) -> Result<()> {
|
||||
let scmd = rt.cli().subcommand_matches("collection").unwrap();
|
||||
|
||||
if scmd.is_present("add") { // adding a new collection
|
||||
let name = scmd.value_of("add").unwrap();
|
||||
if let Ok(id) = BookmarkCollectionStore::new(rt.store(), &name) {
|
||||
rt.report_touched(id.get_location()).unwrap_or_exit();
|
||||
let id = BookmarkCollectionStore::new(rt.store(), &name)?;
|
||||
rt.report_touched(id.get_location())?;
|
||||
info!("Created: {}", name);
|
||||
} else {
|
||||
warn!("Creating collection {} failed", name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if scmd.is_present("remove") { // remove a collection
|
||||
let name = scmd.value_of("remove").unwrap();
|
||||
|
||||
{ // remove all links
|
||||
BookmarkCollectionStore::get(rt.store(), &name)
|
||||
.map_err_trace_exit_unwrap()
|
||||
.ok_or_else(|| format_err!("Collection does not exist: {}", name))
|
||||
.map_err_trace_exit_unwrap()
|
||||
.unlink(rt.store())
|
||||
.map_err_trace_exit_unwrap();
|
||||
BookmarkCollectionStore::get(rt.store(), &name)?
|
||||
.ok_or_else(|| format_err!("Collection does not exist: {}", name))?
|
||||
.unlink(rt.store())?;
|
||||
}
|
||||
|
||||
if BookmarkCollectionStore::delete(rt.store(), &name).is_ok() {
|
||||
BookmarkCollectionStore::delete(rt.store(), &name)?;
|
||||
info!("Deleted: {}", name);
|
||||
} else {
|
||||
warn!("Deleting collection {} failed", name);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn list(rt: &Runtime) {
|
||||
let coll = get_collection_name(rt, "list", "collection");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
let collection = BookmarkCollectionStore::get(rt.store(), &coll)
|
||||
.map_err_trace_exit_unwrap()
|
||||
.ok_or_else(|| format_err!("No bookmark collection '{}' found", coll))
|
||||
.map_err_trace_exit_unwrap();
|
||||
fn list(rt: &Runtime) -> Result<()> {
|
||||
let coll = get_collection_name(rt, "list", "collection")?;
|
||||
|
||||
rt.report_touched(collection.get_location()).unwrap_or_exit();
|
||||
let collection = BookmarkCollectionStore::get(rt.store(), &coll)?
|
||||
.ok_or_else(|| format_err!("No bookmark collection '{}' found", coll))?;
|
||||
|
||||
rt.report_touched(collection.get_location())?;
|
||||
|
||||
let mut i = 0; // poor mans enumerate()
|
||||
|
||||
collection
|
||||
.get_links(rt.store())
|
||||
.map_dbg_str("Listing...")
|
||||
.map_err_trace_exit_unwrap()
|
||||
.enumerate()
|
||||
.for_each(|(i, link)| match link {
|
||||
Ok(link) => writeln!(rt.stdout(), "{: >3}: {}", i, link).to_exit_code().unwrap_or_exit(),
|
||||
Err(e) => trace_error(&e)
|
||||
});
|
||||
debug!("... ready with listing");
|
||||
.get_links(rt.store())?
|
||||
.and_then_ok(|link| {
|
||||
let r = writeln!(rt.stdout(), "{: >3}: {}", i, link).map_err(Error::from);
|
||||
i += 1;
|
||||
r
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn remove(rt: &Runtime) {
|
||||
fn remove(rt: &Runtime) -> Result<()> {
|
||||
let scmd = rt.cli().subcommand_matches("remove").unwrap();
|
||||
let coll = get_collection_name(rt, "list", "collection");
|
||||
let coll = get_collection_name(rt, "list", "collection")?;
|
||||
|
||||
let mut collection = BookmarkCollectionStore::get(rt.store(), &coll)
|
||||
.map_err_trace_exit_unwrap()
|
||||
.ok_or_else(|| format_err!("No bookmark collection '{}' found", coll))
|
||||
.map_err_trace_exit_unwrap();
|
||||
let mut collection = BookmarkCollectionStore::get(rt.store(), &coll)?
|
||||
.ok_or_else(|| format_err!("No bookmark collection '{}' found", coll))?;
|
||||
|
||||
rt.report_touched(collection.get_location()).unwrap_or_exit();
|
||||
rt.report_touched(collection.get_location())?;
|
||||
|
||||
for url in scmd.values_of("urls").unwrap() { // enforced by clap
|
||||
let removed_links = BookmarkCollection::remove_link(collection.deref_mut(), rt.store(), BookmarkLink::from(url))
|
||||
.map_err_trace_exit_unwrap();
|
||||
|
||||
rt.report_all_touched(removed_links.into_iter()).unwrap_or_exit();
|
||||
}
|
||||
|
||||
info!("Ready");
|
||||
scmd.values_of("urls")
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|url| {
|
||||
let removed_links = BookmarkCollection::remove_link(collection.deref_mut(), rt.store(), BookmarkLink::from(url))?;
|
||||
rt.report_all_touched(removed_links.into_iter()).map_err(Error::from)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
|
||||
fn get_collection_name(rt: &Runtime,
|
||||
subcommand_name: &str,
|
||||
collection_argument_name: &str)
|
||||
-> String
|
||||
-> Result<String>
|
||||
{
|
||||
rt.cli()
|
||||
if let Some(cn) = rt.cli()
|
||||
.subcommand_matches(subcommand_name)
|
||||
.and_then(|scmd| scmd.value_of(collection_argument_name).map(String::from))
|
||||
.unwrap_or_else(|| {
|
||||
rt.config()
|
||||
.map(|cfg| {
|
||||
cfg.read_string("bookmark.default_collection")
|
||||
.map_err(Error::from)
|
||||
.map_err_trace_exit_unwrap()
|
||||
.ok_or_else(|| {
|
||||
error!("Missing config: 'bookmark.default_collection'. Set or use commandline to specify.");
|
||||
exit(1)
|
||||
})
|
||||
.unwrap()
|
||||
.clone()
|
||||
})
|
||||
.unwrap_or_else(|| {
|
||||
error!("Failed to read configuration");
|
||||
exit(1)
|
||||
})
|
||||
{
|
||||
return Ok(cn)
|
||||
} else {
|
||||
rt.config().ok_or_else(|| err_msg("No configuration availablew"))
|
||||
.and_then(|cfg| {
|
||||
cfg.read_string("bookmark.default_collection")?
|
||||
.ok_or_else(|| err_msg("Missing config: 'bookmark.default_collection'."))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue