Merge Leons patches for single-binary and CLI completion preparation

This merge pulls in the changes that Leon developed over the course of
the last months which change the binaries to actually be libraries with
a _very_ minimal binary surface. This enables us to actually generate
commandline completion scripts with clap without doing any fancy
file-include magic in a build.rs script.

From the original request-pull message (Mon, 24 Jun 2019 21:48:51 +0200):

> This patch is yet another attempt at bringing CLI completion to this
> workspace project. The details are explained in the commit message.
>
> Advantages of this approach include:
> - Use of standard dependency management features (`cargo install`
>   compatible)
> - Exposing further "binary" business logic to other Rust crates as a
>   library
> - (Possibly) hard linking the "binary" into the main imag binary, so
>   only one binary needs to be shipped. This should improve startup time,
>   and the Runtime instance could even be reused. I'd favor this
>   approach, while making it all configurable via features and still
>   searching the $PATH to allow bash-scripts etc. to provide imag
>   subcommands.
>
> However, this *could* increase binary size, I didn't perform any
> measures (at least when not only using in the build script but in the
> main binary as well). Anyhow, with LTO enabled this shouldn't matter if
> the dependencies aren't used.

Some patches were added by me before the merge, because Leon did not
check whether the tests still work (just minimal adjustments, see the
log).

Also, one change was made to the final patchset send by Leon, which was
a fixup of the Copyright date in bin/core/imag/build.rs. This change
does not appear in the commit logs because it was just bumping the year
from 2018 to 2019 in the Copyright header. This was acked by Leon in a
private conversation.

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
Matthias Beyer 2019-10-26 15:09:41 +02:00
commit 7a06544654
103 changed files with 4252 additions and 1971 deletions

View file

@ -39,3 +39,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["color", "suggestions", "wrap_help"] features = ["color", "suggestions", "wrap_help"]
[lib]
name = "libimagannotatecmd"
path = "src/lib.rs"
[[bin]]
name = "imag-annotate"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagannotatecmd, ImagAnnotate);

View file

@ -44,7 +44,7 @@ extern crate toml_query;
extern crate libimagentryannotation; extern crate libimagentryannotation;
extern crate libimagentryedit; extern crate libimagentryedit;
extern crate libimagerror; extern crate libimagerror;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagstore; extern crate libimagstore;
extern crate libimagutil; extern crate libimagutil;
extern crate libimagentrylink; extern crate libimagentrylink;
@ -52,7 +52,9 @@ extern crate libimagentrylink;
use std::io::Write; use std::io::Write;
use failure::Error; use failure::Error;
use failure::Fallible as Result;
use toml_query::read::TomlValueReadTypeExt; use toml_query::read::TomlValueReadTypeExt;
use clap::App;
use libimagentryannotation::annotateable::*; use libimagentryannotation::annotateable::*;
use libimagentryannotation::annotation_fetcher::*; use libimagentryannotation::annotation_fetcher::*;
@ -63,33 +65,48 @@ use libimagerror::io::ToExitCode;
use libimagerror::errors::ErrorMsg as EM; use libimagerror::errors::ErrorMsg as EM;
use libimagerror::iter::TraceIterator; use libimagerror::iter::TraceIterator;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
use libimagstore::store::FileLockEntry; use libimagstore::store::FileLockEntry;
use libimagstore::iter::get::StoreIdGetIteratorExtension; use libimagstore::iter::get::StoreIdGetIteratorExtension;
use libimagentrylink::linkable::Linkable; use libimagentrylink::linkable::Linkable;
mod ui; mod ui;
fn main() { pub enum ImagAnnotate {}
let version = make_imag_version!(); impl ImagApplication for ImagAnnotate {
let rt = generate_runtime_setup("imag-annotation", fn run(rt: Runtime) -> Result<()> {
&version, if let Some(name) = rt.cli().subcommand_name() {
"Add annotations to entries", match name {
ui::build_ui); "add" => add(&rt),
"remove" => remove(&rt),
if let Some(name) = rt.cli().subcommand_name() { "list" => list(&rt),
match name { other => {
"add" => add(&rt), debug!("Unknown command");
"remove" => remove(&rt), let _ = rt.handle_unknown_subcommand("imag-annotation", other, rt.cli())
"list" => list(&rt), .map_err_trace_exit_unwrap()
other => { .code()
debug!("Unknown command"); .map(::std::process::exit);
let _ = rt.handle_unknown_subcommand("imag-annotation", other, rt.cli()) },
.map_err_trace_exit_unwrap() }
.code()
.map(::std::process::exit);
},
} }
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Add annotations to entries"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
} }
} }

View file

@ -36,3 +36,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["color", "suggestions", "wrap_help"] features = ["color", "suggestions", "wrap_help"]
[lib]
name = "libimagcategorycmd"
path = "src/lib.rs"
[[bin]]
name = "imag-category"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagcategorycmd, ImagCategory);

View file

@ -42,15 +42,18 @@ extern crate failure;
extern crate libimagentrycategory; extern crate libimagentrycategory;
extern crate libimagerror; extern crate libimagerror;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagstore; extern crate libimagstore;
extern crate libimaginteraction; extern crate libimaginteraction;
use failure::Fallible as Result;
use clap::App;
use libimagerror::trace::MapErrTrace; use libimagerror::trace::MapErrTrace;
use libimagerror::exit::ExitUnwrap; use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode; use libimagerror::io::ToExitCode;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
mod ui; mod ui;
@ -63,32 +66,52 @@ use libimagerror::iter::TraceIterator;
use libimagentrycategory::entry::EntryCategory; use libimagentrycategory::entry::EntryCategory;
use libimagentrycategory::category::Category; use libimagentrycategory::category::Category;
fn main() { /// Marker enum for implementing ImagApplication on
let version = make_imag_version!(); ///
let rt = generate_runtime_setup("imag-category", /// This is used by binaries crates to execute business logic
&version, /// or to build a CLI completion.
"Add a category to entries and manage categories", pub enum ImagCategory {}
ui::build_ui); impl ImagApplication for ImagCategory {
fn run(rt: Runtime) -> Result<()> {
if let Some(name) = rt.cli().subcommand_name() { if let Some(name) = rt.cli().subcommand_name() {
match name { match name {
"set" => set(&rt), "set" => set(&rt),
"get" => get(&rt), "get" => get(&rt),
"list-category" => list_category(&rt), "list-category" => list_category(&rt),
"create-category" => create_category(&rt), "create-category" => create_category(&rt),
"delete-category" => delete_category(&rt), "delete-category" => delete_category(&rt),
"list-categories" => list_categories(&rt), "list-categories" => list_categories(&rt),
other => { other => {
debug!("Unknown command"); debug!("Unknown command");
let _ = rt.handle_unknown_subcommand("imag-category", other, rt.cli()) let _ = rt.handle_unknown_subcommand("imag-category", other, rt.cli())
.map_err_trace_exit_unwrap() .map_err_trace_exit_unwrap()
.code() .code()
.map(::std::process::exit); .map(::std::process::exit);
}, },
}
} }
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Add a category to entries and manage categories"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
} }
} }
fn set(rt: &Runtime) { fn set(rt: &Runtime) {
let scmd = rt.cli().subcommand_matches("set").unwrap(); // safed by main() let scmd = rt.cli().subcommand_matches("set").unwrap(); // safed by main()
let name = scmd.value_of("set-name").map(String::from).unwrap(); // safed by clap let name = scmd.value_of("set-name").map(String::from).unwrap(); // safed by clap

View file

@ -27,3 +27,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["suggestions", "color", "wrap_help"] features = ["suggestions", "color", "wrap_help"]
[lib]
name = "libimagcreatecmd"
path = "src/lib.rs"
[[bin]]
name = "imag-create"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagcreatecmd, ImagCreate);

View file

@ -0,0 +1,105 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
extern crate clap;
extern crate failure;
#[macro_use] extern crate log;
extern crate libimagerror;
extern crate libimagrt;
extern crate libimagstore;
use failure::Fallible as Result;
use clap::App;
use libimagrt::runtime::Runtime;
use libimagrt::application::ImagApplication;
use libimagerror::trace::MapErrTrace;
use libimagstore::iter::create::StoreIdCreateIteratorExtension;
use libimagstore::iter::retrieve::StoreIdRetrieveIteratorExtension;
use libimagerror::exit::ExitUnwrap;
mod ui;
pub enum ImagCreate {}
impl ImagApplication for ImagCreate {
fn run(rt: Runtime) -> Result<()> {
let force = rt.cli().is_present("force");
debug!("Detected force = {}", force);
let ids = rt.ids::<crate::ui::PathProvider>()
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("No ids supplied");
::std::process::exit(1);
})
.into_iter()
.map(|id| { debug!("id = {}", id); id })
.map(Ok);
if force {
ids.into_retrieve_iter(rt.store()).collect::<Result<Vec<_>>>()
} else {
ids.into_create_iter(rt.store()).collect::<Result<Vec<_>>>()
}.map_err_trace_exit_unwrap()
.into_iter()
.for_each(|el| {
rt.report_touched(el.get_location()).unwrap_or_exit();
trace!("Entry = {}", el.get_location());
});
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Plumbing tool to create entries"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
}

View file

@ -1,84 +0,0 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
//#![deny(
// non_camel_case_types,
// non_snake_case,
// path_statements,
// trivial_numeric_casts,
// unstable_features,
// unused_allocation,
// unused_import_braces,
// unused_imports,
// unused_must_use,
// unused_mut,
// unused_qualifications,
// while_true,
//)]
extern crate clap;
extern crate failure;
#[macro_use] extern crate log;
extern crate libimagerror;
#[macro_use] extern crate libimagrt;
extern crate libimagstore;
use failure::Fallible as Result;
use libimagerror::trace::MapErrTrace;
use libimagrt::setup::generate_runtime_setup;
use libimagstore::iter::create::StoreIdCreateIteratorExtension;
use libimagstore::iter::retrieve::StoreIdRetrieveIteratorExtension;
use libimagerror::exit::ExitUnwrap;
mod ui;
fn main() {
let version = make_imag_version!();
let rt = generate_runtime_setup("imag-create",
&version,
"Plumbing tool creating entries",
ui::build_ui);
let force = rt.cli().is_present("force");
debug!("Detected force = {}", force);
let ids = rt.ids::<crate::ui::PathProvider>()
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("No ids supplied");
::std::process::exit(1);
})
.into_iter()
.map(|id| { debug!("id = {}", id); id })
.map(Ok);
if force {
ids.into_retrieve_iter(rt.store()).collect::<Result<Vec<_>>>()
} else {
ids.into_create_iter(rt.store()).collect::<Result<Vec<_>>>()
}.map_err_trace_exit_unwrap()
.into_iter()
.for_each(|el| {
rt.report_touched(el.get_location()).unwrap_or_exit();
trace!("Entry = {}", el.get_location());
});
}

View file

@ -30,3 +30,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["suggestions", "color", "wrap_help"] features = ["suggestions", "color", "wrap_help"]
[lib]
name = "libimagdiagnosticscmd"
path = "src/lib.rs"
[[bin]]
name = "imag-diagnostics"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagdiagnosticscmd, ImagDiagnostics);

View file

