~matthiasbeyer/imag

247309bf4ea2f736f93a55db4c4f4dcb2f5fa6a3 — Matthias Beyer 1 year, 9 months ago fd11a34 + 1ffa286
Merge branch 'imag-wiki/noexit' into master

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
2 files changed, 78 insertions(+), 126 deletions(-)

M bin/domain/imag-wiki/Cargo.toml
M bin/domain/imag-wiki/src/lib.rs
M bin/domain/imag-wiki/Cargo.toml => bin/domain/imag-wiki/Cargo.toml +1 -0
@@ 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" }

M bin/domain/imag-wiki/src/lib.rs => bin/domain/imag-wiki/src/lib.rs +77 -126
@@ 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)
}