summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatthias Beyer <mail@beyermatthias.de>2019-12-22 11:47:39 +0100
committerMatthias Beyer <mail@beyermatthias.de>2019-12-22 11:47:39 +0100
commit1ffa2866e1bb91a0eca129ce4593ef62d97fc42f (patch)
treee64eb89f5b0a80844ee746491bdbb2a6640e715f
parentbaa1c2692d2b7de6cfffc53bea5ba6da798f5e21 (diff)
Rewrite imag-wiki to propagate errors instead of calling exit()
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
-rw-r--r--bin/domain/imag-wiki/Cargo.toml1
-rw-r--r--bin/domain/imag-wiki/src/lib.rs203
2 files changed, 78 insertions, 126 deletions
diff --git a/bin/domain/imag-wiki/Cargo.toml b/bin/domain/imag-wiki/Cargo.toml
index eca68017..820bd90a 100644
--- a/bin/domain/imag-wiki/Cargo.toml
+++ b/bin/domain/imag-wiki/Cargo.toml
@@ -22,6 +22,7 @@ is-match = "0.1.0"
regex = "1.1.7"
filters = "0.3.0"
failure = "0.1.5"
+resiter = "0.4.0"
libimagentryedit = { version = "0.10.0", path = "../../../lib/entry/libimagentryedit" }
libimagentrylink = { version = "0.10.0", path = "../../../lib/entry/libimagentrylink" }
diff --git a/bin/domain/imag-wiki/src/lib.rs b/bin/domain/imag-wiki/src/lib.rs
index f541c14f..10be8af9 100644
--- a/bin/domain/imag-wiki/src/lib.rs
+++ b/bin/domain/imag-wiki/src/lib.rs
@@ -23,7 +23,8 @@ extern crate clap;
extern crate regex;
extern crate filters;
#[macro_use] extern crate log;
-extern crate failure;
+#[macro_use] extern crate failure;
+extern crate resiter;
extern crate libimagrt;
extern crate libimagerror;
@@ -35,16 +36,17 @@ extern crate libimagutil;
use std::io::Write;
use failure::Fallible as Result;
+use failure::ResultExt;
+use failure::Error;
+use failure::err_msg;
use clap::App;
+use resiter::AndThen;
use libimagrt::runtime::Runtime;
use libimagrt::application::ImagApplication;
-use libimagerror::iter::TraceIterator;
-use libimagerror::trace::MapErrTrace;
-use libimagerror::exit::ExitUnwrap;
-use libimagerror::io::ToExitCode;
-use libimagwiki::store::WikiStore;
use libimagentryedit::edit::{Edit, EditHeader};
+use libimagwiki::store::WikiStore;
+use libimagwiki::entry::WikiEntry;
mod ui;
@@ -59,24 +61,22 @@ impl ImagApplication for ImagWiki {
trace!("wiki_name = {}", wiki_name);
trace!("calling = {:?}", rt.cli().subcommand_name());
- match rt.cli().subcommand_name() {
- Some("list") => list(&rt, wiki_name),
- Some("idof") => idof(&rt, wiki_name),
- Some("create") => create(&rt, wiki_name),
- Some("create-wiki") => create_wiki(&rt),
- Some("show") => show(&rt, wiki_name),
- Some("delete") => delete(&rt, wiki_name),
- Some(other) => {
+ match rt.cli().subcommand_name().ok_or_else(|| err_msg("No subcommand called"))? {
+ "list" => list(&rt, wiki_name),
+ "idof" => idof(&rt, wiki_name),
+ "create" => create(&rt, wiki_name),
+ "create-wiki" => create_wiki(&rt),
+ "show" => show(&rt, wiki_name),
+ "delete" => delete(&rt, wiki_name),
+ other => {
debug!("Unknown command");
- let _ = rt.handle_unknown_subcommand("imag-wiki", other, rt.cli())
- .map_err_trace_exit_unwrap()
- .code()
- .map(std::process::exit);
+ if rt.handle_unknown_subcommand("imag-wiki", other, rt.cli())?.success() {
+ Ok(())
+ } else {
+ Err(err_msg("Failed to handle unknown subcommand"))
+ }
}
- None => warn!("No command"),
} // end match scmd
-
- Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
@@ -97,7 +97,7 @@ impl ImagApplication for ImagWiki {
}
-fn list(rt: &Runtime, wiki_name: &str) {
+fn list(rt: &Runtime, wiki_name: &str) -> Result<()> {
let scmd = rt.cli().subcommand_matches("list").unwrap(); // safed by clap
let prefix = if scmd.is_present("list-full") {
format!("{}/", rt.store().path().display())
@@ -109,23 +109,15 @@ fn list(rt: &Runtime, wiki_name: &str) {
let mut outlock = out.lock();
rt.store()
- .get_wiki(wiki_name)
- .map_err_trace_exit_unwrap()
- .unwrap_or_else(|| {
- error!("No wiki '{}' found", wiki_name);
- ::std::process::exit(1)
- })
- .all_ids()
- .map_err_trace_exit_unwrap()
- .trace_unwrap_exit()
- .for_each(|id| {
- writeln!(outlock, "{}{}", prefix, id)
- .to_exit_code()
- .unwrap_or_exit();
- });
+ .get_wiki(wiki_name)?
+ .ok_or_else(|| format_err!("No wiki '{}' found", wiki_name))?
+ .all_ids()?
+ .and_then_ok(|id| writeln!(outlock, "{}{}", prefix, id).map_err(Error::from))
+ .collect::<Result<Vec<_>>>()
+ .map(|_| ())
}
-fn idof(rt: &Runtime, wiki_name: &str) {
+fn idof(rt: &Runtime, wiki_name: &str) -> Result<()> {
let scmd = rt.cli().subcommand_matches("idof").unwrap(); // safed by clap
let entryname = scmd
@@ -137,15 +129,11 @@ fn idof(rt: &Runtime, wiki_name: &str) {
let mut lock = out.lock();
rt.store()
- .get_wiki(wiki_name)
- .map_err_trace_exit_unwrap()
- .unwrap_or_else(|| {
- error!("No wiki '{}' found", wiki_name);
- ::std::process::exit(1)
- })
- .get_entry(&entryname)
- .map_err_trace_exit_unwrap()
- .map(|entry| {
+ .get_wiki(wiki_name)?
+ .ok_or_else(|| format_err!("No wiki '{}' found", wiki_name))?
+ .get_entry(&entryname)?
+ .ok_or_else(|| format_err!("Entry '{}' in wiki '{}' not found!", entryname, wiki_name))
+ .and_then(|entry| {
let id = entry.get_location().clone();
let prefix = if scmd.is_present("idof-full") {
format!("{}/", rt.store().path().display())
@@ -153,48 +141,36 @@ fn idof(rt: &Runtime, wiki_name: &str) {
String::from("")
};
- writeln!(lock, "{}{}", prefix, id).to_exit_code().unwrap_or_exit()
+ writeln!(lock, "{}{}", prefix, id).map_err(Error::from)
})
- .unwrap_or_else(|| {
- error!("Entry '{}' in wiki '{}' not found!", entryname, wiki_name);
- ::std::process::exit(1)
- });
}
-fn create(rt: &Runtime, wiki_name: &str) {
- use libimagwiki::entry::WikiEntry;
- use libimagutil::warn_result::WarnResult;
-
+fn create(rt: &Runtime, wiki_name: &str) -> Result<()> {
let scmd = rt.cli().subcommand_matches("create").unwrap(); // safed by clap
let name = String::from(scmd.value_of("create-name").unwrap()); // safe by clap
let wiki = rt
.store()
- .get_wiki(&wiki_name)
- .map_err_trace_exit_unwrap()
- .unwrap_or_else(|| {
- error!("No wiki '{}' found", wiki_name);
- ::std::process::exit(1)
- });
+ .get_wiki(&wiki_name)?
+ .ok_or_else(|| format_err!("No wiki '{}' found", wiki_name))?;
- let mut entry = wiki.create_entry(name).map_err_trace_exit_unwrap();
+ let mut entry = wiki.create_entry(name)?;
if !scmd.is_present("create-noedit") {
if scmd.is_present("create-editheader") {
- entry.edit_header_and_content(rt).map_err_trace_exit_unwrap();
+ entry.edit_header_and_content(rt)?;
} else {
- entry.edit_content(rt).map_err_trace_exit_unwrap();
+ entry.edit_content(rt)?;
}
}
- entry.autolink(rt.store())
- .map_warn_err_str("Linking has failed. Trying to safe the entry now. Please investigate by hand if this succeeds.")
- .map_err(|e| {
- rt.store().update(&mut entry).map_err_trace_exit_unwrap();
- e
- })
- .map_warn_err_str("Safed entry")
- .map_err_trace_exit_unwrap();
+ if let Err(e) = entry
+ .autolink(rt.store())
+ .context("Linking has failed. Trying to safe the entry now. Please investigate by hand if this succeeds.")
+ {
+ rt.store().update(&mut entry).context("Safed entry")?;
+ return Err(e).map_err(Error::from)
+ }
let id = entry.get_location();
@@ -202,21 +178,21 @@ fn create(rt: &Runtime, wiki_name: &str) {
let out = rt.stdout();
let mut lock = out.lock();
- writeln!(lock, "{}", id).to_exit_code().unwrap_or_exit()
+ writeln!(lock, "{}", id)?;
}
- rt.report_touched(&id).unwrap_or_exit();
+ rt.report_touched(&id).map_err(Error::from)
}
-fn create_wiki(rt: &Runtime) {
+fn create_wiki(rt: &Runtime) -> Result<()> {
let scmd = rt.cli().subcommand_matches("create-wiki").unwrap(); // safed by clap
let wiki_name = String::from(scmd.value_of("create-wiki-name").unwrap()); // safe by clap
- let (_, index) = rt.store().create_wiki(&wiki_name).map_err_trace_exit_unwrap();
+ let (_, index) = rt.store().create_wiki(&wiki_name)?;
- rt.report_touched(index.get_location()).unwrap_or_exit();
+ rt.report_touched(index.get_location()).map_err(Error::from)
}
-fn show(rt: &Runtime, wiki_name: &str) {
+fn show(rt: &Runtime, wiki_name: &str) -> Result<()> {
use filters::filter::Filter;
let scmd = rt.cli().subcommand_matches("show").unwrap(); // safed by clap
@@ -235,47 +211,33 @@ fn show(rt: &Runtime, wiki_name: &str) {
.values_of("show-name")
.map(|v| v.map(String::from).collect::<Vec<String>>()));
- let names = scmd
- .values_of("show-name")
- .unwrap() // safe by clap
- .map(String::from)
- .filter(|e| namefilter.filter(e))
- .collect::<Vec<_>>();
-
let wiki = rt
.store()
- .get_wiki(&wiki_name)
- .map_err_trace_exit_unwrap()
- .unwrap_or_else(|| {
- error!("No wiki '{}' found", wiki_name);
- ::std::process::exit(1)
- });
+ .get_wiki(&wiki_name)?
+ .ok_or_else(|| format_err!("No wiki '{}' found", wiki_name))?;
let out = rt.stdout();
let mut outlock = out.lock();
- for name in names {
- let entry = wiki
- .get_entry(&name)
- .map_err_trace_exit_unwrap()
- .unwrap_or_else(|| {
- error!("No wiki entry '{}' found in wiki '{}'", name, wiki_name);
- ::std::process::exit(1)
- });
-
- writeln!(outlock, "{}", entry.get_location())
- .to_exit_code()
- .unwrap_or_exit();
+ scmd.values_of("show-name")
+ .unwrap() // safe by clap
+ .map(String::from)
+ .filter(|e| namefilter.filter(e))
+ .map(|name| {
+ let entry = wiki
+ .get_entry(&name)?
+ .ok_or_else(|| format_err!("No wiki entry '{}' found in wiki '{}'", name, wiki_name))?;
- writeln!(outlock, "{}", entry.get_content())
- .to_exit_code()
- .unwrap_or_exit();
+ writeln!(outlock, "{}", entry.get_location())?;
+ writeln!(outlock, "{}", entry.get_content())?;
- rt.report_touched(entry.get_location()).unwrap_or_exit();
- }
+ rt.report_touched(entry.get_location()).map_err(Error::from)
+ })
+ .collect::<Result<Vec<_>>>()
+ .map(|_| ())
}
-fn delete(rt: &Runtime, wiki_name: &str) {
+fn delete(rt: &Runtime, wiki_name: &str) -> Result<()> {
use libimagentrylink::linkable::Linkable;
let scmd = rt.cli().subcommand_matches("delete").unwrap(); // safed by clap
@@ -284,26 +246,15 @@ fn delete(rt: &Runtime, wiki_name: &str) {
let wiki = rt
.store()
- .get_wiki(&wiki_name)
- .map_err_trace_exit_unwrap()
- .unwrap_or_else(|| {
- error!("No wiki '{}' found", wiki_name);
- ::std::process::exit(1)
- });
+ .get_wiki(&wiki_name)?
+ .ok_or_else(|| format_err!("No wiki '{}' found", wiki_name))?;
if unlink {
- wiki.get_entry(&name)
- .map_err_trace_exit_unwrap()
- .unwrap_or_else(|| {
- error!("No wiki entry '{}' in '{}' found", name, wiki_name);
- ::std::process::exit(1)
- })
- .unlink(rt.store())
- .map_err_trace_exit_unwrap();
+ wiki.get_entry(&name)?
+ .ok_or_else(|| format_err!("No wiki entry '{}' in '{}' found", name, wiki_name))?
+ .unlink(rt.store())?;
}
- wiki
- .delete_entry(&name)
- .map_err_trace_exit_unwrap();
+ wiki.delete_entry(&name)
}