@ -0,0 +1,288 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
extern crate clap;
extern crate toml;
extern crate toml_query;
extern crate indicatif;
extern crate failure;
#[macro_use] extern crate log;
extern crate libimagrt;
extern crate libimagerror;
extern crate libimagentrylink;
extern crate libimagstore;
use std::io::Write;
use libimagrt::runtime::Runtime;
use libimagrt::application::ImagApplication;
use libimagerror::trace::MapErrTrace;
use libimagerror::io::ToExitCode;
use libimagerror::exit::ExitUnwrap;
use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
use libimagentrylink::linkable::Linkable;
use toml::Value;
use toml_query::read::TomlValueReadExt;
use indicatif::{ProgressBar, ProgressStyle};
use failure::Fallible as Result;
use failure::Error;
use failure::err_msg;
use clap::App;
use std::collections::BTreeMap;
mod ui;
#[derive(Debug)]
struct Diagnostic {
pub id: StoreId,
pub entry_store_version: String,
pub header_sections: usize,
pub bytecount_content: usize,
pub overall_byte_size: usize,
pub verified: bool,
pub num_links: usize,
}
impl Diagnostic {
fn for_entry<'a>(entry: &FileLockEntry<'a>) -> Result<Diagnostic> {
Ok(Diagnostic {
id: entry.get_location().clone(),
entry_store_version: entry
.get_header()
.read("imag.version")
.map(|opt| match opt {
Some(&Value::String(ref s)) => s.clone(),
Some(_) => "Non-String type in 'imag.version'".to_owned(),
None => "No version".to_owned(),
})
.unwrap_or("Error reading version".to_owned()),
header_sections: match entry.get_header() {
&Value::Table(ref map) => map.keys().count(),
_ => 0
},
bytecount_content: entry.get_content().as_str().len(),
overall_byte_size: entry.to_str()?.as_str().len(),
verified: entry.verify().is_ok(),
num_links: entry.links().map(Iterator::count).unwrap_or(0),
})
}
}
macro_rules! do_write {
($dest:ident, $pattern:tt) => {
let _ = writeln!($dest, $pattern)
.to_exit_code()
.unwrap_or_exit();
};
($dest:ident, $pattern:tt, $( $args:expr ),*) => {
let _ = writeln!($dest, $pattern, $( $args ),*)
.to_exit_code()
.unwrap_or_exit();
}
}
/// Marker enum for implementing ImagApplication on
///
/// This is used by binaries crates to execute business logic
/// or to build a CLI completion.
pub enum ImagDiagnostics {}
impl ImagApplication for ImagDiagnostics {
fn run(rt: Runtime) -> Result<()> {
let template = get_config(&rt, "rt.progressbar_style");
let tick_chars = get_config(&rt, "rt.progressticker_chars");
let verbose = rt.cli().is_present("more-output");
let style = if let Some(tick_chars) = tick_chars {
ProgressStyle::default_spinner().tick_chars(&tick_chars)
} else {
ProgressStyle::default_spinner()
};
let spinner = ProgressBar::new_spinner();
spinner.enable_steady_tick(100);
spinner.set_style(style);
spinner.set_message("Accumulating data");
let diags = rt.store()
.entries()
.map_err_trace_exit_unwrap()
.into_get_iter()
.map(|e| {
e.map_err_trace_exit_unwrap()
.ok_or_else(|| Error::from(err_msg("Unable to get entry".to_owned())))
.map_err_trace_exit_unwrap()
})
.map(|e| {
let diag = Diagnostic::for_entry(&e);
debug!("Diagnostic for '{:?}' = {:?}", e.get_location(), diag);
drop(e);
diag
})
.collect::<Result<Vec<_>>>()
.map_err_trace_exit_unwrap();
spinner.finish();
let n = diags.len();
let progress = ProgressBar::new(n as u64);
let style = if let Some(template) = template {
ProgressStyle::default_bar().template(&template)
} else {
ProgressStyle::default_bar()
};
progress.set_style(style);
progress.set_message("Calculating stats");
let mut version_counts : BTreeMap<String, usize> = BTreeMap::new();
let mut sum_header_sections = 0;
let mut sum_bytecount_content = 0;
let mut sum_overall_byte_size = 0;
let mut max_overall_byte_size : Option<(usize, StoreId)> = None;
let mut verified_count = 0;
let mut unverified_count = 0;
let mut unverified_entries = vec![];
let mut num_links = 0;
let mut max_links : Option<(usize, StoreId)> = None;
for diag in diags.iter() {
sum_header_sections += diag.header_sections;
sum_bytecount_content += diag.bytecount_content;
sum_overall_byte_size += diag.overall_byte_size;
match max_overall_byte_size {
None => max_overall_byte_size = Some((diag.num_links, diag.id.clone())),
Some((num, _)) => if num < diag.overall_byte_size {
max_overall_byte_size = Some((diag.overall_byte_size, diag.id.clone()));
}
}
let n = version_counts.get(&diag.entry_store_version).map(Clone::clone).unwrap_or(0);
version_counts.insert(diag.entry_store_version.clone(), n+1);
if diag.verified {
verified_count += 1;
} else {
unverified_count += 1;
if verbose {
unverified_entries.push(diag.id.clone());
}
}
num_links += diag.num_links;
match max_links {
None => max_links = Some((diag.num_links, diag.id.clone())),
Some((num, _)) => if num < diag.num_links {
max_links = Some((diag.num_links, diag.id.clone()));
}
}
progress.inc(1);
}
progress.finish();
let mut out = rt.stdout();
do_write!(out, "imag version {}", { env!("CARGO_PKG_VERSION") });
do_write!(out, "");
do_write!(out, "{} entries", n);
for (k, v) in version_counts {
do_write!(out, "{} entries with store version '{}'", v, k);
}
if n != 0 {
do_write!(out, "{} header sections in the average entry", sum_header_sections / n);
do_write!(out, "{} average content bytecount", sum_bytecount_content / n);
do_write!(out, "{} average overall bytecount", sum_overall_byte_size / n);
if let Some((num, path)) = max_overall_byte_size {
do_write!(out, "Largest Entry ({} bytes): {}", num, path.local_display_string());
}
do_write!(out, "{} average internal link count per entry", num_links / n);
if let Some((num, path)) = max_links {
do_write!(out, "Entry with most internal links ({}): {}",
num,
path.local_display_string());
}
do_write!(out, "{} verified entries", verified_count);
do_write!(out, "{} unverified entries", unverified_count);
if verbose {
for unve in unverified_entries.iter() {
do_write!(out, "Unverified: {}", unve);
}
}
}
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Print diagnostics about imag and the imag store"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
}
fn get_config(rt: &Runtime, s: &'static str) -> Option<String> {
rt.config().and_then(|cfg| {
cfg.read(s)
.map_err(Error::from)
.map_err_trace_exit_unwrap()
.map(|opt| match opt {
&Value::String(ref s) => s.to_owned(),
_ => {
error!("Config type wrong: 'rt.progressbar_style' should be a string");
::std::process::exit(1)
}
})
})
}

View file

@ -1,269 +0,0 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
extern crate clap;
extern crate toml;
extern crate toml_query;
extern crate indicatif;
extern crate failure;
#[macro_use] extern crate log;
#[macro_use] extern crate libimagrt;
extern crate libimagerror;
extern crate libimagentrylink;
extern crate libimagstore;
use std::io::Write;
use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagerror::trace::MapErrTrace;
use libimagerror::io::ToExitCode;
use libimagerror::exit::ExitUnwrap;
use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId;
use libimagentrylink::linkable::Linkable;
use toml::Value;
use toml_query::read::TomlValueReadExt;
use indicatif::{ProgressBar, ProgressStyle};
use failure::Fallible as Result;
use failure::Error;
use failure::err_msg;
use std::collections::BTreeMap;
mod ui;
#[derive(Debug)]
struct Diagnostic {
pub id: StoreId,
pub entry_store_version: String,
pub header_sections: usize,
pub bytecount_content: usize,
pub overall_byte_size: usize,
pub verified: bool,
pub num_links: usize,
}
impl Diagnostic {
fn for_entry<'a>(entry: &FileLockEntry<'a>) -> Result<Diagnostic> {
Ok(Diagnostic {
id: entry.get_location().clone(),
entry_store_version: entry
.get_header()
.read("imag.version")
.map(|opt| match opt {
Some(&Value::String(ref s)) => s.clone(),
Some(_) => "Non-String type in 'imag.version'".to_owned(),
None => "No version".to_owned(),
})
.unwrap_or_else(|_| "Error reading version".to_owned()),
header_sections: match entry.get_header() {
Value::Table(ref map) => map.keys().count(),
_ => 0
},
bytecount_content: entry.get_content().as_str().len(),
overall_byte_size: entry.to_str()?.as_str().len(),
verified: entry.verify().is_ok(),
num_links: entry.links().map(Iterator::count).unwrap_or(0),
})
}
}
macro_rules! do_write {
($dest:ident, $pattern:tt) => {
let _ = writeln!($dest, $pattern)
.to_exit_code()
.unwrap_or_exit();
};
($dest:ident, $pattern:tt, $( $args:expr ),*) => {
let _ = writeln!($dest, $pattern, $( $args ),*)
.to_exit_code()
.unwrap_or_exit();
}
}
fn main() {
let version = make_imag_version!();
let rt = generate_runtime_setup("imag-diagnostics",
&version,
"Print diagnostics about imag and the imag store",
ui::build_ui);
let template = get_config(&rt, "rt.progressbar_style");
let tick_chars = get_config(&rt, "rt.progressticker_chars");
let verbose = rt.cli().is_present("more-output");
let style = if let Some(tick_chars) = tick_chars {
ProgressStyle::default_spinner().tick_chars(&tick_chars)
} else {
ProgressStyle::default_spinner()
};
let spinner = ProgressBar::new_spinner();
spinner.enable_steady_tick(100);
spinner.set_style(style);
spinner.set_message("Accumulating data");
let diags = rt.store()
.entries()
.map_err_trace_exit_unwrap()
.into_get_iter()
.map(|e| {
e.map_err_trace_exit_unwrap()
.ok_or_else(|| err_msg("Unable to get entry".to_owned()))
.map_err_trace_exit_unwrap()
})
.map(|e| {
let diag = Diagnostic::for_entry(&e);
debug!("Diagnostic for '{:?}' = {:?}", e.get_location(), diag);
drop(e);
diag
})
.collect::<Result<Vec<_>>>()
.map_err_trace_exit_unwrap();
spinner.finish();
let n = diags.len();
let progress = ProgressBar::new(n as u64);
let style = if let Some(template) = template {
ProgressStyle::default_bar().template(&template)
} else {
ProgressStyle::default_bar()
};
progress.set_style(style);
progress.set_message("Calculating stats");
let mut version_counts : BTreeMap<String, usize> = BTreeMap::new();
let mut sum_header_sections = 0;
let mut sum_bytecount_content = 0;
let mut sum_overall_byte_size = 0;
let mut max_overall_byte_size : Option<(usize, StoreId)> = None;
let mut verified_count = 0;
let mut unverified_count = 0;
let mut unverified_entries = vec![];
let mut num_links = 0;
let mut max_links : Option<(usize, StoreId)> = None;
for diag in diags.iter() {
sum_header_sections += diag.header_sections;
sum_bytecount_content += diag.bytecount_content;
sum_overall_byte_size += diag.overall_byte_size;
match max_overall_byte_size {
None => max_overall_byte_size = Some((diag.num_links, diag.id.clone())),
Some((num, _)) => if num < diag.overall_byte_size {
max_overall_byte_size = Some((diag.overall_byte_size, diag.id.clone()));
}
}
let n = version_counts.get(&diag.entry_store_version).map(Clone::clone).unwrap_or(0);
version_counts.insert(diag.entry_store_version.clone(), n+1);
if diag.verified {
verified_count += 1;
} else {
unverified_count += 1;
if verbose {
unverified_entries.push(diag.id.clone());
}
}
num_links += diag.num_links;
match max_links {
None => max_links = Some((diag.num_links, diag.id.clone())),
Some((num, _)) => if num < diag.num_links {
max_links = Some((diag.num_links, diag.id.clone()));
}
}
progress.inc(1);
}
progress.finish();
let mut out = rt.stdout();
do_write!(out, "imag version {}", { env!("CARGO_PKG_VERSION") });
do_write!(out, "");
do_write!(out, "{} entries", n);
for (k, v) in version_counts {
do_write!(out, "{} entries with store version '{}'", v, k);
}
if n != 0 {
do_write!(out, "{} header sections in the average entry", sum_header_sections / n);
do_write!(out, "{} average content bytecount", sum_bytecount_content / n);
do_write!(out, "{} average overall bytecount", sum_overall_byte_size / n);
if let Some((num, path)) = max_overall_byte_size {
do_write!(out, "Largest Entry ({} bytes): {}", num, path.local_display_string());
}
do_write!(out, "{} average internal link count per entry", num_links / n);
if let Some((num, path)) = max_links {
do_write!(out, "Entry with most internal links ({}): {}",
num,
path.local_display_string());
}
do_write!(out, "{} verified entries", verified_count);
do_write!(out, "{} unverified entries", unverified_count);
if verbose {
for unve in unverified_entries.iter() {
do_write!(out, "Unverified: {}", unve);
}
}
}
}
fn get_config(rt: &Runtime, s: &'static str) -> Option<String> {
rt.config().and_then(|cfg| {
cfg.read(s)
.map_err(Error::from)
.map_err_trace_exit_unwrap()
.map(|opt| match opt {
Value::String(ref s) => s.to_owned(),
_ => {
error!("Config type wrong: 'rt.progressbar_style' should be a string");
::std::process::exit(1)
}
})
})
}

View file

@ -49,3 +49,10 @@ path = "../../../lib/core/libimagrt"
default-features = false default-features = false
features = ["testing"] features = ["testing"]
[lib]
name = "libimageditcmd"
path = "src/lib.rs"
[[bin]]
name = "imag-edit"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimageditcmd, ImagEdit);

View file

@ -0,0 +1,121 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
extern crate clap;
#[macro_use] extern crate log;
extern crate failure;
extern crate libimagentryedit;
extern crate libimagerror;
extern crate libimagrt;
extern crate libimagstore;
extern crate libimagutil;
use libimagerror::trace::MapErrTrace;
use libimagerror::iter::TraceIterator;
use libimagentryedit::edit::Edit;
use libimagentryedit::edit::EditHeader;
use libimagrt::runtime::Runtime;
use libimagrt::application::ImagApplication;
use libimagstore::storeid::StoreIdIterator;
use libimagstore::iter::get::StoreIdGetIteratorExtension;
use failure::Fallible as Result;
use clap::App;
mod ui;
/// Marker enum for implementing ImagApplication on
///
/// This is used by binaries crates to execute business logic
/// or to build a CLI completion.
pub enum ImagEdit {}
impl ImagApplication for ImagEdit {
fn run(rt: Runtime) -> Result<()> {
let edit_header = rt.cli().is_present("edit-header");
let edit_header_only = rt.cli().is_present("edit-header-only");
let sids = rt
.ids::<crate::ui::PathProvider>()
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("No ids supplied");
::std::process::exit(1);
})
.into_iter();
StoreIdIterator::new(Box::new(sids.into_iter().map(Ok)))
.into_get_iter(rt.store())
.trace_unwrap_exit()
.map(|o| o.unwrap_or_else(|| {
error!("Did not find one entry");
::std::process::exit(1)
}))
.for_each(|mut entry| {
if edit_header {
let _ = entry
.edit_header_and_content(&rt)
.map_err_trace_exit_unwrap();
} else if edit_header_only {
let _ = entry
.edit_header(&rt)
.map_err_trace_exit_unwrap();
} else {
let _ = entry
.edit_content(&rt)
.map_err_trace_exit_unwrap();
}
});
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Edit store entries with $EDITOR"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
}

View file

@ -1,99 +0,0 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
extern crate clap;
#[macro_use] extern crate log;
extern crate failure;
extern crate libimagentryedit;
extern crate libimagerror;
#[macro_use] extern crate libimagrt;
extern crate libimagstore;
extern crate libimagutil;
use libimagerror::trace::MapErrTrace;
use libimagerror::iter::TraceIterator;
use libimagentryedit::edit::Edit;
use libimagentryedit::edit::EditHeader;
use libimagrt::setup::generate_runtime_setup;
use libimagstore::storeid::StoreIdIterator;
use libimagstore::iter::get::StoreIdGetIteratorExtension;
mod ui;
fn main() {
let version = make_imag_version!();
let rt = generate_runtime_setup("imag-edit",
&version,
"Edit store entries with $EDITOR",
ui::build_ui);
let edit_header = rt.cli().is_present("edit-header");
let edit_header_only = rt.cli().is_present("edit-header-only");
let sids = rt
.ids::<crate::ui::PathProvider>()
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("No ids supplied");
::std::process::exit(1);
})
.into_iter();
StoreIdIterator::new(Box::new(sids.map(Ok)))
.into_get_iter(rt.store())
.trace_unwrap_exit()
.map(|o| o.unwrap_or_else(|| {
error!("Did not find one entry");
::std::process::exit(1)
}))
.for_each(|mut entry| {
if edit_header {
entry
.edit_header_and_content(&rt)
.map_err_trace_exit_unwrap();
} else if edit_header_only {
entry
.edit_header(&rt)
.map_err_trace_exit_unwrap();
} else {
entry
.edit_content(&rt)
.map_err_trace_exit_unwrap();
}
});
}

View file

@ -23,6 +23,7 @@ maintenance = { status = "actively-developed" }
log = "0.4.6" 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"
libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" } libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" }
libimagerror = { version = "0.10.0", path = "../../../lib/core/libimagerror" } libimagerror = { version = "0.10.0", path = "../../../lib/core/libimagerror" }
@ -32,3 +33,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["color", "suggestions", "wrap_help"] features = ["color", "suggestions", "wrap_help"]
[lib]
name = "libimaggitcmd"
path = "src/lib.rs"
[[bin]]
name = "imag-git"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimaggitcmd, ImagGit);

View file

@ -0,0 +1,197 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
extern crate clap;
#[macro_use] extern crate log;
extern crate toml;
extern crate toml_query;
extern crate failure;
extern crate libimagrt;
extern crate libimagerror;
use std::io::Write;
use std::io::ErrorKind;
use std::process::Command;
use toml::Value;
use toml_query::read::TomlValueReadExt;
use clap::App;
use failure::Fallible as Result;
use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode;
use libimagrt::runtime::Runtime;
use libimagrt::application::ImagApplication;
mod ui;
/// Marker enum for implementing ImagApplication on
///
/// This is used by binaries crates to execute business logic
/// or to build a CLI completion.
pub enum ImagGit {}
impl ImagApplication for ImagGit {
fn run(rt: Runtime) -> Result<()> {
let execute_in_store = rt
.config()
.unwrap_or_else(|| {
error!("No configuration. Please use git yourself, not via imag-git");
error!("Won't continue without configuration.");
::std::process::exit(1);
})
.read("git.execute_in_store")
.unwrap_or_else(|e| {
error!("Failed to read config setting 'git.execute_in_store'");
error!("-> {:?}", e);
::std::process::exit(1)
})
.unwrap_or_else(|| {
error!("Missing config setting 'git.execute_in_store'");
::std::process::exit(1)
});
let execute_in_store = match *execute_in_store {
Value::Boolean(b) => b,
_ => {
error!("Type error: 'git.execute_in_store' is not a boolean!");
::std::process::exit(1)
}
};
let execpath = if execute_in_store {
rt.store().path().to_str()
} else {
rt.rtp().to_str()
}
.map(String::from)
.unwrap_or_else(|| {
error!("Cannot parse to string: {:?}", rt.store().path());
::std::process::exit(1)
});
let mut command = Command::new("git");
command
.stdin(::std::process::Stdio::inherit())
.stdout(::std::process::Stdio::inherit())
.stderr(::std::process::Stdio::inherit())
.arg("-C").arg(&execpath);
let args = rt
.cli()
.values_of("")
.map(|vs| vs.map(String::from).collect())
.unwrap_or_else(|| vec![]);
debug!("Adding args = {:?}", args);
command.args(&args);
match rt.cli().subcommand() {
(external, Some(ext_m)) => {
command.arg(external);
let args = ext_m
.values_of("")
.map(|vs| vs.map(String::from).collect())
.unwrap_or_else(|| vec![]);
debug!("Adding subcommand '{}' and args = {:?}", external, args);
command.args(&args);
},
_ => {},
}
let mut out = rt.stdout();
debug!("Calling: {:?}", command);
match command.spawn().and_then(|mut c| c.wait()) {
Ok(exit_status) => {
if !exit_status.success() {
debug!("git exited with non-zero exit code: {:?}", exit_status);
let mut err = rt.stderr();
writeln!(err, "git exited with non-zero exit code")
.to_exit_code()
.unwrap_or_exit();
::std::process::exit(exit_status.code().unwrap_or(1));
}
debug!("Successful exit!");
},
Err(e) => {
debug!("Error calling git");
match e.kind() {
ErrorKind::NotFound => {
let _ = writeln!(out, "Cannot find 'git' executable")
.to_exit_code()
.unwrap_or_exit();
::std::process::exit(1);
},
ErrorKind::PermissionDenied => {
let _ = writeln!(out, "No permission to execute: 'git'")
.to_exit_code()
.unwrap_or_exit();
::std::process::exit(1);
},
_ => {
let _ = writeln!(out, "Error spawning: {:?}", e)
.to_exit_code()
.unwrap_or_exit();
::std::process::exit(1);
}
}
}
}
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Helper to call git in the store"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
}

View file

@ -1,171 +0,0 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
extern crate clap;
#[macro_use] extern crate log;
extern crate toml;
extern crate toml_query;
#[macro_use] extern crate libimagrt;
extern crate libimagerror;
use std::io::Write;
use std::io::ErrorKind;
use std::process::Command;
use toml::Value;
use toml_query::read::TomlValueReadExt;
use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode;
use libimagrt::setup::generate_runtime_setup;
mod ui;
fn main() {
let version = make_imag_version!();
let rt = generate_runtime_setup("imag-git",
&version,
"Helper to call git in the store",
ui::build_ui);
let execute_in_store = rt
.config()
.unwrap_or_else(|| {
error!("No configuration. Please use git yourself, not via imag-git");
error!("Won't continue without configuration.");
::std::process::exit(1);
})
.read("git.execute_in_store")
.unwrap_or_else(|e| {
error!("Failed to read config setting 'git.execute_in_store'");
error!("-> {:?}", e);
::std::process::exit(1)
})
.unwrap_or_else(|| {
error!("Missing config setting 'git.execute_in_store'");
::std::process::exit(1)
});
let execute_in_store = match *execute_in_store {
Value::Boolean(b) => b,
_ => {
error!("Type error: 'git.execute_in_store' is not a boolean!");
::std::process::exit(1)
}
};
let execpath = if execute_in_store {
rt.store().path().to_str()
} else {
rt.rtp().to_str()
}
.map(String::from)
.unwrap_or_else(|| {
error!("Cannot parse to string: {:?}", rt.store().path());
::std::process::exit(1)
});
let mut command = Command::new("git");
command
.stdin(::std::process::Stdio::inherit())
.stdout(::std::process::Stdio::inherit())
.stderr(::std::process::Stdio::inherit())
.arg("-C").arg(&execpath);
let args = rt
.cli()
.values_of("")
.map(|vs| vs.map(String::from).collect())
.unwrap_or_else(|| vec![]);
debug!("Adding args = {:?}", args);
command.args(&args);
if let (external, Some(ext_m)) = rt.cli().subcommand() {
command.arg(external);
let args = ext_m
.values_of("")
.map(|vs| vs.map(String::from).collect())
.unwrap_or_else(|| vec![]);
debug!("Adding subcommand '{}' and args = {:?}", external, args);
command.args(&args);
}
let mut out = rt.stdout();
debug!("Calling: {:?}", command);
match command.spawn().and_then(|mut c| c.wait()) {
Ok(exit_status) => {
if !exit_status.success() {
debug!("git exited with non-zero exit code: {:?}", exit_status);
let mut err = rt.stderr();
writeln!(err, "git exited with non-zero exit code")
.to_exit_code()
.unwrap_or_exit();
::std::process::exit(exit_status.code().unwrap_or(1));
}
debug!("Successful exit!");
},
Err(e) => {
debug!("Error calling git");
match e.kind() {
ErrorKind::NotFound => {
writeln!(out, "Cannot find 'git' executable")
.to_exit_code()
.unwrap_or_exit();
::std::process::exit(1);
},
ErrorKind::PermissionDenied => {
writeln!(out, "No permission to execute: 'git'")
.to_exit_code()
.unwrap_or_exit();
::std::process::exit(1);
},
_ => {
writeln!(out, "Error spawning: {:?}", e)
.to_exit_code()
.unwrap_or_exit();
::std::process::exit(1);
}
}
}
}
}

View file

@ -43,3 +43,10 @@ path = "../../../lib/etc/libimagutil"
default-features = false default-features = false
features = ["testing"] features = ["testing"]
[lib]
name = "libimaggpscmd"
path = "src/lib.rs"
[[bin]]
name = "imag-gps"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimaggpscmd, ImagGps);

