From 981c6f852e1cc3e69db07931dc1156266dca8837 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 28 Jul 2019 10:51:35 +0200 Subject: [PATCH] Add imag-id-in-collection core command Signed-off-by: Matthias Beyer --- Cargo.toml | 1 + bin/core/imag-id-in-collection/Cargo.toml | 40 +++++++ bin/core/imag-id-in-collection/src/main.rs | 120 +++++++++++++++++++++ bin/core/imag-id-in-collection/src/ui.rs | 58 ++++++++++ scripts/release.sh | 1 + 5 files changed, 220 insertions(+) create mode 100644 bin/core/imag-id-in-collection/Cargo.toml create mode 100644 bin/core/imag-id-in-collection/src/main.rs create mode 100644 bin/core/imag-id-in-collection/src/ui.rs diff --git a/Cargo.toml b/Cargo.toml index 23c9969b..a80bbfb2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,6 +9,7 @@ members = [ "bin/core/imag-gps", "bin/core/imag-grep", "bin/core/imag-header", + "bin/core/imag-id-in-collection", "bin/core/imag-ids", "bin/core/imag-init", "bin/core/imag-link", diff --git a/bin/core/imag-id-in-collection/Cargo.toml b/bin/core/imag-id-in-collection/Cargo.toml new file mode 100644 index 00000000..fc9f6136 --- /dev/null +++ b/bin/core/imag-id-in-collection/Cargo.toml @@ -0,0 +1,40 @@ +[package] +name = "imag-id-in-collection" +version = "0.10.0" +authors = ["Matthias Beyer "] + +description = "Part of the imag core distribution: imag-ids command" + +keywords = ["imag", "PIM", "personal", "information", "management"] +readme = "../../../README.md" +license = "LGPL-2.1" + +documentation = "https://imag-pim.org/doc/" +repository = "https://github.com/matthiasbeyer/imag" +homepage = "http://imag-pim.org" + +[badges] +travis-ci = { repository = "matthiasbeyer/imag" } +is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" } +is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" } +maintenance = { status = "actively-developed" } + +[dependencies] +filters = "0.3.0" +log = "0.4.6" +toml = "0.5.1" +toml-query = "0.9.2" +failure = "0.1.5" + +libimagstore = { version = "0.10.0", path = "../../../lib/core/libimagstore" } +libimagrt = { version = "0.10.0", path = "../../../lib/core/libimagrt" } +libimagerror = { version = "0.10.0", path = "../../../lib/core/libimagerror" } + +[dependencies.clap] +version = "2.33.0" +default-features = false +features = ["color", "suggestions", "wrap_help"] + +[dev-dependencies] +env_logger = "0.6.1" + diff --git a/bin/core/imag-id-in-collection/src/main.rs b/bin/core/imag-id-in-collection/src/main.rs new file mode 100644 index 00000000..8357828a --- /dev/null +++ b/bin/core/imag-id-in-collection/src/main.rs @@ -0,0 +1,120 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015-2019 Matthias Beyer 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 filters; +#[macro_use] extern crate log; +extern crate toml; +extern crate toml_query; +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 filters::filter::Filter; + +use libimagstore::storeid::StoreId; +use libimagrt::setup::generate_runtime_setup; +use libimagerror::trace::MapErrTrace; +use libimagerror::exit::ExitUnwrap; +use libimagerror::io::ToExitCode; + +mod ui; + +pub struct IsInCollectionsFilter<'a, A>(Option, ::std::marker::PhantomData<&'a str>) + where A: AsRef<[&'a str]>; + +impl<'a, A> IsInCollectionsFilter<'a, A> + where A: AsRef<[&'a str]> +{ + pub fn new(collections: Option) -> Self { + IsInCollectionsFilter(collections, ::std::marker::PhantomData) + } +} + +impl<'a, A> Filter for IsInCollectionsFilter<'a, A> + where A: AsRef<[&'a str]> + 'a +{ + fn filter(&self, sid: &StoreId) -> bool { + match self.0 { + Some(ref colls) => sid.is_in_collection(colls), + None => true, + } + } +} + + +fn main() { + let version = make_imag_version!(); + let rt = generate_runtime_setup("imag-id-in-collection", + &version, + "filter ids by collection", + crate::ui::build_ui); + let values = rt + .cli() + .values_of("in-collection-filter") + .map(|v| v.collect::>()); + + let collection_filter = IsInCollectionsFilter::new(values); + + let mut stdout = rt.stdout(); + trace!("Got output: {:?}", stdout); + + + rt.ids::() + .map_err_trace_exit_unwrap() + .unwrap_or_else(|| { + error!("No ids supplied"); + ::std::process::exit(1); + }) + .iter() + .filter(|id| collection_filter.filter(id)) + .for_each(|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); + writeln!(stdout, "{}", id).to_exit_code().unwrap_or_exit(); + } + }) +} + diff --git a/bin/core/imag-id-in-collection/src/ui.rs b/bin/core/imag-id-in-collection/src/ui.rs new file mode 100644 index 00000000..6480550b --- /dev/null +++ b/bin/core/imag-id-in-collection/src/ui.rs @@ -0,0 +1,58 @@ +// +// imag - the personal information management suite for the commandline +// Copyright (C) 2015-2019 Matthias Beyer 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 +// + +use std::path::PathBuf; + +use clap::{Arg, ArgMatches, App}; +use failure::Fallible as Result; + +use libimagstore::storeid::StoreId; +use libimagrt::runtime::IdPathProvider; + +pub fn build_ui<'a>(app: App<'a, 'a>) -> App<'a, 'a> { + app + .arg(Arg::with_name("in-collection-filter") + .index(1) + .required(true) + .takes_value(true) + .multiple(false) + .value_name("COLLECTION") + .help("Filter for ids which are in this collection")) + + .arg(Arg::with_name("ids") + .index(2) + .required(false) + .takes_value(true) + .multiple(true) + .value_names(&["IDs"]) + .help("Ids to filter")) +} + +pub struct PathProvider; +impl IdPathProvider for PathProvider { + fn get_ids(matches: &ArgMatches) -> Result>> { + if let Some(ids) = matches.values_of("ids") { + ids.map(|i| StoreId::new(PathBuf::from(i))) + .collect::>>() + .map(Some) + } else { + Ok(None) + } + } +} diff --git a/scripts/release.sh b/scripts/release.sh index ff1598db..25f5f310 100644 --- a/scripts/release.sh +++ b/scripts/release.sh @@ -62,6 +62,7 @@ CRATES=( ./bin/core/imag-init ./bin/core/imag-edit ./bin/core/imag-ids + ./bin/core/imag-id-in-collection ./bin/core/imag-git ./bin/core/imag-category ./bin/core/imag-header