View file

@ -39,7 +39,7 @@ extern crate clap;
#[macro_use] extern crate failure; #[macro_use] extern crate failure;
extern crate libimagentrygps; extern crate libimagentrygps;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagutil; extern crate libimagutil;
extern crate libimagerror; extern crate libimagerror;
extern crate libimagstore; extern crate libimagstore;
@ -50,11 +50,13 @@ use std::str::FromStr;
use failure::err_msg; use failure::err_msg;
use failure::Fallible as Result;
use clap::App;
use libimagstore::storeid::StoreId; use libimagstore::storeid::StoreId;
use libimagentrygps::types::*; use libimagentrygps::types::*;
use libimagentrygps::entry::*; use libimagentrygps::entry::*;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagerror::trace::MapErrTrace; use libimagerror::trace::MapErrTrace;
use libimagerror::exit::ExitUnwrap; use libimagerror::exit::ExitUnwrap;
@ -62,26 +64,45 @@ use libimagerror::io::ToExitCode;
mod ui; mod ui;
fn main() { /// Marker enum for implementing ImagApplication on
let version = make_imag_version!(); ///
let rt = generate_runtime_setup("imag-gps", /// This is used by binaries crates to execute business logic
&version, /// or to build a CLI completion.
"Add GPS coordinates to entries", pub enum ImagGps {}
ui::build_ui); impl ImagApplication for ImagGps {
fn run(rt: Runtime) -> Result<()> {
if let Some(name) = rt.cli().subcommand_name() { if let Some(name) = rt.cli().subcommand_name() {
match name { match name {
"add" => add(&rt), "add" => add(&rt),
"remove" => remove(&rt), "remove" => remove(&rt),
"get" => get(&rt), "get" => get(&rt),
other => { other => {
debug!("Unknown command"); debug!("Unknown command");
let _ = rt.handle_unknown_subcommand("imag-gps", other, rt.cli()) let _ = rt.handle_unknown_subcommand("imag-gps", other, rt.cli())
.map_err_trace_exit_unwrap() .map_err_trace_exit_unwrap()
.code() .code()
.map(::std::process::exit); .map(::std::process::exit);
}
} }
} }
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Add GPS coordinates to entries"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
} }
} }

View file

@ -22,6 +22,7 @@ maintenance = { status = "actively-developed" }
[dependencies] [dependencies]
log = "0.4.6" log = "0.4.6"
regex = "1.1.7" regex = "1.1.7"
failure = "0.1.5"
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" }
@ -32,3 +33,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["color", "suggestions", "wrap_help"] features = ["color", "suggestions", "wrap_help"]
[lib]
name = "libimaggrepcmd"
path = "src/lib.rs"
[[bin]]
name = "imag-grep"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimaggrepcmd, ImagGrep);

View file

@ -37,17 +37,20 @@
#[macro_use] extern crate log; #[macro_use] extern crate log;
extern crate clap; extern crate clap;
extern crate regex; extern crate regex;
extern crate failure;
extern crate libimagstore; extern crate libimagstore;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagerror; extern crate libimagerror;
use std::io::Write; use std::io::Write;
use regex::Regex; use regex::Regex;
use failure::Fallible as Result;
use clap::App;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
use libimagstore::store::Entry; use libimagstore::store::Entry;
use libimagerror::trace::MapErrTrace; use libimagerror::trace::MapErrTrace;
use libimagerror::exit::ExitUnwrap; use libimagerror::exit::ExitUnwrap;
@ -60,53 +63,72 @@ struct Options {
count: bool, count: bool,
} }
fn main() { /// Marker enum for implementing ImagApplication on
let version = make_imag_version!(); ///
let rt = generate_runtime_setup("imag-grep", /// This is used by binaries crates to execute business logic
&version, /// or to build a CLI completion.
"grep through entries text", pub enum ImagGrep {}
ui::build_ui); impl ImagApplication for ImagGrep {
fn run(rt: Runtime) -> Result<()> {
let opts = Options {
files_with_matches : rt.cli().is_present("files-with-matches"),
count : rt.cli().is_present("count"),
};
let opts = Options { let mut count : usize = 0;
files_with_matches : rt.cli().is_present("files-with-matches"),
count : rt.cli().is_present("count"),
};
let mut count : usize = 0; let pattern = rt
.cli()
.value_of("pattern")
.map(Regex::new)
.unwrap() // ensured by clap
.unwrap_or_else(|e| {
error!("Regex building error: {:?}", e);
::std::process::exit(1)
});
let pattern = rt let overall_count = rt
.cli() .store()
.value_of("pattern") .entries()
.map(Regex::new) .map_err_trace_exit_unwrap()
.unwrap() // ensured by clap .into_get_iter()
.unwrap_or_else(|e| { .filter_map(|res| res.map_err_trace_exit_unwrap())
error!("Regex building error: {:?}", e); .filter_map(|entry| if pattern.is_match(entry.get_content()) {
::std::process::exit(1) show(&rt, &entry, &pattern, &opts, &mut count);
}); Some(())
} else {
None
})
.count();
let overall_count = rt if opts.count {
.store() writeln!(rt.stdout(), "{}", count).to_exit_code().unwrap_or_exit();
.entries() } else if !opts.files_with_matches {
.map_err_trace_exit_unwrap() writeln!(rt.stdout(), "Processed {} files, {} matches, {} nonmatches",
.into_get_iter() overall_count,
.filter_map(|res| res.map_err_trace_exit_unwrap()) count,
.filter_map(|entry| if pattern.is_match(entry.get_content()) { overall_count - count)
show(&rt, &entry, &pattern, &opts, &mut count); .to_exit_code()
Some(()) .unwrap_or_exit();
} else { }
None
})
.count();
if opts.count { Ok(())
writeln!(rt.stdout(), "{}", count).to_exit_code().unwrap_or_exit(); }
} else if !opts.files_with_matches {
writeln!(rt.stdout(), "Processed {} files, {} matches, {} nonmatches", fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
overall_count, ui::build_ui(app)
count, }
overall_count - count)
.to_exit_code() fn name() -> &'static str {
.unwrap_or_exit(); env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"grep through entries text"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
} }
} }

View file

@ -45,3 +45,10 @@ path = "../../../lib/core/libimagrt"
default-features = false default-features = false
features = ["testing"] features = ["testing"]
[lib]
name = "libimagheadercmd"
path = "src/lib.rs"
[[bin]]
name = "imag-header"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagheadercmd, ImagHeader);

View file

@ -41,7 +41,7 @@ extern crate failure;
extern crate libimagentryedit; extern crate libimagentryedit;
extern crate libimagerror; extern crate libimagerror;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagstore; extern crate libimagstore;
extern crate libimagutil; extern crate libimagutil;
@ -49,10 +49,10 @@ use std::io::Write;
use std::str::FromStr; use std::str::FromStr;
use std::string::ToString; use std::string::ToString;
use clap::ArgMatches; use clap::{App, ArgMatches};
use filters::filter::Filter; use filters::filter::Filter;
use failure::Error;
use toml::Value; use toml::Value;
use failure::{Fallible as Result, Error};
use libimagerror::exit::ExitCode; use libimagerror::exit::ExitCode;
use libimagerror::exit::ExitUnwrap; use libimagerror::exit::ExitUnwrap;
@ -60,7 +60,7 @@ use libimagerror::io::ToExitCode;
use libimagerror::iter::TraceIterator; use libimagerror::iter::TraceIterator;
use libimagerror::trace::MapErrTrace; use libimagerror::trace::MapErrTrace;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
use libimagstore::iter::get::StoreIdGetIteratorExtension; use libimagstore::iter::get::StoreIdGetIteratorExtension;
use libimagstore::store::FileLockEntry; use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreIdIterator; use libimagstore::storeid::StoreIdIterator;
@ -68,55 +68,73 @@ use libimagstore::storeid::StoreIdIterator;
use toml_query::read::TomlValueReadExt; use toml_query::read::TomlValueReadExt;
use toml_query::read::TomlValueReadTypeExt; use toml_query::read::TomlValueReadTypeExt;
mod ui; mod ui;
const EPS_CMP: f64 = 1e-10; const EPS_CMP: f64 = 1e-10;
fn main() { /// Marker enum for implementing ImagApplication on
let version = make_imag_version!(); ///
let rt = generate_runtime_setup("imag-header", /// This is used by binaries crates to execute business logic
&version, /// or to build a CLI completion.
"Plumbing tool for reading/writing structured data in entries", pub enum ImagHeader {}
ui::build_ui); impl ImagApplication for ImagHeader {
fn run(rt: Runtime) -> Result<()> {
let list_output_with_ids = rt.cli().is_present("list-id");
let list_output_with_ids_fmt = rt.cli().value_of("list-id-format");
let list_output_with_ids = rt.cli().is_present("list-id"); trace!("list_output_with_ids = {:?}", list_output_with_ids );
let list_output_with_ids_fmt = rt.cli().value_of("list-id-format"); trace!("list_output_with_ids_fmt = {:?}", list_output_with_ids_fmt);
trace!("list_output_with_ids = {:?}", list_output_with_ids ); let sids = rt
trace!("list_output_with_ids_fmt = {:?}", list_output_with_ids_fmt); .ids::<crate::ui::PathProvider>()
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("No ids supplied");
::std::process::exit(1);
})
.into_iter();
let sids = rt let iter = StoreIdIterator::new(Box::new(sids.map(Ok)))
.ids::<crate::ui::PathProvider>() .into_get_iter(rt.store())
.map_err_trace_exit_unwrap() .trace_unwrap_exit()
.unwrap_or_else(|| { .filter_map(|x| x);
error!("No ids supplied");
::std::process::exit(1);
})
.into_iter();
let iter = StoreIdIterator::new(Box::new(sids.map(Ok))) match rt.cli().subcommand() {
.into_get_iter(rt.store()) ("read", Some(mtch)) => ::std::process::exit(read(&rt, mtch, iter)),
.trace_unwrap_exit() ("has", Some(mtch)) => has(&rt, mtch, iter),
.filter_map(|x| x); ("hasnt", Some(mtch)) => hasnt(&rt, mtch, iter),
("int", Some(mtch)) => int(&rt, mtch, iter),
("float", Some(mtch)) => float(&rt, mtch, iter),
("string", Some(mtch)) => string(&rt, mtch, iter),
("bool", Some(mtch)) => boolean(&rt, mtch, iter),
(other, _mtchs) => {
debug!("Unknown command");
::std::process::exit({
rt.handle_unknown_subcommand("imag-header", other, rt.cli())
.map_err_trace_exit_unwrap()
.code()
.unwrap_or(1)
});
},
};
match rt.cli().subcommand() { Ok(())
("read", Some(mtch)) => ::std::process::exit(read(&rt, mtch, iter)), }
("has", Some(mtch)) => has(&rt, mtch, iter),
("hasnt", Some(mtch)) => hasnt(&rt, mtch, iter), fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
("int", Some(mtch)) => int(&rt, mtch, iter), ui::build_ui(app)
("float", Some(mtch)) => float(&rt, mtch, iter), }
("string", Some(mtch)) => string(&rt, mtch, iter),
("bool", Some(mtch)) => boolean(&rt, mtch, iter), fn name() -> &'static str {
(other, _mtchs) => { env!("CARGO_PKG_NAME")
debug!("Unknown command"); }
::std::process::exit({
rt.handle_unknown_subcommand("imag-header", other, rt.cli()) fn description() -> &'static str {
.map_err_trace_exit_unwrap() "Plumbing tool for reading/writing structured data in entries"
.code() }
.unwrap_or(1)
}); fn version() -> &'static str {
}, env!("CARGO_PKG_VERSION")
} }
} }

View file

@ -37,3 +37,10 @@ features = ["color", "suggestions", "wrap_help"]
[dev-dependencies] [dev-dependencies]
env_logger = "0.7" env_logger = "0.7"
[lib]
name = "libimagidscmd"
path = "src/lib.rs"
[[bin]]
name = "imag-ids"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagidscmd, ImagIds);

View file

@ -0,0 +1,134 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
extern crate clap;
#[macro_use] extern crate log;
extern crate toml;
extern crate toml_query;
#[macro_use] extern crate failure;
#[cfg(test)]
extern crate env_logger;
extern crate libimagerror;
extern crate libimagstore;
extern crate libimagrt;
use std::io::Write;
use std::result::Result as RResult;
use failure::Fallible as Result;
use clap::App;
use libimagstore::storeid::StoreId;
use libimagrt::runtime::Runtime;
use libimagrt::application::ImagApplication;
use libimagerror::trace::MapErrTrace;
use libimagerror::iter::TraceIterator;
use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode;
mod ui;
/// Marker enum for implementing ImagApplication on
///
/// This is used by binaries crates to execute business logic
/// or to build a CLI completion.
pub enum ImagIds {}
impl ImagApplication for ImagIds {
fn run(rt: Runtime) -> Result<()> {
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();
trace!("Got output: {:?}", stdout);
iterator.for_each(|(storepath, id)| {
rt.report_touched(&id).unwrap_or_exit();
if !rt.output_is_pipe() {
let id = id.to_str().map_err_trace_exit_unwrap();
trace!("Writing to {:?}", stdout);
let result = if let Some(store) = storepath {
writeln!(stdout, "{}/{}", store.display(), id)
} else {
writeln!(stdout, "{}", id)
};
result.to_exit_code().unwrap_or_exit();
}
});
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"print all ids"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
}

View file

@ -1,113 +0,0 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
extern crate clap;
#[macro_use] extern crate log;
extern crate toml;
extern crate toml_query;
#[macro_use] extern crate failure;
#[cfg(test)]
extern crate env_logger;
extern crate libimagerror;
extern crate libimagstore;
#[macro_use] extern crate libimagrt;
use std::io::Write;
use libimagstore::storeid::StoreId;
use libimagrt::setup::generate_runtime_setup;
use libimagerror::trace::MapErrTrace;
use libimagerror::iter::TraceIterator;
use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode;
mod ui;
use crate::ui::build_ui;
fn main() {
let version = make_imag_version!();
let rt = generate_runtime_setup("imag-ids",
&version,
"print all ids",
build_ui);
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 = Result<StoreId, _>>>
} else {
Box::new(rt.store().entries().map_err_trace_exit_unwrap())
as Box<dyn Iterator<Item = Result<StoreId, _>>>
}
.trace_unwrap_exit()
.map(|id| if print_storepath {
(Some(rt.store().path()), id)
} else {
(None, id)
});
let mut stdout = rt.stdout();
trace!("Got output: {:?}", stdout);
iterator.for_each(|(storepath, id)| {
rt.report_touched(&id).unwrap_or_exit();
if !rt.output_is_pipe() {
let id = id.to_str().map_err_trace_exit_unwrap();
trace!("Writing to {:?}", stdout);
let result = if let Some(store) = storepath {
writeln!(stdout, "{}/{}", store.display(), id)
} else {
writeln!(stdout, "{}", id)
};
result.to_exit_code().unwrap_or_exit();
}
})
}

View file

@ -20,6 +20,8 @@ is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
maintenance = { status = "actively-developed" } maintenance = { status = "actively-developed" }
[dependencies] [dependencies]
failure = "0.1.5"
libimagerror = { version = "0.10.0", path = "../../../lib/core/libimagerror" } libimagerror = { version = "0.10.0", path = "../../../lib/core/libimagerror" }
libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" } libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" }
@ -31,3 +33,10 @@ features = ["color", "suggestions", "wrap_help"]
[dev-dependencies] [dev-dependencies]
toml = "0.5.1" toml = "0.5.1"
[lib]
name = "libimaginitcmd"
path = "src/lib.rs"
[[bin]]
name = "imag-init"
path = "src/bin.rs"

View file

@ -0,0 +1,46 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
extern crate failure;
use failure::Fallible as Result;
extern crate libimaginitcmd;
fn main() -> Result<()> {
libimaginitcmd::imag_init();
Ok(())
}

View file

@ -35,7 +35,7 @@
)] )]
extern crate clap; extern crate clap;
extern crate failure;
#[cfg(test)] #[cfg(test)]
extern crate toml; extern crate toml;
@ -53,6 +53,10 @@ use std::process::Command;
use libimagerror::exit::ExitUnwrap; use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode; use libimagerror::io::ToExitCode;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::application::ImagApplication;
use failure::Fallible as Result;
use clap::App;
const CONFIGURATION_STR : &str = include_str!("../imagrc.toml"); const CONFIGURATION_STR : &str = include_str!("../imagrc.toml");
@ -69,7 +73,34 @@ const GITIGNORE_STR : &str = r#"
imagrc.toml imagrc.toml
"#; "#;
fn main() { /// Marker enum for implementing ImagApplication on
///
/// This is used by binaries crates to execute business logic
/// or to build a CLI completion.
pub enum ImagInit {}
impl ImagApplication for ImagInit {
fn run(_rt: Runtime) -> Result<()> {
panic!("imag-init needs to be run as a seperate binary, or we'll need to figure something out here!");
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Intialize the imag store"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
}
pub fn imag_init() {
let version = make_imag_version!(); let version = make_imag_version!();
let app = ui::build_ui(Runtime::get_default_cli_builder( let app = ui::build_ui(Runtime::get_default_cli_builder(
"imag-init", "imag-init",

View file

@ -54,4 +54,10 @@ path = "../../../lib/core/libimagrt"
default-features = false default-features = false
features = ["testing"] features = ["testing"]
[lib]
name = "libimaglinkcmd"
path = "src/lib.rs"
[[bin]]
name = "imag-link"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimaglinkcmd, ImagLink);

View file

@ -45,7 +45,7 @@ extern crate failure;
extern crate libimagentrylink; extern crate libimagentrylink;
extern crate libimagentryurl; extern crate libimagentryurl;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagstore; extern crate libimagstore;
extern crate libimagerror; extern crate libimagerror;
@ -69,7 +69,7 @@ use libimagerror::trace::{MapErrTrace, trace_error};
use libimagerror::exit::ExitUnwrap; use libimagerror::exit::ExitUnwrap;
use libimagerror::io::ToExitCode; use libimagerror::io::ToExitCode;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
use libimagstore::store::FileLockEntry; use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreId; use libimagstore::storeid::StoreId;
use libimagutil::warn_exit::warn_exit; use libimagutil::warn_exit::warn_exit;
@ -77,57 +77,75 @@ use libimagutil::warn_result::*;
use url::Url; use url::Url;
use failure::Fallible as Result; use failure::Fallible as Result;
use clap::App;
mod ui; mod ui;
use crate::ui::build_ui; /// Marker enum for implementing ImagApplication on
///
/// This is used by binaries crates to execute business logic
/// or to build a CLI completion.
pub enum ImagLink {}
impl ImagApplication for ImagLink {
fn run(rt: Runtime) -> Result<()> {
if rt.cli().is_present("check-consistency") {
let exit_code = match rt.store().check_link_consistency() {
Ok(_) => {
info!("Store is consistent");
0
}
Err(e) => {
trace_error(&e);
1
}
};
::std::process::exit(exit_code);
}
fn main() { let _ = rt.cli()
let version = make_imag_version!(); .subcommand_name()
let rt = generate_runtime_setup("imag-link", .map(|name| {
&version, match name {
"Link entries", "remove" => remove_linking(&rt),
build_ui); "unlink" => unlink(&rt),
if rt.cli().is_present("check-consistency") { "list" => list_linkings(&rt),
let exit_code = match rt.store().check_link_consistency() { other => {
Ok(_) => { debug!("Unknown command");
info!("Store is consistent"); let _ = rt.handle_unknown_subcommand("imag-link", other, rt.cli())
0 .map_err_trace_exit_unwrap()
} .code()
Err(e) => { .map(::std::process::exit);
trace_error(&e); },
1 }
} })
}; .or_else(|| {
::std::process::exit(exit_code); if let (Some(from), Some(to)) = (rt.cli().value_of("from"), rt.cli().values_of("to")) {
Some(link_from_to(&rt, from, to))
} else {
warn_exit("No commandline call", 1)
}
})
.ok_or_else(|| err_msg("No commandline call".to_owned()))
.map_err_trace_exit_unwrap();
Ok(())
} }
rt.cli() fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
.subcommand_name() ui::build_ui(app)
.map(|name| { }
match name {
"remove" => remove_linking(&rt), fn name() -> &'static str {
"unlink" => unlink(&rt), env!("CARGO_PKG_NAME")
"list" => list_linkings(&rt), }
other => {
debug!("Unknown command"); fn description() -> &'static str {
let _ = rt.handle_unknown_subcommand("imag-link", other, rt.cli()) "Link entries"
.map_err_trace_exit_unwrap() }
.code()
.map(::std::process::exit); fn version() -> &'static str {
}, env!("CARGO_PKG_VERSION")
} }
})
.or_else(|| {
if let (Some(from), Some(to)) = (rt.cli().value_of("from"), rt.cli().values_of("to")) {
link_from_to(&rt, from, to);
Some(())
} else {
warn_exit("No commandline call", 1)
}
})
.ok_or_else(|| err_msg("No commandline call".to_owned()))
.map_err_trace_exit_unwrap();
} }
fn get_entry_by_name<'a>(rt: &'a Runtime, name: &str) -> Result<Option<FileLockEntry<'a>>> { fn get_entry_by_name<'a>(rt: &'a Runtime, name: &str) -> Result<Option<FileLockEntry<'a>>> {
@ -378,6 +396,7 @@ mod tests {
modulename mock; modulename mock;
version env!("CARGO_PKG_VERSION"); version env!("CARGO_PKG_VERSION");
with help "imag-link mocking app"; with help "imag-link mocking app";
with ui builder function crate::ui::build_ui;
} }
use self::mock::generate_test_runtime; use self::mock::generate_test_runtime;
use self::mock::reset_test_runtime; use self::mock::reset_test_runtime;

View file

@ -34,3 +34,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["color", "suggestions", "wrap_help"] features = ["color", "suggestions", "wrap_help"]
[lib]
name = "libimagmarkdowncmd"
path = "src/lib.rs"
[[bin]]
name = "imag-markdown"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagmarkdowncmd, ImagMarkdown);

View file

@ -0,0 +1,123 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
extern crate clap;
#[macro_use] extern crate log;
extern crate failure;
extern crate libimagerror;
extern crate libimagrt;
extern crate libimagstore;
use std::io::Write;
use failure::Error;
use failure::err_msg;
use failure::Fallible as Result;
use clap::App;
use libimagerror::trace::MapErrTrace;
use libimagerror::iter::TraceIterator;
use libimagrt::runtime::Runtime;
use libimagrt::application::ImagApplication;
use libimagstore::iter::get::StoreIdGetIteratorExtension;
mod ui;
/// Marker enum for implementing ImagApplication on
///
/// This is used by binaries crates to execute business logic
/// or to build a CLI completion.
pub enum ImagMarkdown {}
impl ImagApplication for ImagMarkdown {
fn run(rt: Runtime) -> Result<()> {
let only_links = rt.cli().is_present("links");
let out = rt.stdout();
let mut outlock = out.lock();
let iter = rt
.ids::<crate::ui::PathProvider>()
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("No ids supplied");
::std::process::exit(1);
})
.into_iter()
.map(Ok)
.into_get_iter(rt.store())
.trace_unwrap_exit()
.map(|ofle| ofle.ok_or_else(|| {
err_msg("Entry does not exist but is in store. This is a BUG, please report!")
}))
.trace_unwrap_exit();
if only_links {
iter.map(|fle| libimagentrymarkdown::link::extract_links(fle.get_content()))
.for_each(|links| {
links.iter().for_each(|link| {
writeln!(outlock, "{title}: {link}", title = link.title, link = link.link)
.map_err(Error::from)
.map_err_trace_exit_unwrap();
})
})
} else {
iter.map(|fle| libimagentrymarkdown::html::to_html(fle.get_content()))
.trace_unwrap_exit()
.for_each(|html| {
writeln!(outlock, "{}", html).map_err(Error::from).map_err_trace_exit_unwrap();
})
}
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Print one or more imag entries after processing them with a markdown parser"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
}

View file

@ -1,102 +0,0 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
extern crate clap;
#[macro_use] extern crate log;
extern crate failure;
extern crate libimagerror;
#[macro_use] extern crate libimagrt;
extern crate libimagstore;
use std::io::Write;
use failure::Error;
use failure::err_msg;
use libimagerror::trace::MapErrTrace;
use libimagerror::iter::TraceIterator;
use libimagrt::setup::generate_runtime_setup;
use libimagstore::iter::get::StoreIdGetIteratorExtension;
mod ui;
fn main() {
let version = make_imag_version!();
let rt = generate_runtime_setup("imag-markdown",
&version,
"Print one or more imag entries after processing them with a markdown parser",
ui::build_ui);
let only_links = rt.cli().is_present("links");
let out = rt.stdout();
let mut outlock = out.lock();
let iter = rt
.ids::<crate::ui::PathProvider>()
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("No ids supplied");
::std::process::exit(1);
})
.into_iter()
.map(Ok)
.into_get_iter(rt.store())
.trace_unwrap_exit()
.map(|ofle| ofle.ok_or_else(|| {
err_msg("Entry does not exist but is in store. This is a BUG, please report!")
}))
.trace_unwrap_exit();
if only_links {
iter.map(|fle| libimagentrymarkdown::link::extract_links(fle.get_content()))
.for_each(|links| {
links.iter().for_each(|link| {
writeln!(outlock, "{title}: {link}", title = link.title, link = link.link)
.map_err(Error::from)
.map_err_trace_exit_unwrap();
})
})
} else {
iter.map(|fle| libimagentrymarkdown::html::to_html(fle.get_content()))
.trace_unwrap_exit()
.for_each(|html| {
writeln!(outlock, "{}", html).map_err(Error::from).map_err_trace_exit_unwrap();
})
}
}

View file

@ -21,6 +21,7 @@ maintenance = { status = "actively-developed" }
[dependencies] [dependencies]
log = "0.4.6" log = "0.4.6"
failure = "0.1.5"
libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" } libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" }
libimagerror = { version = "0.10.0", path = "../../../lib/core/libimagerror" } libimagerror = { version = "0.10.0", path = "../../../lib/core/libimagerror" }
@ -32,3 +33,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["color", "suggestions", "wrap_help"] features = ["color", "suggestions", "wrap_help"]
[lib]
name = "libimagmvcmd"
path = "src/lib.rs"
[[bin]]
name = "imag-mv"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagmvcmd, ImagMv);

181
bin/core/imag-mv/src/lib.rs Normal file
View file

@ -0,0 +1,181 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate log;
extern crate clap;
extern crate failure;
extern crate libimagrt;
extern crate libimagstore;
extern crate libimagerror;
extern crate libimagentrylink;
use std::process::exit;
mod ui;
use std::path::PathBuf;
use std::result::Result as RResult;
use libimagrt::runtime::Runtime;
use libimagrt::application::ImagApplication;
use libimagerror::trace::MapErrTrace;
use libimagerror::iter::TraceIterator;
use libimagerror::exit::ExitUnwrap;
use libimagstore::storeid::StoreId;
use libimagstore::store::Store;
use libimagstore::store::FileLockEntry;
use libimagentrylink::linkable::Linkable;
use libimagstore::iter::get::StoreIdGetIteratorExtension;
use failure::Fallible as Result;
use clap::App;
/// Marker enum for implementing ImagApplication on
///
/// This is used by binaries crates to execute business logic
/// or to build a CLI completion.
pub enum ImagMv {}
impl ImagApplication for ImagMv {
fn run(rt: Runtime) -> Result<()> {
let sourcename = rt
.cli()
.value_of("source")
.map(PathBuf::from)
.map(StoreId::new)
.unwrap() // unwrap safe by clap
.map_err_trace_exit_unwrap();
let destname = rt
.cli()
.value_of("dest")
.map(PathBuf::from)
.map(StoreId::new)
.unwrap() // unwrap safe by clap
.map_err_trace_exit_unwrap();
// remove links to entry, and re-add them later
let mut linked_entries = {
rt.store()
.get(sourcename.clone())
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("Funny things happened: Entry moved to destination did not fail, but entry does not exist");
exit(1)
})
.links()
.map_err_trace_exit_unwrap()
.map(|link| Ok(link.get_store_id().clone()) as RResult<_, _>)
.into_get_iter(rt.store())
.trace_unwrap_exit()
.map(|e| {
e.unwrap_or_else(|| {
error!("Linked entry does not exist");
exit(1)
})
})
.collect::<Vec<_>>()
};
{ // remove links to linked entries from source
let mut entry = rt
.store()
.get(sourcename.clone())
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("Source Entry does not exist");
exit(1)
});
for link in linked_entries.iter_mut() {
let _ = entry.remove_link(link).map_err_trace_exit_unwrap();
}
}
let _ = rt
.store()
.move_by_id(sourcename.clone(), destname.clone())
.map_err(|e| { // on error, re-add links
debug!("Re-adding links to source entry because moving failed");
relink(rt.store(), sourcename.clone(), &mut linked_entries);
e
})
.map_err_trace_exit_unwrap();
let _ = rt.report_touched(&destname).unwrap_or_exit();
// re-add links to moved entry
relink(rt.store(), destname, &mut linked_entries);
info!("Ok.");
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Move things around in the store"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
}
fn relink<'a>(store: &'a Store, target: StoreId, linked_entries: &mut Vec<FileLockEntry<'a>>) {
let mut entry = store
.get(target)
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("Funny things happened: Entry moved to destination did not fail, but entry does not exist");
exit(1)
});
for mut link in linked_entries {
let _ = entry.add_link(&mut link).map_err_trace_exit_unwrap();
}
}

View file

@ -1,156 +0,0 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate log;
extern crate clap;
#[macro_use] extern crate libimagrt;
extern crate libimagstore;
extern crate libimagerror;
extern crate libimagentrylink;
use std::process::exit;
mod ui;
use crate::ui::build_ui;
use std::path::PathBuf;
use libimagrt::setup::generate_runtime_setup;
use libimagerror::trace::MapErrTrace;
use libimagerror::iter::TraceIterator;
use libimagerror::exit::ExitUnwrap;
use libimagstore::storeid::StoreId;
use libimagstore::store::Store;
use libimagstore::store::FileLockEntry;
use libimagentrylink::linkable::Linkable;
use libimagstore::iter::get::StoreIdGetIteratorExtension;
fn main() {
let version = make_imag_version!();
let rt = generate_runtime_setup("imag-mv",
&version,
"Move things around in the store",
build_ui);
debug!("mv");
let sourcename = rt
.cli()
.value_of("source")
.map(PathBuf::from)
.map(StoreId::new)
.unwrap() // unwrap safe by clap
.map_err_trace_exit_unwrap();
let destname = rt
.cli()
.value_of("dest")
.map(PathBuf::from)
.map(StoreId::new)
.unwrap() // unwrap safe by clap
.map_err_trace_exit_unwrap();
// remove links to entry, and re-add them later
let mut linked_entries = {
rt.store()
.get(sourcename.clone())
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("Funny things happened: Entry moved to destination did not fail, but entry does not exist");
exit(1)
})
.links()
.map_err_trace_exit_unwrap()
.map(|link| Ok(link.get_store_id().clone()) as Result<_, _>)
.into_get_iter(rt.store())
.trace_unwrap_exit()
.map(|e| {
e.unwrap_or_else(|| {
error!("Linked entry does not exist");
exit(1)
})
})
.collect::<Vec<_>>()
};
{ // remove links to linked entries from source
let mut entry = rt
.store()
.get(sourcename.clone())
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("Source Entry does not exist");
exit(1)
});
for link in linked_entries.iter_mut() {
entry.remove_link(link).map_err_trace_exit_unwrap();
}
}
rt
.store()
.move_by_id(sourcename.clone(), destname.clone())
.map_err(|e| { // on error, re-add links
debug!("Re-adding links to source entry because moving failed");
relink(rt.store(), sourcename.clone(), &mut linked_entries);
e
})
.map_err_trace_exit_unwrap();
rt.report_touched(&destname).unwrap_or_exit();
// re-add links to moved entry
relink(rt.store(), destname, &mut linked_entries);
info!("Ok.");
}
fn relink<'a>(store: &'a Store, target: StoreId, linked_entries: &mut Vec<FileLockEntry<'a>>) {
let mut entry = store
.get(target)
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("Funny things happened: Entry moved to destination did not fail, but entry does not exist");
exit(1)
});
for mut link in linked_entries {
entry.add_link(&mut link).map_err_trace_exit_unwrap();
}
}

View file

@ -35,3 +35,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["color", "suggestions", "wrap_help"] features = ["color", "suggestions", "wrap_help"]
[lib]
name = "libimagrefcmd"
path = "src/lib.rs"
[[bin]]
name = "imag-ref"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagrefcmd, ImagRef);

View file

@ -39,23 +39,24 @@ extern crate clap;
#[macro_use] extern crate failure; #[macro_use] extern crate failure;
extern crate libimagstore; extern crate libimagstore;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagentryref; extern crate libimagentryref;
extern crate libimagerror; extern crate libimagerror;
extern crate libimaginteraction; extern crate libimaginteraction;
extern crate libimagutil; extern crate libimagutil;
mod ui; mod ui;
use crate::ui::build_ui;
use std::process::exit; use std::process::exit;
use std::io::Write; use std::io::Write;
use failure::Error; use failure::Error;
use failure::Fallible as Result;
use clap::App;
use libimagerror::trace::MapErrTrace; use libimagerror::trace::MapErrTrace;
use libimagerror::exit::ExitUnwrap; use libimagerror::exit::ExitUnwrap;
use libimagrt::setup::generate_runtime_setup; 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::MutRef;
@ -63,27 +64,47 @@ 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;
fn main() { /// Marker enum for implementing ImagApplication on
let version = make_imag_version!(); ///
let rt = generate_runtime_setup("imag-ref", /// This is used by binaries crates to execute business logic
&version, /// or to build a CLI completion.
"Reference files outside of the store", pub enum ImagRef {}
build_ui); impl ImagApplication for ImagRef {
if let Some(name) = rt.cli().subcommand_name() { fn run(rt: Runtime) -> Result<()> {
debug!("Call: {}", name); if let Some(name) = rt.cli().subcommand_name() {
match name { debug!("Call: {}", name);
"deref" => deref(&rt), match name {
"create" => create(&rt), "deref" => deref(&rt),
"remove" => remove(&rt), "create" => create(&rt),
"list-dead" => list_dead(&rt), "remove" => remove(&rt),
other => { "list-dead" => list_dead(&rt),
debug!("Unknown command"); other => {
let _ = rt.handle_unknown_subcommand("imag-ref", other, rt.cli()) debug!("Unknown command");
.map_err_trace_exit_unwrap() let _ = rt.handle_unknown_subcommand("imag-ref", other, rt.cli())
.code() .map_err_trace_exit_unwrap()
.map(::std::process::exit); .code()
}, .map(::std::process::exit);
},
}
}; };
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Reference files outside of the store"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
} }
} }

View file

@ -52,3 +52,10 @@ path = "../../../lib/core/libimagrt"
default-features = false default-features = false
features = ["testing"] features = ["testing"]
[lib]
name = "libimagstorecmd"
path = "src/lib.rs"
[[bin]]
name = "imag-store"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagstorecmd, ImagStore);

View file

@ -168,6 +168,7 @@ mod tests {
modulename mock; modulename mock;
version env!("CARGO_PKG_VERSION"); version env!("CARGO_PKG_VERSION");
with help "imag-store mocking app"; with help "imag-store mocking app";
with ui builder function crate::ui::build_ui;
} }
use self::mock::generate_test_runtime; use self::mock::generate_test_runtime;

View file

@ -49,6 +49,7 @@ mod tests {
modulename mock; modulename mock;
version env!("CARGO_PKG_VERSION"); version env!("CARGO_PKG_VERSION");
with help "imag-store mocking app"; with help "imag-store mocking app";
with ui builder function crate::ui::build_ui;
} }
use self::mock::generate_test_runtime; use self::mock::generate_test_runtime;
use self::mock::reset_test_runtime; use self::mock::reset_test_runtime;

View file

@ -40,7 +40,7 @@ extern crate toml;
#[cfg(test)] extern crate toml_query; #[cfg(test)] extern crate toml_query;
extern crate failure; extern crate failure;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagstore; extern crate libimagstore;
extern crate libimagerror; extern crate libimagerror;
@ -51,7 +51,8 @@ extern crate libimagutil;
#[cfg(not(test))] #[cfg(not(test))]
extern crate libimagutil; extern crate libimagutil;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
use libimagrt::runtime::Runtime;
use libimagerror::trace::MapErrTrace; use libimagerror::trace::MapErrTrace;
mod create; mod create;
@ -65,42 +66,62 @@ mod util;
use std::ops::Deref; use std::ops::Deref;
use failure::Fallible as Result;
use clap::App;
use crate::create::create; use crate::create::create;
use crate::delete::delete; use crate::delete::delete;
use crate::get::get; use crate::get::get;
use crate::retrieve::retrieve; use crate::retrieve::retrieve;
use crate::ui::build_ui;
use crate::update::update; use crate::update::update;
use crate::verify::verify; use crate::verify::verify;
fn main() { /// Marker enum for implementing ImagApplication on
let version = make_imag_version!(); ///
let rt = generate_runtime_setup("imag-store", /// This is used by binaries crates to execute business logic
&version, /// or to build a CLI completion.
"Direct interface to the store. Use with great care!", pub enum ImagStore {}
build_ui); impl ImagApplication for ImagStore {
fn run(rt: Runtime) -> Result<()> {
let command = rt.cli().subcommand_name().map(String::from);
let command = rt.cli().subcommand_name().map(String::from); if let Some(command) = command {
debug!("Call: {}", command);
match command.deref() {
"create" => create(&rt),
"delete" => delete(&rt),
"get" => get(&rt),
"retrieve" => retrieve(&rt),
"update" => update(&rt),
"verify" => verify(&rt),
other => {
debug!("Unknown command");
let _ = rt.handle_unknown_subcommand("imag-store", other, rt.cli())
.map_err_trace_exit_unwrap()
.code()
.map(::std::process::exit);
},
};
} else {
debug!("No command");
}
if let Some(command) = command { Ok(())
debug!("Call: {}", command); }
match command.deref() {
"create" => create(&rt), fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
"delete" => delete(&rt), ui::build_ui(app)
"get" => get(&rt), }
"retrieve" => retrieve(&rt),
"update" => update(&rt), fn name() -> &'static str {
"verify" => verify(&rt), env!("CARGO_PKG_NAME")
other => { }
debug!("Unknown command");
let _ = rt.handle_unknown_subcommand("imag-store", other, rt.cli()) fn description() -> &'static str {
.map_err_trace_exit_unwrap() "Direct interface to the store. Use with great care!"
.code() }
.map(::std::process::exit);
}, fn version() -> &'static str {
}; env!("CARGO_PKG_VERSION")
} else {
debug!("No command");
} }
} }

View file

@ -51,3 +51,10 @@ path = "../../../lib/core/libimagrt"
default-features = false default-features = false
features = ["testing"] features = ["testing"]
[lib]
name = "libimagtagcmd"
path = "src/lib.rs"
[[bin]]
name = "imag-tag"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagtagcmd, ImagTag);

View file

@ -41,7 +41,7 @@ extern crate clap;
extern crate failure; extern crate failure;
extern crate libimagstore; extern crate libimagstore;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagentrytag; extern crate libimagentrytag;
extern crate libimagerror; extern crate libimagerror;
@ -61,7 +61,7 @@ extern crate env_logger;
use std::io::Write; use std::io::Write;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
use libimagentrytag::tagable::Tagable; use libimagentrytag::tagable::Tagable;
use libimagentrytag::tag::Tag; use libimagentrytag::tag::Tag;
use libimagerror::trace::trace_error; use libimagerror::trace::trace_error;
@ -71,53 +71,72 @@ use libimagerror::exit::ExitUnwrap;
use libimagstore::storeid::StoreId; use libimagstore::storeid::StoreId;
use libimagutil::warn_exit::warn_exit; use libimagutil::warn_exit::warn_exit;
use clap::ArgMatches; use clap::{App, ArgMatches};
use failure::Fallible as Result;
mod ui; mod ui;
use crate::ui::build_ui;
fn main() { /// Marker enum for implementing ImagApplication on
let version = make_imag_version!(); ///
let rt = generate_runtime_setup("imag-tag", /// This is used by binaries crates to execute business logic
&version, /// or to build a CLI completion.
"Direct interface to the store. Use with great care!", pub enum ImagTag {}
build_ui); impl ImagApplication for ImagTag {
fn run(rt: Runtime) -> Result<()> {
let ids = rt
.ids::<crate::ui::PathProvider>()
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("No ids supplied");
::std::process::exit(1);
})
.into_iter();
let ids = rt if let Some(name) = rt.cli().subcommand_name() {
.ids::<crate::ui::PathProvider>() match name {
.map_err_trace_exit_unwrap() "list" => for id in ids {
.unwrap_or_else(|| { list(id, &rt)
error!("No ids supplied"); },
::std::process::exit(1); "remove" => for id in ids {
}) let add = None;
.into_iter(); let rem = get_remove_tags(rt.cli());
debug!("id = {:?}, add = {:?}, rem = {:?}", id, add, rem);
if let Some(name) = rt.cli().subcommand_name() { alter(&rt, id, add, rem);
match name { },
"list" => for id in ids { "add" => for id in ids {
list(id, &rt) let add = get_add_tags(rt.cli());
}, let rem = None;
"remove" => for id in ids { debug!("id = {:?}, add = {:?}, rem = {:?}", id, add, rem);
let add = None; alter(&rt, id, add, rem);
let rem = get_remove_tags(rt.cli()); },
debug!("id = {:?}, add = {:?}, rem = {:?}", id, add, rem); other => {
alter(&rt, id, add, rem); debug!("Unknown command");
}, let _ = rt.handle_unknown_subcommand("imag-tag", other, rt.cli())
"add" => for id in ids { .map_err_trace_exit_unwrap()
let add = get_add_tags(rt.cli()); .code()
let rem = None; .map(::std::process::exit);
debug!("id = {:?}, add = {:?}, rem = {:?}", id, add, rem); },
alter(&rt, id, add, rem); }
},
other => {
debug!("Unknown command");
let _ = rt.handle_unknown_subcommand("imag-tag", other, rt.cli())
.map_err_trace_exit_unwrap()
.code()
.map(::std::process::exit);
},
} }
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Manage tags of entries"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
} }
} }
@ -263,6 +282,7 @@ mod tests {
modulename mock; modulename mock;
version env!("CARGO_PKG_VERSION"); version env!("CARGO_PKG_VERSION");
with help "imag-tag mocking app"; with help "imag-tag mocking app";
with ui builder function crate::ui::build_ui;
} }
use self::mock::generate_test_runtime; use self::mock::generate_test_runtime;

View file

@ -41,3 +41,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["color", "suggestions", "wrap_help"] features = ["color", "suggestions", "wrap_help"]
[lib]
name = "libimagviewcmd"
path = "src/lib.rs"
[[bin]]
name = "imag-view"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagviewcmd, ImagView);

View file

@ -0,0 +1,315 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
extern crate clap;
#[macro_use] extern crate log;
extern crate handlebars;
extern crate tempfile;
extern crate toml;
extern crate toml_query;
extern crate failure;
extern crate libimagentryview;
extern crate libimagerror;
extern crate libimagrt;
extern crate libimagstore;
extern crate libimagutil;
use std::str::FromStr;
use std::collections::BTreeMap;
use std::io::Write;
use std::process::Command;
use std::process::exit;
use handlebars::Handlebars;
use toml_query::read::TomlValueReadTypeExt;
use failure::Error;
use failure::err_msg;
use failure::Fallible as Result;
use clap::App;
use libimagrt::runtime::Runtime;
use libimagrt::application::ImagApplication;
use libimagerror::trace::MapErrTrace;
use libimagerror::iter::TraceIterator;
use libimagerror::io::ToExitCode;
use libimagerror::exit::ExitUnwrap;
use libimagentryview::builtin::stdout::StdoutViewer;
use libimagentryview::builtin::md::MarkdownViewer;
use libimagentryview::viewer::Viewer;
use libimagstore::iter::get::StoreIdGetIteratorExtension;
use libimagstore::store::FileLockEntry;
mod ui;
/// Marker enum for implementing ImagApplication on
///
/// This is used by binaries crates to execute business logic
/// or to build a CLI completion.
pub enum ImagView {}
impl ImagApplication for ImagView {
fn run(rt: Runtime) -> Result<()> {
let view_header = rt.cli().is_present("view-header");
let hide_content = rt.cli().is_present("not-view-content");
let entries = rt
.ids::<::ui::PathProvider>()
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("No ids supplied");
::std::process::exit(1);
})
.into_iter()
.map(Ok)
.into_get_iter(rt.store())
.trace_unwrap_exit()
.map(|e| {
e.ok_or_else(|| err_msg("Entry not found"))
.map_err(Error::from)
.map_err_trace_exit_unwrap()
});
if rt.cli().is_present("in") {
let files = entries
.map(|entry| {
let tmpfile = create_tempfile_for(&entry, view_header, hide_content);
rt.report_touched(entry.get_location()).unwrap_or_exit();
tmpfile
})
.collect::<Vec<_>>();
let mut command = {
let viewer = rt
.cli()
.value_of("in")
.ok_or_else(|| Error::from(err_msg("No viewer given")))
.map_err_trace_exit_unwrap();
let config = rt
.config()
.ok_or_else(|| Error::from(err_msg("No configuration, cannot continue")))
.map_err_trace_exit_unwrap();
let query = format!("view.viewers.{}", viewer);
let viewer_template = config
.read_string(&query)
.map_err(Error::from)
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("Cannot find '{}' in config", query);
exit(1)
});
let mut handlebars = Handlebars::new();
handlebars.register_escape_fn(::handlebars::no_escape);
let _ = handlebars
.register_template_string("template", viewer_template)
.map_err(Error::from)
.map_err_trace_exit_unwrap();
let mut data = BTreeMap::new();
let file_paths = files
.iter()
.map(|&(_, ref path)| path.clone())
.collect::<Vec<String>>()
.join(" ");
data.insert("entries", file_paths);
let call = handlebars
.render("template", &data)
.map_err(Error::from)
.map_err_trace_exit_unwrap();
let mut elems = call.split_whitespace();
let command_string = elems
.next()
.ok_or_else(|| Error::from(err_msg("No command")))
.map_err_trace_exit_unwrap();
let mut cmd = Command::new(command_string);
for arg in elems {
cmd.arg(arg);
}
cmd
};
debug!("Calling: {:?}", command);
if !command
.status()
.map_err(Error::from)
.map_err_trace_exit_unwrap()
.success()
{
exit(1)
}
drop(files);
} else {
let out = rt.stdout();
let mut outlock = out.lock();
let basesep = if rt.cli().occurrences_of("seperator") != 0 { // checker for default value
rt.cli().value_of("seperator").map(String::from)
} else {
None
};
let mut sep_width = 80; // base width, automatically overridden by wrap width
// Helper to build the seperator with a base string `sep` and a `width`
let build_seperator = |sep: String, width: usize| -> String {
sep.repeat(width / sep.len())
};
if rt.cli().is_present("compile-md") {
let viewer = MarkdownViewer::new(&rt);
let seperator = basesep.map(|s| build_seperator(s, sep_width));
entries
.enumerate()
.for_each(|(n, entry)| {
if n != 0 {
seperator
.as_ref()
.map(|s| writeln!(outlock, "{}", s).to_exit_code().unwrap_or_exit());
}
if let Err(e) = viewer.view_entry(&entry, &mut outlock) {
handle_error(e);
}
rt.report_touched(entry.get_location()).unwrap_or_exit();
});
} else {
let mut viewer = StdoutViewer::new(view_header, !hide_content);
if rt.cli().occurrences_of("autowrap") != 0 {
let width = rt.cli().value_of("autowrap").unwrap(); // ensured by clap
let width = usize::from_str(width).unwrap_or_else(|e| {
error!("Failed to parse argument to number: autowrap = {:?}",
rt.cli().value_of("autowrap").map(String::from));
error!("-> {:?}", e);
::std::process::exit(1)
});
// Copying this value over, so that the seperator has the right len as well
sep_width = width;
viewer.wrap_at(width);
}
let seperator = basesep.map(|s| build_seperator(s, sep_width));
entries
.enumerate()
.for_each(|(n, entry)| {
if n != 0 {
seperator
.as_ref()
.map(|s| writeln!(outlock, "{}", s).to_exit_code().unwrap_or_exit());
}
if let Err(e) = viewer.view_entry(&entry, &mut outlock) {
handle_error(e);
}
rt.report_touched(entry.get_location()).unwrap_or_exit();
});
}
}
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"View entries (readonly)"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
}
fn create_tempfile_for<'a>(entry: &FileLockEntry<'a>, view_header: bool, hide_content: bool)
-> (tempfile::NamedTempFile, String)
{
let mut tmpfile = tempfile::NamedTempFile::new()
.map_err(Error::from)
.map_err_trace_exit_unwrap();
if view_header {
let hdr = toml::ser::to_string_pretty(entry.get_header())
.map_err(Error::from)
.map_err_trace_exit_unwrap();
let _ = tmpfile.write(format!("---\n{}---\n", hdr).as_bytes())
.map_err(Error::from)
.map_err_trace_exit_unwrap();
}
if !hide_content {
let _ = tmpfile.write(entry.get_content().as_bytes())
.map_err(Error::from)
.map_err_trace_exit_unwrap();
}
let file_path = tmpfile
.path()
.to_str()
.map(String::from)
.ok_or_else(|| Error::from(err_msg("Cannot build path")))
.map_err_trace_exit_unwrap();
(tmpfile, file_path)
}
fn handle_error(e: ::libimagentryview::error::Error) {
use libimagentryview::error::Error;
match e {
Error::Io(e) => Err(e).to_exit_code().unwrap_or_exit(),
Error::Other(e) => Err(e).map_err_trace_exit_unwrap()
}
}

View file

@ -1,293 +0,0 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
extern crate clap;
#[macro_use] extern crate log;
extern crate handlebars;
extern crate tempfile;
extern crate toml;
extern crate toml_query;
extern crate failure;
extern crate libimagentryview;
extern crate libimagerror;
#[macro_use] extern crate libimagrt;
extern crate libimagstore;
extern crate libimagutil;
use std::str::FromStr;
use std::collections::BTreeMap;
use std::io::Write;
use std::process::Command;
use std::process::exit;
use handlebars::Handlebars;
use toml_query::read::TomlValueReadTypeExt;
use failure::Error;
use failure::err_msg;
use libimagrt::setup::generate_runtime_setup;
use libimagerror::trace::MapErrTrace;
use libimagerror::iter::TraceIterator;
use libimagerror::io::ToExitCode;
use libimagerror::exit::ExitUnwrap;
use libimagentryview::builtin::stdout::StdoutViewer;
use libimagentryview::builtin::md::MarkdownViewer;
use libimagentryview::viewer::Viewer;
use libimagstore::iter::get::StoreIdGetIteratorExtension;
use libimagstore::store::FileLockEntry;
mod ui;
use crate::ui::build_ui;
fn main() {
let version = make_imag_version!();
let rt = generate_runtime_setup( "imag-view",
&version,
"View entries (readonly)",
build_ui);
let view_header = rt.cli().is_present("view-header");
let hide_content = rt.cli().is_present("not-view-content");
let entries = rt
.ids::<::ui::PathProvider>()
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("No ids supplied");
::std::process::exit(1);
})
.into_iter()
.map(Ok)
.into_get_iter(rt.store())
.trace_unwrap_exit()
.map(|e| {
e.ok_or_else(|| err_msg("Entry not found"))
.map_err(Error::from)
.map_err_trace_exit_unwrap()
});
if rt.cli().is_present("in") {
let files = entries
.map(|entry| {
let tmpfile = create_tempfile_for(&entry, view_header, hide_content);
rt.report_touched(entry.get_location()).unwrap_or_exit();
tmpfile
})
.collect::<Vec<_>>();
let mut command = {
let viewer = rt
.cli()
.value_of("in")
.ok_or_else(|| err_msg("No viewer given"))
.map_err_trace_exit_unwrap();
let config = rt
.config()
.ok_or_else(|| err_msg("No configuration, cannot continue"))
.map_err_trace_exit_unwrap();
let query = format!("view.viewers.{}", viewer);
let viewer_template = config
.read_string(&query)
.map_err(Error::from)
.map_err_trace_exit_unwrap()
.unwrap_or_else(|| {
error!("Cannot find '{}' in config", query);
exit(1)
});
let mut handlebars = Handlebars::new();
handlebars.register_escape_fn(::handlebars::no_escape);
handlebars
.register_template_string("template", viewer_template)
.map_err(Error::from)
.map_err_trace_exit_unwrap();
let mut data = BTreeMap::new();
let file_paths = files
.iter()
.map(|&(_, ref path)| path.clone())
.collect::<Vec<String>>()
.join(" ");
data.insert("entries", file_paths);
let call = handlebars
.render("template", &data)
.map_err(Error::from)
.map_err_trace_exit_unwrap();
let mut elems = call.split_whitespace();
let command_string = elems
.next()
.ok_or_else(|| err_msg("No command"))
.map_err_trace_exit_unwrap();
let mut cmd = Command::new(command_string);
for arg in elems {
cmd.arg(arg);
}
cmd
};
debug!("Calling: {:?}", command);
if !command
.status()
.map_err(Error::from)
.map_err_trace_exit_unwrap()
.success()
{
exit(1)
}
drop(files);
} else {
let out = rt.stdout();
let mut outlock = out.lock();
let basesep = if rt.cli().occurrences_of("seperator") != 0 { // checker for default value
rt.cli().value_of("seperator").map(String::from)
} else {
None
};
let mut sep_width = 80; // base width, automatically overridden by wrap width
// Helper to build the seperator with a base string `sep` and a `width`
let build_seperator = |sep: String, width: usize| -> String {
sep.repeat(width / sep.len())
};
if rt.cli().is_present("compile-md") {
let viewer = MarkdownViewer::new(&rt);
let seperator = basesep.map(|s| build_seperator(s, sep_width));
entries
.enumerate()
.for_each(|(n, entry)| {
if n != 0 {
if let Some(s) = seperator
.as_ref() { writeln!(outlock, "{}", s).to_exit_code().unwrap_or_exit() }
}
if let Err(e) = viewer.view_entry(&entry, &mut outlock) {
handle_error(e);
}
rt.report_touched(entry.get_location()).unwrap_or_exit();
});
} else {
let mut viewer = StdoutViewer::new(view_header, !hide_content);
if rt.cli().occurrences_of("autowrap") != 0 {
let width = rt.cli().value_of("autowrap").unwrap(); // ensured by clap
let width = usize::from_str(width).unwrap_or_else(|e| {
error!("Failed to parse argument to number: autowrap = {:?}",
rt.cli().value_of("autowrap").map(String::from));
error!("-> {:?}", e);
::std::process::exit(1)
});
// Copying this value over, so that the seperator has the right len as well
sep_width = width;
viewer.wrap_at(width);
}
let seperator = basesep.map(|s| build_seperator(s, sep_width));
entries
.enumerate()
.for_each(|(n, entry)| {
if n != 0 {
if let Some(s) = seperator
.as_ref() { writeln!(outlock, "{}", s).to_exit_code().unwrap_or_exit() }
}
if let Err(e) = viewer.view_entry(&entry, &mut outlock) {
handle_error(e);
}
rt.report_touched(entry.get_location()).unwrap_or_exit();
});
}
}
}
fn create_tempfile_for<'a>(entry: &FileLockEntry<'a>, view_header: bool, hide_content: bool)
-> (tempfile::NamedTempFile, String)
{
let mut tmpfile = tempfile::NamedTempFile::new()
.map_err(Error::from)
.map_err_trace_exit_unwrap();
if view_header {
let hdr = toml::ser::to_string_pretty(entry.get_header())
.map_err(Error::from)
.map_err_trace_exit_unwrap();
let _ = tmpfile.write(format!("---\n{}---\n", hdr).as_bytes())
.map_err(Error::from)
.map_err_trace_exit_unwrap();
}
if !hide_content {
let _ = tmpfile.write(entry.get_content().as_bytes())
.map_err(Error::from)
.map_err_trace_exit_unwrap();
}
let file_path = tmpfile
.path()
.to_str()
.map(String::from)
.ok_or_else(|| err_msg("Cannot build path"))
.map_err_trace_exit_unwrap();
(tmpfile, file_path)
}
fn handle_error(e: ::libimagentryview::error::Error) {
use libimagentryview::error::Error;
match e {
Error::Io(e) => Err(e).to_exit_code().unwrap_or_exit(),
Error::Other(e) => Err(e).map_err_trace_exit_unwrap()
}
}

View file

@ -23,6 +23,33 @@ libimagutil = { version = "0.10.0", path = "../../../lib/etc/libimagutil" }
failure = "0.1.5" failure = "0.1.5"
log = "0.4.6" log = "0.4.6"
# Build time dependencies for cli completion
imag-annotate = { optional = true, path = "../imag-annotate" }
imag-create = { optional = true, path = "../imag-create" }
imag-diagnostics = { optional = true, path = "../imag-diagnostics" }
imag-edit = { optional = true, path = "../imag-edit" }
imag-gps = { optional = true, path = "../imag-gps" }
imag-grep = { optional = true, path = "../imag-grep" }
imag-ids = { optional = true, path = "../imag-ids" }
imag-init = { optional = true, path = "../imag-init" }
imag-link = { optional = true, path = "../imag-link" }
imag-mv = { optional = true, path = "../imag-mv" }
imag-ref = { optional = true, path = "../imag-ref" }
imag-store = { optional = true, path = "../imag-store" }
imag-tag = { optional = true, path = "../imag-tag" }
imag-view = { optional = true, path = "../imag-view" }
imag-bookmark = { optional = true, path = "../../domain/imag-bookmark" }
imag-calendar = { optional = true, path = "../../domain/imag-calendar" }
imag-contact = { optional = true, path = "../../domain/imag-contact" }
imag-diary = { optional = true, path = "../../domain/imag-diary" }
imag-habit = { optional = true, path = "../../domain/imag-habit" }
imag-log = { optional = true, path = "../../domain/imag-log" }
imag-mail = { optional = true, path = "../../domain/imag-mail" }
imag-notes = { optional = true, path = "../../domain/imag-notes" }
imag-timetrack = { optional = true, path = "../../domain/imag-timetrack" }
imag-todo = { optional = true, path = "../../domain/imag-todo" }
imag-wiki = { optional = true, path = "../../domain/imag-wiki" }
[badges] [badges]
travis-ci = { repository = "matthiasbeyer/imag" } travis-ci = { repository = "matthiasbeyer/imag" }
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" } is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
@ -48,3 +75,59 @@ version = "0.10.0"
path = "../../../lib/core/libimagrt" path = "../../../lib/core/libimagrt"
features = ["pub_logging_initialization"] features = ["pub_logging_initialization"]
[features]
default = [ "cc-all" ]
# Features for enabling cli completion files for individual subcommands
cc-all = [
"cc-imag-annotate",
"cc-imag-create",
"cc-imag-diagnostics",
"cc-imag-edit",
"cc-imag-gps",
"cc-imag-grep",
"cc-imag-ids",
"cc-imag-init",
"cc-imag-link",
"cc-imag-mv",
"cc-imag-ref",
"cc-imag-store",
"cc-imag-tag",
"cc-imag-view",
"cc-imag-bookmark",
"cc-imag-calendar",
"cc-imag-contact",
"cc-imag-diary",
"cc-imag-habit",
"cc-imag-log",
"cc-imag-mail",
"cc-imag-notes",
"cc-imag-timetrack",
"cc-imag-todo",
"cc-imag-wiki",
]
cc-imag-annotate = [ "imag-annotate" ]
cc-imag-create = [ "imag-create" ]
cc-imag-diagnostics = [ "imag-diagnostics" ]
cc-imag-edit = [ "imag-edit" ]
cc-imag-gps = [ "imag-gps" ]
cc-imag-grep = [ "imag-grep" ]
cc-imag-ids = [ "imag-ids" ]
cc-imag-init = [ "imag-init" ]
cc-imag-link = [ "imag-link" ]
cc-imag-mv = [ "imag-mv" ]
cc-imag-ref = [ "imag-ref" ]
cc-imag-store = [ "imag-store" ]
cc-imag-tag = [ "imag-tag" ]
cc-imag-view = [ "imag-view" ]
cc-imag-bookmark = [ "imag-bookmark" ]
cc-imag-calendar = [ "imag-calendar" ]
cc-imag-contact = [ "imag-contact" ]
cc-imag-diary = [ "imag-diary" ]
cc-imag-habit = [ "imag-habit" ]
cc-imag-log = [ "imag-log" ]
cc-imag-mail = [ "imag-mail" ]
cc-imag-notes = [ "imag-notes" ]
cc-imag-timetrack = [ "imag-timetrack" ]
cc-imag-todo = [ "imag-todo" ]
cc-imag-wiki = [ "imag-wiki" ]

164
bin/core/imag/build.rs Normal file
View file

@ -0,0 +1,164 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
extern crate clap;
extern crate libimagrt;
extern crate libimagentrytag;
extern crate libimagutil;
use clap::Shell;
use libimagrt::runtime::Runtime;
#[allow(unused_imports)]
use libimagrt::application::ImagApplication;
#[cfg(feature = "cc-imag-annotate")]
extern crate libimagannotatecmd;
#[cfg(feature = "cc-imag-create")]
extern crate libimagcreatecmd;
#[cfg(feature = "cc-imag-diagnostics")]
extern crate libimagdiagnosticscmd;
#[cfg(feature = "cc-imag-edit")]
extern crate libimageditcmd;
#[cfg(feature = "cc-imag-gps")]
extern crate libimaggpscmd;
#[cfg(feature = "cc-imag-grep")]
extern crate libimaggrepcmd;
#[cfg(feature = "cc-imag-ids")]
extern crate libimagidscmd;
#[cfg(feature = "cc-imag-init")]
extern crate libimaginitcmd;
#[cfg(feature = "cc-imag-link")]
extern crate libimaglinkcmd;
#[cfg(feature = "cc-imag-mv")]
extern crate libimagmvcmd;
#[cfg(feature = "cc-imag-ref")]
extern crate libimagrefcmd;
#[cfg(feature = "cc-imag-store")]
extern crate libimagstorecmd;
#[cfg(feature = "cc-imag-tag")]
extern crate libimagtagcmd;
#[cfg(feature = "cc-imag-view")]
extern crate libimagviewcmd;
#[cfg(feature = "cc-imag-bookmark")]
extern crate libimagbookmarkfrontend;
#[cfg(feature = "cc-imag-calendar")]
extern crate libimagcalendarfrontend;
#[cfg(feature = "cc-imag-contact")]
extern crate libimagcontactfrontend;
#[cfg(feature = "cc-imag-diary")]
extern crate libimagdiaryfrontend;
#[cfg(feature = "cc-imag-habit")]
extern crate libimaghabitfrontend;
#[cfg(feature = "cc-imag-log")]
extern crate libimaglogfrontend;
#[cfg(feature = "cc-imag-mail")]
extern crate libimagmailfrontend;
#[cfg(feature = "cc-imag-notes")]
extern crate libimagnotesfrontend;
#[cfg(feature = "cc-imag-timetrack")]
extern crate libimagtimetrackfrontend;
#[cfg(feature = "cc-imag-todo")]
extern crate libimagtodofrontend;
/// This macro reduces boilerplate code.
///
/// For example: `build_subcommand!("counter", libbinimagcounter, ImagCounter)`
/// will result in the following code:
/// ```ignore
/// ImagCounter::build_cli(Runtime::get_default_cli_builder(
/// "counter",
/// "abc",
/// "counter"))
/// ```
/// As for the `"abc"` part, it does not matter
/// which version the subcommand is getting here, as the
/// output of this script is a completion script, which
/// does not contain information about the version at all.
#[allow(unused_macros)]
macro_rules! build_subcommand {
($name:expr, $lib:ident, $implementor:ident) => (
$lib::$implementor::build_cli(Runtime::get_default_cli_builder($name, "abc", $name))
)
}
fn main() {
// Make the `imag`-App...
let app = Runtime::get_default_cli_builder(
"imag",
"abc",
"imag");
// and add all the subapps as subcommands.
// TODO: This feels tedious, can we automate this?
#[cfg(feature = "cc-imag-annotate")]
let app = app.subcommand(build_subcommand!("annotate", libimagannotatecmd, ImagAnnotate));
#[cfg(feature = "cc-imag-create")]
let app = app.subcommand(build_subcommand!("create", libimagcreatecmd, ImagCreate));
#[cfg(feature = "cc-imag-diagnostics")]
let app = app.subcommand(build_subcommand!("diagnostics", libimagdiagnosticscmd, ImagDiagnostics));
#[cfg(feature = "cc-imag-edit")]
let app = app.subcommand(build_subcommand!("edit", libimageditcmd, ImagEdit));
#[cfg(feature = "cc-imag-gps")]
let app = app.subcommand(build_subcommand!("gps", libimaggpscmd, ImagGps));
#[cfg(feature = "cc-imag-grep")]
let app = app.subcommand(build_subcommand!("grep", libimaggrepcmd, ImagGrep));
#[cfg(feature = "cc-imag-ids")]
let app = app.subcommand(build_subcommand!("ids", libimagidscmd, ImagIds));
#[cfg(feature = "cc-imag-init")]
let app = app.subcommand(build_subcommand!("init", libimaginitcmd, ImagInit));
#[cfg(feature = "cc-imag-link")]
let app = app.subcommand(build_subcommand!("link", libimaglinkcmd, ImagLink));
#[cfg(feature = "cc-imag-mv")]
let app = app.subcommand(build_subcommand!("mv", libimagmvcmd, ImagMv));
#[cfg(feature = "cc-imag-ref")]
let app = app.subcommand(build_subcommand!("ref", libimagrefcmd, ImagRef));
#[cfg(feature = "cc-imag-store")]
let app = app.subcommand(build_subcommand!("store", libimagstorecmd, ImagStore));
#[cfg(feature = "cc-imag-tag")]
let app = app.subcommand(build_subcommand!("tag", libimagtagcmd, ImagTag));
#[cfg(feature = "cc-imag-view")]
let app = app.subcommand(build_subcommand!("view", libimagviewcmd, ImagView));
#[cfg(feature = "cc-imag-bookmark")]
let app = app.subcommand(build_subcommand!("bookmark", libimagbookmarkfrontend, ImagBookmark));
#[cfg(feature = "cc-imag-calendar")]
let app = app.subcommand(build_subcommand!("calendar", libimagcalendarfrontend, ImagCalendar));
#[cfg(feature = "cc-imag-contact")]
let app = app.subcommand(build_subcommand!("contact", libimagcontactfrontend, ImagContact));
#[cfg(feature = "cc-imag-diary")]
let app = app.subcommand(build_subcommand!("diary", libimagdiaryfrontend, ImagDiary));
#[cfg(feature = "cc-imag-habit")]
let app = app.subcommand(build_subcommand!("habit", libimaghabitfrontend, ImagHabit));
#[cfg(feature = "cc-imag-log")]
let app = app.subcommand(build_subcommand!("log", libimaglogfrontend, ImagLog));
#[cfg(feature = "cc-imag-mail")]
let app = app.subcommand(build_subcommand!("mail", libimagmailfrontend, ImagMail));
#[cfg(feature = "cc-imag-notes")]
let app = app.subcommand(build_subcommand!("notes", libimagnotesfrontend, ImagNotes));
#[cfg(feature = "cc-imag-timetrack")]
let app = app.subcommand(build_subcommand!("timetrack", libimagtimetrackfrontend, ImagTimetrack));
#[cfg(feature = "cc-imag-todo")]
let app = app.subcommand(build_subcommand!("todo", libimagtodofrontend, ImagTodo));
let mut app = app;
// Actually generates the completion files
app.gen_completions("imag", Shell::Bash, "../../../target/");
app.gen_completions("imag", Shell::Fish, "../../../target/");
app.gen_completions("imag", Shell::Zsh, "../../../target/");
}

View file

@ -36,3 +36,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["color", "suggestions", "wrap_help"] features = ["color", "suggestions", "wrap_help"]
[lib]
name = "libimagbookmarkfrontend"
path = "src/lib.rs"
[[bin]]
name = "imag-bookmark"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagbookmarkfrontend, ImagBookmark);

View file

@ -41,7 +41,7 @@ extern crate toml_query;
#[macro_use] extern crate failure; #[macro_use] extern crate failure;
extern crate libimagbookmark; extern crate libimagbookmark;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagerror; extern crate libimagerror;
extern crate libimagutil; extern crate libimagutil;
extern crate libimagentrylink; extern crate libimagentrylink;
@ -52,9 +52,11 @@ use std::ops::DerefMut;
use toml_query::read::TomlValueReadTypeExt; use toml_query::read::TomlValueReadTypeExt;
use failure::Error; use failure::Error;
use failure::Fallible as Result;
use clap::App;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
use libimagbookmark::collection::BookmarkCollection; use libimagbookmark::collection::BookmarkCollection;
use libimagbookmark::collection::BookmarkCollectionStore; use libimagbookmark::collection::BookmarkCollectionStore;
use libimagbookmark::link::Link as BookmarkLink; use libimagbookmark::link::Link as BookmarkLink;
@ -64,33 +66,49 @@ use libimagerror::exit::ExitUnwrap;
use libimagutil::debug_result::DebugResult; use libimagutil::debug_result::DebugResult;
use libimagentrylink::linkable::Linkable; use libimagentrylink::linkable::Linkable;
mod ui; mod ui;
use crate::ui::build_ui; /// Marker enum for implementing ImagApplication on
///
fn main() { /// This is used by binaries crates to execute business logic
let version = make_imag_version!(); /// or to build a CLI completion.
let rt = generate_runtime_setup("imag-bookmark", pub enum ImagBookmark {}
&version, impl ImagApplication for ImagBookmark {
"Bookmark collection tool", fn run(rt: Runtime) -> Result<()> {
build_ui); if let Some(name) = rt.cli().subcommand_name() {
debug!("Call {}", name);
if let Some(name) = rt.cli().subcommand_name() { match name {
debug!("Call {}", name); "add" => add(&rt),
match name { "collection" => collection(&rt),
"add" => add(&rt), "list" => list(&rt),
"collection" => collection(&rt), "remove" => remove(&rt),
"list" => list(&rt), other => {
"remove" => remove(&rt), debug!("Unknown command");
other => { let _ = rt.handle_unknown_subcommand("imag-bookmark", other, rt.cli())
debug!("Unknown command"); .map_err_trace_exit_unwrap()
let _ = rt.handle_unknown_subcommand("imag-bookmark", other, rt.cli()) .code()
.map_err_trace_exit_unwrap() .map(::std::process::exit);
.code() },
.map(::std::process::exit); }
},
} }
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Bookmark collection tool"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
} }
} }

View file

@ -48,3 +48,10 @@ version = "0.9.2"
default-features = false default-features = false
features = ["typed"] features = ["typed"]
[lib]
name = "libimagcalendarfrontend"
path = "src/lib.rs"
[[bin]]
name = "imag-calendar"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagcalendarfrontend, ImagCalendar);

View file

@ -43,7 +43,7 @@ extern crate handlebars;
extern crate chrono; extern crate chrono;
extern crate kairos; extern crate kairos;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagcalendar; extern crate libimagcalendar;
extern crate libimagerror; extern crate libimagerror;
extern crate libimagstore; extern crate libimagstore;
@ -61,6 +61,7 @@ use toml_query::read::TomlValueReadExt;
use walkdir::DirEntry; use walkdir::DirEntry;
use walkdir::WalkDir; use walkdir::WalkDir;
use vobject::icalendar::Event; use vobject::icalendar::Event;
use clap::App;
use libimagcalendar::store::EventStore; use libimagcalendar::store::EventStore;
use libimagerror::io::ToExitCode; use libimagerror::io::ToExitCode;
@ -68,35 +69,53 @@ use libimagerror::exit::ExitUnwrap;
use libimagerror::iter::TraceIterator; use libimagerror::iter::TraceIterator;
use libimagerror::trace::MapErrTrace; use libimagerror::trace::MapErrTrace;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
mod filters; mod filters;
mod ui; mod ui;
mod util; mod util;
fn main() { /// Marker enum for implementing ImagApplication on
let version = make_imag_version!(); ///
let rt = generate_runtime_setup("imag-calendar", /// This is used by binary crates to execute business logic or to
&version, /// build a CLI completion.
"Calendar management tool", pub enum ImagCalendar {}
crate::ui::build_ui); impl ImagApplication for ImagCalendar {
fn run(rt: Runtime) -> Result<()> {
if let Some(name) = rt.cli().subcommand_name() {
debug!("Call {}", name);
match name {
"import" => import(&rt),
"list" => list(&rt),
"show" => show(&rt),
other => {
warn!("Right now, only the 'import' command is available");
debug!("Unknown command");
let _ = rt.handle_unknown_subcommand("imag-calendar", other, rt.cli())
.map_err_trace_exit_unwrap()
.code()
.map(::std::process::exit);
},
}
}
Ok(())
}
if let Some(name) = rt.cli().subcommand_name() { fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
debug!("Call {}", name); ui::build_ui(app)
match name { }
"import" => import(&rt),
"list" => list(&rt), fn name() -> &'static str {
"show" => show(&rt), env!("CARGO_PKG_NAME")
other => { }
warn!("Right now, only the 'import' command is available");
debug!("Unknown command"); fn description() -> &'static str {
let _ = rt.handle_unknown_subcommand("imag-calendar", other, rt.cli()) "Calendar management tool"
.map_err_trace_exit_unwrap() }
.code()
.map(::std::process::exit); fn version() -> &'static str {
}, env!("CARGO_PKG_VERSION")
}
} }
} }

View file

@ -47,3 +47,11 @@ features = ["color", "suggestions", "wrap_help"]
version = "0.9.2" version = "0.9.2"
default-features = false default-features = false
features = ["typed"] features = ["typed"]
[lib]
name = "libimagcontactfrontend"
path = "src/lib.rs"
[[bin]]
name = "imag-contact"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagcontactfrontend, ImagContact);

View file

@ -47,7 +47,7 @@ extern crate serde_json;
extern crate libimagcontact; extern crate libimagcontact;
extern crate libimagstore; extern crate libimagstore;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagerror; extern crate libimagerror;
extern crate libimagutil; extern crate libimagutil;
extern crate libimaginteraction; extern crate libimaginteraction;
@ -59,16 +59,17 @@ use std::path::PathBuf;
use std::io::Write; use std::io::Write;
use handlebars::Handlebars; use handlebars::Handlebars;
use clap::ArgMatches; use clap::{App, ArgMatches};
use toml_query::read::TomlValueReadExt; use toml_query::read::TomlValueReadExt;
use toml_query::read::TomlValueReadTypeExt; use toml_query::read::TomlValueReadTypeExt;
use toml_query::read::Partial; use toml_query::read::Partial;
use walkdir::WalkDir; use walkdir::WalkDir;
use failure::Error; use failure::Error;
use failure::err_msg; use failure::err_msg;
use failure::Fallible as Result;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
use libimagerror::trace::MapErrTrace; use libimagerror::trace::MapErrTrace;
use libimagerror::io::ToExitCode; use libimagerror::io::ToExitCode;
use libimagerror::exit::ExitUnwrap; use libimagerror::exit::ExitUnwrap;
@ -82,36 +83,53 @@ mod util;
mod create; mod create;
mod edit; mod edit;
use crate::ui::build_ui;
use crate::util::build_data_object_for_handlebars; use crate::util::build_data_object_for_handlebars;
use crate::create::create; use crate::create::create;
use crate::edit::edit; use crate::edit::edit;
fn main() { /// Marker enum for implementing ImagApplication on
let version = make_imag_version!(); ///
let rt = generate_runtime_setup("imag-contact", /// This is used by binaries crates to execute business logic
&version, /// or to build a CLI completion.
"Contact management tool", pub enum ImagContact {}
build_ui); impl ImagApplication for ImagContact {
fn run(rt: Runtime) -> Result<()> {
if let Some(name) = rt.cli().subcommand_name() {
if let Some(name) = rt.cli().subcommand_name() { debug!("Call {}", name);
debug!("Call {}", name); match name {
match name { "list" => list(&rt),
"list" => list(&rt), "import" => import(&rt),
"import" => import(&rt), "show" => show(&rt),
"show" => show(&rt), "edit" => edit(&rt),
"edit" => edit(&rt), "find" => find(&rt),
"find" => find(&rt), "create" => create(&rt),
"create" => create(&rt), other => {
other => { debug!("Unknown command");
debug!("Unknown command"); let _ = rt.handle_unknown_subcommand("imag-contact", other, rt.cli())
let _ = rt.handle_unknown_subcommand("imag-contact", other, rt.cli()) .map_err_trace_exit_unwrap()
.map_err_trace_exit_unwrap() .code()
.code() .map(::std::process::exit);
.map(::std::process::exit); },
}, }
} }
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Contact management tool"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
} }
} }

View file

@ -42,3 +42,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["color", "suggestions", "wrap_help"] features = ["color", "suggestions", "wrap_help"]
[lib]
name = "libimagdiaryfrontend"
path = "src/lib.rs"
[[bin]]
name = "imag-diary"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagdiaryfrontend, ImagDiary);

View file

@ -47,18 +47,20 @@ extern crate libimagentryedit;
extern crate libimagentryview; extern crate libimagentryview;
extern crate libimagerror; extern crate libimagerror;
extern crate libimaginteraction; extern crate libimaginteraction;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagstore; extern crate libimagstore;
extern crate libimagtimeui; extern crate libimagtimeui;
extern crate libimagutil; extern crate libimagutil;
use std::io::Write; use std::io::Write;
use libimagrt::setup::generate_runtime_setup;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::application::ImagApplication;
use libimagerror::trace::MapErrTrace; use libimagerror::trace::MapErrTrace;
use itertools::Itertools; use itertools::Itertools;
use clap::App;
use failure::Fallible as Result;
mod create; mod create;
mod delete; mod delete;
@ -72,29 +74,48 @@ use crate::delete::delete;
use crate::list::list; use crate::list::list;
use crate::view::view; use crate::view::view;
fn main() { /// Marker enum for implementing ImagApplication on
let version = make_imag_version!(); ///
let rt = generate_runtime_setup("imag-diary", /// This is used by binaries crates to execute business logic
&version, /// or to build a CLI completion.
"Personal Diary/Diaries", pub enum ImagDiary {}
ui::build_ui); impl ImagApplication for ImagDiary {
fn run(rt: Runtime) -> Result<()> {
if let Some(name) = rt.cli().subcommand_name() { if let Some(name) = rt.cli().subcommand_name() {
debug!("Call {}", name); debug!("Call {}", name);
match name { match name {
"diaries" => diaries(&rt), "diaries" => diaries(&rt),
"create" => create(&rt), "create" => create(&rt),
"delete" => delete(&rt), "delete" => delete(&rt),
"list" => list(&rt), "list" => list(&rt),
"view" => view(&rt), "view" => view(&rt),
other => { other => {
debug!("Unknown command"); debug!("Unknown command");
let _ = rt.handle_unknown_subcommand("imag-diary", other, rt.cli()) let _ = rt.handle_unknown_subcommand("imag-diary", other, rt.cli())
.map_err_trace_exit_unwrap() .map_err_trace_exit_unwrap()
.code() .code()
.map(::std::process::exit); .map(::std::process::exit);
}, },
}
} }
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Personal Diary/Diaries"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
} }
} }

View file

@ -42,3 +42,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["color", "suggestions", "wrap_help"] features = ["color", "suggestions", "wrap_help"]
[lib]
name = "libimaghabitfrontend"
path = "src/lib.rs"
[[bin]]
name = "imag-habit"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimaghabitfrontend, ImagHabit);

View file

@ -45,7 +45,7 @@ extern crate prettytable;
extern crate libimaghabit; extern crate libimaghabit;
extern crate libimagstore; extern crate libimagstore;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagerror; extern crate libimagerror;
extern crate libimagutil; extern crate libimagutil;
extern crate libimaginteraction; extern crate libimaginteraction;
@ -57,9 +57,11 @@ use prettytable::Table;
use prettytable::Cell; use prettytable::Cell;
use prettytable::Row; use prettytable::Row;
use failure::Error; use failure::Error;
use failure::Fallible as Result;
use clap::App;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
use libimagerror::trace::{MapErrTrace, trace_error}; use libimagerror::trace::{MapErrTrace, trace_error};
use libimagerror::iter::TraceIterator; use libimagerror::iter::TraceIterator;
use libimagerror::exit::ExitUnwrap; use libimagerror::exit::ExitUnwrap;
@ -75,37 +77,55 @@ use libimagutil::debug_result::DebugResult;
mod ui; mod ui;
fn main() { /// Marker enum for implementing ImagApplication on
let version = make_imag_version!(); ///
let rt = generate_runtime_setup("imag-habit", /// This is used by binaries crates to execute business logic
&version, /// or to build a CLI completion.
"Habit tracking tool", pub enum ImagHabit {}
ui::build_ui); impl ImagApplication for ImagHabit {
fn run(rt: Runtime) -> Result<()> {
rt
.cli()
.subcommand_name()
.map(|name| {
debug!("Call {}", name);
match name {
"create" => create(&rt),
"delete" => delete(&rt),
"list" => list(&rt),
"today" => today(&rt, false),
"status" => today(&rt, true),
"show" => show(&rt),
"done" => done(&rt),
other => {
debug!("Unknown command");
let _ = rt.handle_unknown_subcommand("imag-habit", other, rt.cli())
.map_err_trace_exit_unwrap()
.code()
.map(::std::process::exit);
},
}
})
.unwrap_or_else(|| today(&rt, true));
Ok(())
}
rt fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
.cli() ui::build_ui(app)
.subcommand_name() }
.map(|name| {
debug!("Call {}", name); fn name() -> &'static str {
match name { env!("CARGO_PKG_NAME")
"create" => create(&rt), }
"delete" => delete(&rt),
"list" => list(&rt), fn description() -> &'static str {
"today" => today(&rt, false), "Habit tracking tool"
"status" => today(&rt, true), }
"show" => show(&rt),
"done" => done(&rt), fn version() -> &'static str {
other => { env!("CARGO_PKG_VERSION")
debug!("Unknown command"); }
let _ = rt.handle_unknown_subcommand("imag-habit", other, rt.cli())
.map_err_trace_exit_unwrap()
.code()
.map(::std::process::exit);
},
}
})
.unwrap_or_else(|| today(&rt, true));
} }
fn create(rt: &Runtime) { fn create(rt: &Runtime) {

View file

@ -39,3 +39,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["color", "suggestions", "wrap_help"] features = ["color", "suggestions", "wrap_help"]
[lib]
name = "libimaglogfrontend"
path = "src/lib.rs"
[[bin]]
name = "imag-log"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimaglogfrontend, ImagLog);

View file

@ -44,7 +44,7 @@ extern crate failure;
extern crate textwrap; extern crate textwrap;
extern crate libimaglog; extern crate libimaglog;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagstore; extern crate libimagstore;
extern crate libimagerror; extern crate libimagerror;
extern crate libimagdiary; extern crate libimagdiary;
@ -56,9 +56,10 @@ use std::str::FromStr;
use failure::Error; use failure::Error;
use failure::err_msg; use failure::err_msg;
use failure::Fallible as Result;
use libimagrt::application::ImagApplication;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagerror::trace::MapErrTrace; use libimagerror::trace::MapErrTrace;
use libimagerror::io::ToExitCode; use libimagerror::io::ToExitCode;
use libimagerror::exit::ExitUnwrap; use libimagerror::exit::ExitUnwrap;
@ -70,50 +71,70 @@ use libimaglog::log::Log;
use libimagstore::iter::get::StoreIdGetIteratorExtension; use libimagstore::iter::get::StoreIdGetIteratorExtension;
use libimagstore::store::FileLockEntry; use libimagstore::store::FileLockEntry;
use clap::App;
mod ui; mod ui;
use crate::ui::build_ui;
use toml::Value; use toml::Value;
use itertools::Itertools; use itertools::Itertools;
fn main() { /// Marker enum for implementing ImagApplication on
let version = make_imag_version!(); ///
let rt = generate_runtime_setup("imag-log", /// This is used by binaries crates to execute business logic
&version, /// or to build a CLI completion.
"Overlay to imag-diary to 'log' single lines of text", pub enum ImagLog {}
build_ui); impl ImagApplication for ImagLog {
fn run(rt: Runtime) -> Result<()> {
if let Some(scmd) = rt.cli().subcommand_name() {
match scmd {
"show" => show(&rt),
other => {
debug!("Unknown command");
let _ = rt.handle_unknown_subcommand("imag-log", other, rt.cli())
.map_err_trace_exit_unwrap()
.code()
.map(::std::process::exit);
},
}
} else {
let text = get_log_text(&rt);
let diary_name = rt.cli()
.value_of("diaryname")
.map(String::from)
.unwrap_or_else(|| get_diary_name(&rt));
debug!("Writing to '{}': {}", diary_name, text);
rt
.store()
.new_entry_now(&diary_name)
.map(|mut fle| {
fle.make_log_entry().map_err_trace_exit_unwrap();
*fle.get_content_mut() = text;
fle
})
.map(|fle| rt.report_touched(fle.get_location()).unwrap_or_exit())
.map_err_trace_exit_unwrap();
if let Some(scmd) = rt.cli() .subcommand_name() {
match scmd {
"show" => show(&rt),
other => {
debug!("Unknown command");
let _ = rt.handle_unknown_subcommand("imag-log", other, rt.cli())
.map_err_trace_exit_unwrap()
.code()
.map(::std::process::exit);
},
} }
} else {
let text = get_log_text(&rt);
let diary_name = rt.cli()
.value_of("diaryname")
.map(String::from)
.unwrap_or_else(|| get_diary_name(&rt));
debug!("Writing to '{}': {}", diary_name, text); Ok(())
}
rt fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
.store() ui::build_ui(app)
.new_entry_now(&diary_name) }
.map(|mut fle| {
fle.make_log_entry().map_err_trace_exit_unwrap(); fn name() -> &'static str {
*fle.get_content_mut() = text; env!("CARGO_PKG_NAME")
fle }
})
.map(|fle| rt.report_touched(fle.get_location()).unwrap_or_exit()) fn description() -> &'static str {
.map_err_trace_exit_unwrap(); "Overlay to imag-diary to 'log' single lines of text"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
} }
} }
@ -203,7 +224,7 @@ fn show(rt: &Runtime) {
.unwrap_or_exit(); .unwrap_or_exit();
Ok(()) Ok(())
}) })
.collect::<Result<Vec<()>, ExitCode>>() .collect::<RResult<Vec<()>, ExitCode>>()
.unwrap_or_exit(); .unwrap_or_exit();
} }

View file

@ -41,3 +41,10 @@ version = "0.9.2"
default-features = false default-features = false
features = ["typed"] features = ["typed"]
[lib]
name = "libimagmailfrontend"
path = "src/lib.rs"
[[bin]]
name = "imag-mail"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagmailfrontend, ImagMail);

View file

@ -40,7 +40,7 @@ extern crate clap;
extern crate toml_query; extern crate toml_query;
#[macro_use] extern crate indoc; #[macro_use] extern crate indoc;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagmail; extern crate libimagmail;
extern crate libimagerror; extern crate libimagerror;
extern crate libimagstore; extern crate libimagstore;
@ -52,6 +52,7 @@ use std::path::PathBuf;
use failure::Fallible as Result; use failure::Fallible as Result;
use toml_query::read::TomlValueReadTypeExt; use toml_query::read::TomlValueReadTypeExt;
use clap::App;
use libimagerror::trace::{MapErrTrace, trace_error}; use libimagerror::trace::{MapErrTrace, trace_error};
use libimagerror::iter::TraceIterator; use libimagerror::iter::TraceIterator;
@ -63,7 +64,7 @@ use libimagmail::util;
use libimagentryref::reference::{Ref, RefFassade}; use libimagentryref::reference::{Ref, RefFassade};
use libimagentryref::util::get_ref_config; use libimagentryref::util::get_ref_config;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
use libimagutil::info_result::*; use libimagutil::info_result::*;
use libimagstore::store::FileLockEntry; use libimagstore::store::FileLockEntry;
use libimagstore::storeid::StoreIdIterator; use libimagstore::storeid::StoreIdIterator;
@ -71,32 +72,52 @@ use libimagstore::iter::get::StoreIdGetIteratorExtension;
mod ui; mod ui;
use crate::ui::build_ui; /// Marker enum for implementing ImagApplication on
///
/// This is used by binaries crates to execute business logic
/// or to build a CLI completion.
pub enum ImagMail {}
impl ImagApplication for ImagMail {
fn run(rt: Runtime) -> Result<()> {
fn main() { if let Some(name) = rt.cli().subcommand_name() {
let version = make_imag_version!();
let rt = generate_runtime_setup("imag-mail",
&version,
"Mail collection tool",
build_ui);
if let Some(name) = rt.cli().subcommand_name() { debug!("Call {}", name);
debug!("Call {}", name); match name {
match name { "import-mail" => import_mail(&rt),
"import-mail" => import_mail(&rt), "list" => list(&rt),
"list" => list(&rt), "mail-store" => mail_store(&rt),
"mail-store" => mail_store(&rt), other => {
other => { debug!("Unknown command");
debug!("Unknown command"); let _ = rt.handle_unknown_subcommand("imag-mail", other, rt.cli())
let _ = rt.handle_unknown_subcommand("imag-mail", other, rt.cli()) .map_err_trace_exit_unwrap()
.map_err_trace_exit_unwrap() .code()
.code() .map(::std::process::exit);
.map(::std::process::exit); }
}
} }
}
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Mail collection tool"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
} }
} }
fn import_mail(rt: &Runtime) { fn import_mail(rt: &Runtime) {
let collection_name = get_ref_collection_name(rt).map_err_trace_exit_unwrap(); let collection_name = get_ref_collection_name(rt).map_err_trace_exit_unwrap();
let refconfig = get_ref_config(rt, "imag-mail").map_err_trace_exit_unwrap(); let refconfig = get_ref_config(rt, "imag-mail").map_err_trace_exit_unwrap();

View file

@ -22,6 +22,7 @@ maintenance = { status = "actively-developed" }
[dependencies] [dependencies]
log = "0.4.6" log = "0.4.6"
itertools = "0.8.0" itertools = "0.8.0"
failure = "0.1.5"
libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" } libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" }
libimagerror = { version = "0.10.0", path = "../../../lib/core/libimagerror" } libimagerror = { version = "0.10.0", path = "../../../lib/core/libimagerror" }
@ -35,3 +36,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["color", "suggestions", "wrap_help"] features = ["color", "suggestions", "wrap_help"]
[lib]
name = "libimagnotesfrontend"
path = "src/lib.rs"
[[bin]]
name = "imag-notes"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagnotesfrontend, ImagNotes);

View file

@ -37,9 +37,10 @@
extern crate clap; extern crate clap;
#[macro_use] extern crate log; #[macro_use] extern crate log;
extern crate itertools; extern crate itertools;
extern crate failure;
extern crate libimagnotes; extern crate libimagnotes;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagentryedit; extern crate libimagentryedit;
extern crate libimagerror; extern crate libimagerror;
extern crate libimagutil; extern crate libimagutil;
@ -49,10 +50,12 @@ use std::io::Write;
use std::process::exit; use std::process::exit;
use itertools::Itertools; use itertools::Itertools;
use clap::App;
use failure::Fallible as Result;
use libimagentryedit::edit::Edit; use libimagentryedit::edit::Edit;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
use libimagstore::iter::get::StoreIdGetIteratorExtension; use libimagstore::iter::get::StoreIdGetIteratorExtension;
use libimagnotes::note::Note; use libimagnotes::note::Note;
use libimagnotes::notestore::*; use libimagnotes::notestore::*;
@ -65,30 +68,49 @@ use libimagutil::warn_result::WarnResult;
mod ui; mod ui;
use crate::ui::build_ui;
fn main() { /// Marker enum for implementing ImagApplication on
let version = make_imag_version!(); ///
let rt = generate_runtime_setup("imag-notes", /// This is used by binaries crates to execute business logic
&version, /// or to build a CLI completion.
"Note taking helper", pub enum ImagNotes {}
build_ui); impl ImagApplication for ImagNotes {
fn run(rt: Runtime) -> Result<()> {
if let Some(name) = rt.cli().subcommand_name() {
if let Some(name) = rt.cli().subcommand_name() { debug!("Call: {}", name);
debug!("Call: {}", name); match name {
match name { "create" => create(&rt),
"create" => create(&rt), "delete" => delete(&rt),
"delete" => delete(&rt), "edit" => edit(&rt),
"edit" => edit(&rt), "list" => list(&rt),
"list" => list(&rt), other => {
other => { debug!("Unknown command");
debug!("Unknown command"); let _ = rt.handle_unknown_subcommand("imag-notes", other, rt.cli())
let _ = rt.handle_unknown_subcommand("imag-notes", other, rt.cli()) .map_err_trace_exit_unwrap()
.map_err_trace_exit_unwrap() .code()
.code() .map(::std::process::exit);
.map(::std::process::exit); },
}, };
}; }
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Note taking helper"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
} }
} }

View file

@ -39,3 +39,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["color", "suggestions", "wrap_help"] features = ["color", "suggestions", "wrap_help"]
[lib]
name = "libimagtimetrackfrontend"
path = "src/lib.rs"
[[bin]]
name = "imag-timetrack"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagtimetrackfrontend, ImagTimetrack);

View file

@ -0,0 +1,137 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use]
extern crate log;
extern crate clap;
extern crate chrono;
extern crate filters;
extern crate itertools;
extern crate prettytable;
extern crate kairos;
extern crate failure;
extern crate libimagerror;
extern crate libimagstore;
extern crate libimagrt;
extern crate libimagtimetrack;
extern crate libimagutil;
mod cont;
mod day;
mod list;
mod month;
mod shell;
mod start;
mod stop;
mod track;
mod ui;
mod week;
mod year;
use crate::cont::cont;
use crate::day::day;
use crate::list::{list, list_impl};
use crate::month::month;
use crate::shell::shell;
use crate::start::start;
use crate::stop::stop;
use crate::track::track;
use crate::week::week;
use crate::year::year;
use clap::App;
use failure::Fallible as Result;
use libimagrt::runtime::Runtime;
use libimagrt::application::ImagApplication;
use libimagerror::trace::MapErrTrace;
/// Marker enum for implementing ImagApplication on
///
/// This is used by binaries crates to execute business logic
/// or to build a CLI completion.
pub enum ImagTimetrack {}
impl ImagApplication for ImagTimetrack {
fn run(rt: Runtime) -> Result<()> {
let command = rt.cli().subcommand_name();
let retval = if let Some(command) = command {
debug!("Call: {}", command);
match command {
"continue" => cont(&rt),
"day" => day(&rt),
"list" => list(&rt),
"month" => month(&rt),
"shell" => shell(&rt),
"start" => start(&rt),
"stop" => stop(&rt),
"track" => track(&rt),
"week" => week(&rt),
"year" => year(&rt),
other => {
debug!("Unknown command");
rt.handle_unknown_subcommand("imag-timetrack", other, rt.cli())
.map_err_trace_exit_unwrap()
.code()
.unwrap_or(0)
},
}
} else {
let start = ::chrono::offset::Local::today().naive_local().and_hms(0, 0, 0);
let end = ::chrono::offset::Local::today().naive_local().and_hms(23, 59, 59);
list_impl(&rt, Some(start), Some(end), false, false)
};
::std::process::exit(retval);
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Time tracking module"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
}

View file

@ -1,117 +0,0 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use]
extern crate log;
extern crate clap;
extern crate chrono;
extern crate filters;
extern crate itertools;
extern crate prettytable;
extern crate kairos;
extern crate failure;
extern crate libimagerror;
extern crate libimagstore;
#[macro_use] extern crate libimagrt;
extern crate libimagtimetrack;
extern crate libimagutil;
mod cont;
mod day;
mod list;
mod month;
mod shell;
mod start;
mod stop;
mod track;
mod ui;
mod week;
mod year;
use crate::cont::cont;
use crate::day::day;
use crate::list::{list, list_impl};
use crate::month::month;
use crate::shell::shell;
use crate::start::start;
use crate::stop::stop;
use crate::track::track;
use crate::ui::build_ui;
use crate::week::week;
use crate::year::year;
use libimagrt::setup::generate_runtime_setup;
use libimagerror::trace::MapErrTrace;
fn main() {
let version = make_imag_version!();
let rt = generate_runtime_setup("imag-timetrack",
&version,
"Time tracking module",
build_ui);
let command = rt.cli().subcommand_name();
let retval = if let Some(command) = command {
debug!("Call: {}", command);
match command {
"continue" => cont(&rt),
"day" => day(&rt),
"list" => list(&rt),
"month" => month(&rt),
"shell" => shell(&rt),
"start" => start(&rt),
"stop" => stop(&rt),
"track" => track(&rt),
"week" => week(&rt),
"year" => year(&rt),
other => {
debug!("Unknown command");
rt.handle_unknown_subcommand("imag-timetrack", other, rt.cli())
.map_err_trace_exit_unwrap()
.code()
.unwrap_or(0)
},
}
} else {
let start = ::chrono::offset::Local::today().naive_local().and_hms(0, 0, 0);
let end = ::chrono::offset::Local::today().naive_local().and_hms(23, 59, 59);
list_impl(&rt, Some(start), Some(end), false, false)
};
::std::process::exit(retval);
}

View file

@ -35,3 +35,10 @@ version = "2.33.0"
default-features = false default-features = false
features = ["color", "suggestions", "wrap_help"] features = ["color", "suggestions", "wrap_help"]
[lib]
name = "libimagtodofrontend"
path = "src/lib.rs"
[[bin]]
name = "imag-todo"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagtodofrontend, ImagTodo);

View file

@ -41,7 +41,7 @@ extern crate toml_query;
#[macro_use] extern crate is_match; #[macro_use] extern crate is_match;
extern crate failure; extern crate failure;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagerror; extern crate libimagerror;
extern crate libimagtodo; extern crate libimagtodo;
@ -49,9 +49,11 @@ use std::process::{Command, Stdio};
use std::io::stdin; use std::io::stdin;
use std::io::Write; use std::io::Write;
use failure::Error; use failure::Error;
use failure::Fallible as Result;
use clap::App;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
use libimagtodo::taskstore::TaskStore; use libimagtodo::taskstore::TaskStore;
use libimagerror::trace::{MapErrTrace, trace_error}; use libimagerror::trace::{MapErrTrace, trace_error};
use libimagerror::iter::TraceIterator; use libimagerror::iter::TraceIterator;
@ -60,29 +62,47 @@ use libimagerror::io::ToExitCode;
mod ui; mod ui;
use crate::ui::build_ui; /// Marker enum for implementing ImagApplication on
fn main() { ///
let version = make_imag_version!(); /// This is used by binaries crates to execute business logic
let rt = generate_runtime_setup("imag-todo", /// or to build a CLI completion.
&version, pub enum ImagTodo {}
"Interface with taskwarrior", impl ImagApplication for ImagTodo {
build_ui); fn run(rt: Runtime) -> Result<()> {
match rt.cli().subcommand_name() {
Some("tw-hook") => tw_hook(&rt),
Some("list") => list(&rt),
Some(other) => {
debug!("Unknown command");
let _ = rt.handle_unknown_subcommand("imag-todo", other, rt.cli())
.map_err_trace_exit_unwrap()
.code()
.map(::std::process::exit);
}
None => {
warn!("No command");
},
};
match rt.cli().subcommand_name() { Ok(())
Some("tw-hook") => tw_hook(&rt), }
Some("list") => list(&rt),
Some(other) => { fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
debug!("Unknown command"); ui::build_ui(app)
let _ = rt.handle_unknown_subcommand("imag-todo", other, rt.cli()) }
.map_err_trace_exit_unwrap()
.code() fn name() -> &'static str {
.map(::std::process::exit); env!("CARGO_PKG_NAME")
} }
None => {
warn!("No command"); fn description() -> &'static str {
}, "Interface with taskwarrior"
} // end match scmd }
} // end main
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
}
fn tw_hook(rt: &Runtime) { fn tw_hook(rt: &Runtime) {
let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap(); let subcmd = rt.cli().subcommand_matches("tw-hook").unwrap();

View file

@ -21,6 +21,7 @@ toml-query = "0.9.2"
is-match = "0.1.0" is-match = "0.1.0"
regex = "1.1.7" regex = "1.1.7"
filters = "0.3.0" filters = "0.3.0"
failure = "0.1.5"
libimagentryedit = { version = "0.10.0", path = "../../../lib/entry/libimagentryedit" } libimagentryedit = { version = "0.10.0", path = "../../../lib/entry/libimagentryedit" }
libimagentrylink = { version = "0.10.0", path = "../../../lib/entry/libimagentrylink" } libimagentrylink = { version = "0.10.0", path = "../../../lib/entry/libimagentrylink" }
@ -31,3 +32,10 @@ libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagst
libimagwiki = { version = "0.10.0", path = "../../../lib/domain/libimagwiki" } libimagwiki = { version = "0.10.0", path = "../../../lib/domain/libimagwiki" }
libimagutil = { version = "0.10.0", path = "../../../lib/etc/libimagutil" } libimagutil = { version = "0.10.0", path = "../../../lib/etc/libimagutil" }
[lib]
name = "libimagwikifrontend"
path = "src/lib.rs"
[[bin]]
name = "imag-wiki"
path = "src/bin.rs"

View file

@ -0,0 +1,39 @@
//
// imag - the personal information management suite for the commandline
// Copyright (C) 2015-2019 Matthias Beyer <mail@beyermatthias.de> and contributors
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; version
// 2.1 of the License.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#![forbid(unsafe_code)]
#![deny(
non_camel_case_types,
non_snake_case,
path_statements,
trivial_numeric_casts,
unstable_features,
unused_allocation,
unused_import_braces,
unused_imports,
unused_must_use,
unused_mut,
unused_qualifications,
while_true,
)]
#[macro_use] extern crate libimagrt;
simple_imag_application_binary!(libimagwikifrontend, ImagWiki);

View file

@ -23,8 +23,9 @@ extern crate clap;
extern crate regex; extern crate regex;
extern crate filters; extern crate filters;
#[macro_use] extern crate log; #[macro_use] extern crate log;
extern crate failure;
#[macro_use] extern crate libimagrt; extern crate libimagrt;
extern crate libimagerror; extern crate libimagerror;
extern crate libimagstore; extern crate libimagstore;
extern crate libimagwiki; extern crate libimagwiki;
@ -33,9 +34,11 @@ extern crate libimagentrylink;
extern crate libimagutil; extern crate libimagutil;
use std::io::Write; use std::io::Write;
use failure::Fallible as Result;
use clap::App;
use libimagrt::runtime::Runtime; use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup; use libimagrt::application::ImagApplication;
use libimagerror::iter::TraceIterator; use libimagerror::iter::TraceIterator;
use libimagerror::trace::MapErrTrace; use libimagerror::trace::MapErrTrace;
use libimagerror::exit::ExitUnwrap; use libimagerror::exit::ExitUnwrap;
@ -44,36 +47,55 @@ use libimagwiki::store::WikiStore;
use libimagentryedit::edit::{Edit, EditHeader}; use libimagentryedit::edit::{Edit, EditHeader};
mod ui; mod ui;
use crate::ui::build_ui;
fn main() { /// Marker enum for implementing ImagApplication on
let version = make_imag_version!(); ///
let rt = generate_runtime_setup("imag-wiki", /// This is used by binaries crates to execute business logic
&version, /// or to build a CLI completion.
"Personal wiki", pub enum ImagWiki {}
build_ui); impl ImagApplication for ImagWiki {
fn run(rt: Runtime) -> Result<()> {
let wiki_name = rt.cli().value_of("wikiname").unwrap_or("default");
trace!("wiki_name = {}", wiki_name);
trace!("calling = {:?}", rt.cli().subcommand_name());
let wiki_name = rt.cli().value_of("wikiname").unwrap_or("default"); match rt.cli().subcommand_name() {
trace!("wiki_name = {}", wiki_name); Some("list") => list(&rt, wiki_name),
trace!("calling = {:?}", rt.cli().subcommand_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) => {
debug!("Unknown command");
let _ = rt.handle_unknown_subcommand("imag-wiki", other, rt.cli())
.map_err_trace_exit_unwrap()
.code()
.map(std::process::exit);
}
None => warn!("No command"),
} // end match scmd
Ok(())
}
fn build_cli<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
ui::build_ui(app)
}
fn name() -> &'static str {
env!("CARGO_PKG_NAME")
}
fn description() -> &'static str {
"Personal wiki"
}
fn version() -> &'static str {
env!("CARGO_PKG_VERSION")
}
}
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) => {
debug!("Unknown command");
let _ = rt.handle_unknown_subcommand("imag-wiki", other, rt.cli())
.map_err_trace_exit_unwrap()
.code()
.map(std::process::exit);
}
None => warn!("No command"),
} // end match scmd
} // end main
fn list(rt: &Runtime, wiki_name: &str) { fn list(rt: &Runtime, wiki_name: &str) {
let scmd = rt.cli().subcommand_matches("list").unwrap(); // safed by clap let scmd = rt.cli().subcommand_matches("list").unwrap(); // safed by clap

Some files were not shown because too many files have changed in this diff Show more