From 8c4407415dd470a88953a99276961ec578b5203f Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 13 Jan 2018 02:45:13 +0100 Subject: [PATCH 01/18] Fix wrong version-number --- doc/src/09020-changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/src/09020-changelog.md b/doc/src/09020-changelog.md index 4756bc83..78a93816 100644 --- a/doc/src/09020-changelog.md +++ b/doc/src/09020-changelog.md @@ -39,6 +39,7 @@ This section contains the changelog from the last release to the next release. * The `toml-query` dependency was updated to 0.5.0 * `imag-timetrack list` lists with a table now * `imag-timetrack stop` now stops all runnings tags if none are specified + * The `toml-query` dependency was updated to 0.6.0 * Bugfixes ## 0.5.0 From 2618e245c263e0cd445067629c9890a3aa1ce2f7 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Thu, 4 Jan 2018 12:53:04 +0100 Subject: [PATCH 02/18] Add commit template --- scripts/commit-template | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 scripts/commit-template diff --git a/scripts/commit-template b/scripts/commit-template new file mode 100644 index 00000000..62cc46c5 --- /dev/null +++ b/scripts/commit-template @@ -0,0 +1,10 @@ +One line description of your change + +Motivation: + +Modifications: + +Result: + +# To use this template as commit template, +# call `git config commit.template From 0913afd368660d5db1c263c2fc093006777043a8 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 6 Jan 2018 13:15:17 +0100 Subject: [PATCH 03/18] Add script to add a new crate --- scripts/new-crate.sh | 113 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 scripts/new-crate.sh diff --git a/scripts/new-crate.sh b/scripts/new-crate.sh new file mode 100644 index 00000000..b0178088 --- /dev/null +++ b/scripts/new-crate.sh @@ -0,0 +1,113 @@ +#!/usr/bin/env bash + +# Helper script to create a new crate in the imag workspace + +# 1. Creates a new crate +# 2. Adds the required crate meta information +# 3. Sets the version of the crate to the same version as libimagstore +# 4. Adds the crate to the top-level workspace + +if [[ "$1" == "-h" || "$1" == "--help" ]]; +then + echo "$0 [bin|lib] ./path/to/new/crate" + echo + echo "Execute _only_ from the top level of the repository" + exit 0 +fi + +crate_type="$1" +crate_location="$2" + +exit_if_empty() { + [[ -z "$1" ]] && { echo "$2 not passed"; exit 1; } +} + +exit_if_empty "$crate_type" "crate type" +exit_if_empty "$crate_location" "crate location" + +exists_cmd() { + command -v $1 || { echo "No $1 found"; exit 1; } +} + +exists_cmd "git" +exists_cmd "cargo" + +{ cat ./Cargo.toml 2>/dev/null | head -n 1 | grep -q "[workspace]"; } || { + echo "Not in root of repository as it seems. Exiting"; + exit 1; +} + +[[ "$crate_type" == "lib" || "$crate_type" == "bin" ]] || { + echo "Invalid crate type, use 'lib' or 'bin'"; + exit 1; +} + +if [[ -e "$crate_location" ]]; then + echo "Crate exists: $crate_location" + exit 1; +fi + +IFS=/ read -ra crate_name_parts <<< "$crate_location" +crate_name="${crate_name_parts[-1]}" + +if [[ "$crate_type" == "lib" ]]; +then + crate_description="Library for the imag core distribution" +else if [[ "$crate_type" == "bin" ]]; then + crate_description="Part of the imag core distribution: $crate_name command" +fi + +git_name="$(git config user.name)" +git_email="$(git config user.email)" + +store="lib/core/libimagstore/Cargo.toml" +crate_version=$(grep -m 1 version $store | cut -d '"' -f 2) + +echo "Crate type: $crate_type" +echo "Crate location: $crate_location" +echo "Crate name: $crate_name" +echo "Crate version: $crate_version" +echo "Crate description: $crate_description" +echo "Crate author: $git_name <$git_email>" + +echo "Not doing anything as this script is not ready yet." +echo "Exiting now" +exit 1 + +pushd "$(dirname $crate_location)" +crate new --${crate_type} $crate_name + +cat < ./$crate_name/Cargo.toml +[package] +name = "$crate_name" +version = "$crate_version" +authors = ["$git_name <$git_email>"] + +description = "$crate_description" + +keywords = ["imag", "PIM", "personal", "information", "management"] +readme = "../../../README.md" +license = "LGPL-2.1" + +documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.html" +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] + +EOS + +echo "Cargo.toml written. Please make sure that the README has the right path!" +popd + +git add ${crate_location}/* + +sed -i "$ s/]/ \"${crate_location}\",\n]/" Cargo.toml +echo "Top-level Cargo.toml modified. Please sort crate list manually!" + From 74f58d6c06e4fd7daff3aceb2254e737adc18736 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 15 Jan 2018 18:50:14 +0100 Subject: [PATCH 04/18] Remove unused imports --- bin/domain/imag-todo/src/main.rs | 3 --- 1 file changed, 3 deletions(-) diff --git a/bin/domain/imag-todo/src/main.rs b/bin/domain/imag-todo/src/main.rs index 8a2c88c1..36453c1d 100644 --- a/bin/domain/imag-todo/src/main.rs +++ b/bin/domain/imag-todo/src/main.rs @@ -30,8 +30,6 @@ extern crate libimagtodo; use std::process::{Command, Stdio}; use std::io::stdin; -use toml::Value; - use libimagrt::runtime::Runtime; use libimagrt::setup::generate_runtime_setup; use libimagtodo::taskstore::TaskStore; @@ -81,7 +79,6 @@ fn tw_hook(rt: &Runtime) { } fn list(rt: &Runtime) { - use toml_query::read::TomlValueReadExt; use toml_query::read::TomlValueReadTypeExt; let subcmd = rt.cli().subcommand_matches("list").unwrap(); From 5319d20636a58fec47f54f5d497dcb91a089fd22 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 15 Jan 2018 18:51:02 +0100 Subject: [PATCH 05/18] Remove verbosity flag for less cluttered CI logs --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2d3311fc..bb49062d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,8 +29,8 @@ addons: - pkg-config script: - - cargo build --all --all-features --verbose -j 1 - - cargo test --all --all-features --verbose -j 1 + - cargo build --all --all-features -j 1 + - cargo test --all --all-features -j 1 notifications: email: From 113c4b1f7f62c0de3a18fd087d88814facb6ce7e Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 15 Jan 2018 18:51:41 +0100 Subject: [PATCH 06/18] Ensure build script is exited early when failures happen --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index bb49062d..38efdf12 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,8 +29,9 @@ addons: - pkg-config script: - - cargo build --all --all-features -j 1 - - cargo test --all --all-features -j 1 + - | + cargo build --all --all-features -j 1 || exit 1 + cargo test --all --all-features -j 1 || exit 1 notifications: email: From e8ebe8f88bb9010f51540545927a09cb64c35363 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 19 Jan 2018 21:52:47 +0100 Subject: [PATCH 07/18] Update README --- README.md | 45 +++++++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index ae0413b0..77ab2769 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,10 @@ Our (long-term) goal is to Yes, imag is a rather ambitious project as it tries to reimplement functionality for several "personal information management aspects". It is a hobby project, -keep that in mind. We try to use standards like vcard and icalendar wherever -possible. +keep that in mind. We try to use standards like vcard, icalendar and others +wherever possible. -imag consists of _modules_ (e.g. `imag-notes`, `imag-tag`, `imag-view`), where -each module covers one PIM aspect. Have a look at -[the documentation](./doc/) for some more words on this. +Have a look at [the documentation](./doc/) for some more words on this. ## Building/Running @@ -48,6 +46,18 @@ Make sure to use a recent `cargo`, at least one with workspace support. Building all crates works with `cargo build --all`, building individual crates by `cd`ing to their directory and calling `cargo build`. +For building all commandline applications: + +```bash +find bin -maxdepth 3 -name Cargo.toml -exec cargo build --manifest-path {} \; +``` + +For building only the core functionality + +```bash +find bin/core -maxdepth 3 -name Cargo.toml -exec cargo build --manifest-path {} \; +``` + ### Running After you build the module you want to play with, you can simply call the binary @@ -57,48 +67,43 @@ If you installed the module, you can either call `imag-` (if the install-directory is in your `$PATH`), or install the `imag` binary to call `imag ` (also if everything is in your `$PATH`). + ## Staying up-to-date We have a [official website for imag](https://imag-pim.org), where I post [release notes](http://imag-pim.org/releases/) and monthly(ish) updates what's happening in the source tree ([RSS here](https://imag-pim.org/index.xml)). - We also have a [mailinglist](https://imag-pim.org/mailinglist/) where I post updates and where discussion and questions are encouraged. + ## Documentation -This is a hobby project, so sometimes things are not optimal and might go -unrecognized and slip through. Feel free to open issues about things you notice! - -Though, we have some documentation in [the ./doc subtree](./doc/) +We have some documentation in [the ./doc subtree](./doc/) which can be compiled to PDF or a website. -These docs are not published anywhere and are not even integrated into our CI, -so it might be broken (though it's unlikely). -Developer documentation is also available -[online on github.io](https://matthiasbeyer.github.io/imag/imag_documentation/index.html) -and [on docs.rs](https://docs.rs/releases/search?query=imag), though they might -be a bit outdated. +It might not be up to date, though. +Developer documentation for the last release is available +[on docs.rs](https://docs.rs/releases/search?query=imag). + ## Please contribute! We are looking for contributors! - Feel free to open issues for asking questions, suggesting features or other things! Also have a look at [the CONTRIBUTING.md file](./CONTRIBUTING.md)! -## Contact -Have a look at [our website](https://imag-pim.org) where you can find some -information on how to get in touch and so on. +## Contact Feel free to join our new IRC channel at freenode: #imag or our [mailinglist](https://imag-pim.org/mailinglist/). + ## License We chose to distribute this software under terms of GNU LGPLv2.1. + From 2c133de5bce0c617eb38551b4272fd4197bc6742 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Fri, 19 Jan 2018 22:02:15 +0100 Subject: [PATCH 08/18] Update contributing guide --- doc/src/09010-contributing.md | 81 ++++++++++++----------------------- 1 file changed, 27 insertions(+), 54 deletions(-) diff --git a/doc/src/09010-contributing.md b/doc/src/09010-contributing.md index baea4872..d643aa34 100644 --- a/doc/src/09010-contributing.md +++ b/doc/src/09010-contributing.md @@ -6,30 +6,28 @@ All contributors agree to the [developer certificate of origin](#developer-certificate-of-origin) by contributing to imag. -If you already have something in mind, go ahead with [the prerequisites -section](#prerequisites). If you don't know what you could do, start here. ## Without Github -Contributing without a github account is perfectly fine. +Contributing without a github account is perfectly fine and actually encouraged +as we try to move away from github step by step. Feel free to contact [us via our mailinglist](http://imag-pim.org/mailinglist/) and/or submit patches via mail (use `git format-patch` and `git send-email`, always add a cover letter to describe your submission). -Also ensure that each commit has +Also ensure that each commit submitted via email has [a "Signed-off-by: " line](https://stackoverflow.com/questions/1962094/what-is-the-sign-off-feature-in-git-for). By adding that line, you agree to our [developer certificate of origin](#developer-certificate-of-origin). -If you do not add the "Signed-off-by: " line, -I reserve the right to reject your patch. +If you do not add the "Signed-off-by: " line, I reserve the right to kindly +reject your patch. Once _I am_ okay with your patchset, I will -submit it as PR in the github repository, so more people can review it and CI -can test it (the mailinglist is not yet used as much as github). I might come -back to you if something broke in CI or someone has a suggestion how to improve -your PR. I will keep you as author of the commits. +submit it as PR in the github repository (as long as we're using github), +so CI can test it. +I might come back to you if something broke in CI or someone has a suggestion +how to improve your PR. I will keep you as author of the commits. -The following sections describe the way how to contribute with github. ## Finding an issue @@ -43,13 +41,17 @@ code... you'll always find things to improve! Also, if you've found bugs or outdated stuff in our documentation, feel free to file issues about them or even better: Write a pull request to fix them! + ## Prerequisites -* cargo and rust compiler in current version (stable) +The prerequisites are simple: `cargo` and `rustc` in current version (stable) +or newer (we do not use nighly features though). -Dependencies are listed in the +Build dependencies for building are listed in the [default.nix file](http://git.imag-pim.org/imag/tree/default.nix), -though you do not have to have `nix` installed to build imag. +though you do not have to have the `nix` package manager installed to build +imag. +Everything else will be done by `cargo`. Note that this software is targeted towards commandline linux users and we do not aim to be portable to Windows or Mac OSX (though I wouldn't mind merging @@ -61,65 +63,40 @@ If you want to build the documentation (you don't have to) you'll need: * pandoc-citeproc * texlive * lmodern (font package) -* make +* (gnu) make All dependencies are installable with the nix package manager by using a `nix-shell`, if you have the nix package manager installed on your system. + ## Commit guidelines Please don't refer to issues or PRs from inside a commit message, if possible. Make sure your PR does not contain "Fixup" commits when publishing it, but feel free to push "Fixup" commits in the review process. We will ask you to clean your history before merging! If you're submitting via patch-mail, I will do the -fixup squashing myself. +fixup squashing myself. If it fails I will come back to you. -Make sure to prefix your commits with `"doc: "` if you change the document. Do -not change document and code in one commit, always separate them. +Make sure to prefix your commits with `"doc: "` if you change the documentation. +Do not change document and code in one commit, always separate them. -If your changes are user-visible, make sure to add a note in the -`CHANGELOG.md` file. +If your changes are user-visible (new commandline flags, other semantics in the +commandline, etc), make sure to add a note in the `CHANGELOG.md` file (in the +same commit if it is a simple change). We do not follow some official Rust styleguide for our codebase, but we try to write minimal and readable code. 100 characters per line, as few lines as possible, avoid noise in the codebase, ... you get it. -Not all of your commits have to be buildable. But your PR has to be. +Not all of your commits have to be buildable. But your PR has to be before it +will be merged to master. -## PR guidelines -We'd like to have one PR per module change. This means you _should_ only change -one imag module in one commit or PR (library plus belonging binary is okay). -As this is not always possible, we do not enforce this, though we might ask you -to split your commits/PR into two smaller ones. +## Feature branches Use feature branches. If you could name them "/", for example "libimagstore/add-debugging-calls", that would be awesome. -You are welcome to publish your PR as soon as there is one commit in your -branch. This gives us the possibility to review whether your ideas go into a -nice direction or whether there are issues with your approach so we can report -them to you quickly. Rewriting a whole PR is not satisfactory and we'd -like to make your contribution process enjoyable for you. - -# Merging tools which use the imag core functionality into this repo - -If you're writing an application or module for imag, feel free to propose -integrating it into the imag core distribution, if it fulfills the following -requirements: - -1. It is written in Rust -1. It has a commandline interface which is the main interface to the module - OR it is a utility library for creating new kinds of functionality within the - imag core. - The commandline interface should be structured like the existing interfaces - (as in commands, options and arguments). -1. It is licensed under the terms of GNU LGPLv2.1 OR all of your contributors - approve a commit which changes the license of your codebase to GNU LGPLv2.1 - (The word "approve" in this sentence is to be defined). - -If your tool does not fulfill these requirements, I won't merge it into the -imag core distribution. ## Code of Conduct @@ -129,10 +106,6 @@ We use the same Basically: Be kind, encourage others to ask questions - you are encouraged to ask questions as well! -## Contact - -Feel free to reach out via mail/[mailinglist](http://imag-pim.org/mailinglist/) -or [IRC](irc://irc.freenode.net/#imag). ## Developer Certificate of Origin From 4bd156fdb36da577ff180915a5706c77bad6f4b6 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 21 Jan 2018 21:47:56 +0100 Subject: [PATCH 09/18] Remove unecessary String instantiation --- lib/entry/libimagentrycategory/src/register.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/entry/libimagentrycategory/src/register.rs b/lib/entry/libimagentrycategory/src/register.rs index 4d21c37a..219d267c 100644 --- a/lib/entry/libimagentrycategory/src/register.rs +++ b/lib/entry/libimagentrycategory/src/register.rs @@ -266,7 +266,7 @@ impl<'a> Iterator for CategoryNameIter<'a> { fn next(&mut self) -> Option { // TODO: Optimize me with lazy_static - let query = String::from(CATEGORY_REGISTER_NAME_FIELD_PATH); + let query = CATEGORY_REGISTER_NAME_FIELD_PATH; self.1 .next() @@ -275,7 +275,7 @@ impl<'a> Iterator for CategoryNameIter<'a> { .get(sid)? .ok_or_else(|| CE::from_kind(CEK::StoreReadError))? .get_header() - .read_string(&query) + .read_string(query) .chain_err(|| CEK::HeaderReadError)? .map(Category::from) .ok_or_else(|| CE::from_kind(CEK::StoreReadError)) From 82b67115e68e6d878d950f2095149be5e5d1f9b9 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 21 Jan 2018 22:29:47 +0100 Subject: [PATCH 10/18] Refactor: Minify Pull in new dependencies for minification --- bin/domain/imag-timetrack/Cargo.toml | 1 + bin/domain/imag-timetrack/src/main.rs | 1 + bin/domain/imag-timetrack/src/stop.rs | 51 ++++++++++----------------- 3 files changed, 20 insertions(+), 33 deletions(-) diff --git a/bin/domain/imag-timetrack/Cargo.toml b/bin/domain/imag-timetrack/Cargo.toml index e3708209..562310d1 100644 --- a/bin/domain/imag-timetrack/Cargo.toml +++ b/bin/domain/imag-timetrack/Cargo.toml @@ -31,3 +31,4 @@ libimagstore = { version = "0.6.0", path = "../../../lib/core/libimagstore" libimagrt = { version = "0.6.0", path = "../../../lib/core/libimagrt" } libimagerror = { version = "0.6.0", path = "../../../lib/core/libimagerror" } libimagtimetrack = { version = "0.6.0", path = "../../../lib/domain/libimagtimetrack" } +libimagutil = { version = "0.6.0", path = "../../../lib/etc/libimagutil" } diff --git a/bin/domain/imag-timetrack/src/main.rs b/bin/domain/imag-timetrack/src/main.rs index 6d736cb0..28d659e1 100644 --- a/bin/domain/imag-timetrack/src/main.rs +++ b/bin/domain/imag-timetrack/src/main.rs @@ -30,6 +30,7 @@ extern crate libimagerror; extern crate libimagstore; extern crate libimagrt; extern crate libimagtimetrack; +extern crate libimagutil; mod cont; mod day; diff --git a/bin/domain/imag-timetrack/src/stop.rs b/bin/domain/imag-timetrack/src/stop.rs index d0f17ea8..a3ac47cb 100644 --- a/bin/domain/imag-timetrack/src/stop.rs +++ b/bin/domain/imag-timetrack/src/stop.rs @@ -29,9 +29,10 @@ use libimagrt::runtime::Runtime; use libimagtimetrack::timetracking::TimeTracking; use libimagtimetrack::tag::TimeTrackingTag; use libimagtimetrack::timetrackingstore::*; -use libimagtimetrack::iter::get::GetTimeTrackIter; use libimagtimetrack::iter::filter::has_end_time; use libimagtimetrack::iter::filter::has_one_of_tags; +use libimagutil::warn_result::*; +use libimagutil::debug_result::*; pub fn stop(rt: &Runtime) -> i32 { let (_, cmd) = rt.cli().subcommand(); @@ -74,41 +75,25 @@ pub fn stop(rt: &Runtime) -> i32 { .collect() }); - let iter : GetTimeTrackIter = match rt.store().get_timetrackings() { - Ok(i) => i, - Err(e) => { - error!("Getting timetrackings failed"); - trace_error(&e); - return 1 - } - - }; let filter = has_end_time.not().and(has_one_of_tags(&tags)); + rt + .store() + .get_timetrackings() + .map_warn_err_str("Getting timetrackings failed") + .map_err_trace_exit_unwrap(1) + .trace_unwrap() - // Filter all timetrackings for the ones that are not yet ended. - iter.trace_unwrap() - .filter_map(|elem| { - if filter.filter(&elem) { - Some(elem) - } else { - None - } + // Filter all timetrackings for the ones that are not yet ended. + .filter(|e| filter.filter(e)) + + // for each of these timetrackings, end them + // for each result, print the backtrace (if any) + .fold(0, |acc, mut elem| { + elem.set_end_datetime(stop_time.clone()) + .map_dbg(|e| format!("Setting end time worked: {:?}", e)) + .map(|_| acc) + .map_err_trace_exit_unwrap(1) }) - - // for each of these timetrackings, end them - // for each result, print the backtrace (if any) - .fold(0, |acc, mut elem| match elem.set_end_datetime(stop_time.clone()) { - Err(e) => { // if there was an error - trace_error(&e); // trace - 1 // set exit code to 1 - }, - Ok(_) => { - debug!("Setting end time worked: {:?}", elem); - - // Keep the exit code - acc - } - }) } From e43812d262afdf564cb88a2266d18f2b170b7370 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 21 Jan 2018 22:34:40 +0100 Subject: [PATCH 11/18] Ignore Intellij-IDEA dotfiles --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 88f6183d..80cd5b4d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ Cargo.lock out target +.idea From 7731b88c9767df25bee982a5529a8a9dbf37255f Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 22 Jan 2018 12:48:28 +0100 Subject: [PATCH 12/18] Remove map_err_trace_exit() calls in favour of map_err_trace_exit_unwrap() --- bin/core/imag-annotate/src/main.rs | 46 ++++++++++----------------- bin/core/imag-diagnostics/src/main.rs | 3 +- bin/core/imag-gps/src/main.rs | 3 +- bin/core/imag-link/src/main.rs | 2 +- bin/core/imag-mv/src/main.rs | 2 +- bin/core/imag-store/src/delete.rs | 2 +- bin/core/imag-store/src/retrieve.rs | 2 +- bin/core/imag-view/src/main.rs | 2 +- bin/domain/imag-contact/src/main.rs | 43 ++++++++----------------- bin/domain/imag-notes/src/main.rs | 41 +++++++++++------------- doc/src/09020-changelog.md | 2 ++ lib/core/libimagerror/src/trace.rs | 12 ++----- 12 files changed, 60 insertions(+), 100 deletions(-) diff --git a/bin/core/imag-annotate/src/main.rs b/bin/core/imag-annotate/src/main.rs index 94cbd48a..92a2f92e 100644 --- a/bin/core/imag-annotate/src/main.rs +++ b/bin/core/imag-annotate/src/main.rs @@ -82,22 +82,18 @@ fn add(rt: &Runtime) { let entry_name = scmd .value_of("entry") .map(PathBuf::from) - .map(|pb| pb.into_storeid().map_err_trace_exit(1).unwrap()) + .map(|pb| pb.into_storeid().map_err_trace_exit_unwrap(1)) .unwrap(); // safed by clap let _ = rt.store() .get(entry_name) - .map_err_trace_exit(1) - .unwrap() + .map_err_trace_exit_unwrap(1) .ok_or(AE::from("Entry does not exist".to_owned())) - .map_err_trace_exit(1) - .unwrap() + .map_err_trace_exit_unwrap(1) .annotate(rt.store(), annotation_name) - .map_err_trace_exit(1) - .unwrap() + .map_err_trace_exit_unwrap(1) .edit_content(&rt) - .map_err_trace_exit(1) - .unwrap(); + .map_err_trace_exit_unwrap(1); info!("Ok"); } @@ -109,17 +105,14 @@ fn remove(rt: &Runtime) { let delete = scmd.is_present("delete-annotation"); let mut entry = rt.store() - .get(PathBuf::from(entry_name).into_storeid().map_err_trace_exit(1).unwrap()) - .map_err_trace_exit(1) - .unwrap() + .get(PathBuf::from(entry_name).into_storeid().map_err_trace_exit_unwrap(1)) + .map_err_trace_exit_unwrap(1) .ok_or(AE::from("Entry does not exist".to_owned())) - .map_err_trace_exit(1) - .unwrap(); + .map_err_trace_exit_unwrap(1); let annotation = entry .denotate(rt.store(), annotation_name) - .map_err_trace_exit(1) - .unwrap(); + .map_err_trace_exit_unwrap(1); if delete { debug!("Deleting annotation object"); @@ -130,8 +123,7 @@ fn remove(rt: &Runtime) { let _ = rt .store() .delete(loc) - .map_err_trace_exit(1) - .unwrap(); + .map_err_trace_exit_unwrap(1); } else { warn!("Not having annotation object, cannot delete!"); } @@ -149,17 +141,14 @@ fn list(rt: &Runtime) { Some(pb) => { let _ = rt .store() - .get(pb.into_storeid().map_err_trace_exit(1).unwrap()) - .map_err_trace_exit(1) - .unwrap() + .get(pb.into_storeid().map_err_trace_exit_unwrap(1)) + .map_err_trace_exit_unwrap(1) .ok_or(AE::from("Entry does not exist".to_owned())) - .map_err_trace_exit(1) - .unwrap() + .map_err_trace_exit_unwrap(1) .annotations(rt.store()) - .map_err_trace_exit(1) - .unwrap() + .map_err_trace_exit_unwrap(1) .enumerate() - .map(|(i, a)| list_annotation(i, a.map_err_trace_exit(1).unwrap(), with_text)) + .map(|(i, a)| list_annotation(i, a.map_err_trace_exit_unwrap(1), with_text)) .collect::>(); } @@ -168,10 +157,9 @@ fn list(rt: &Runtime) { let _ = rt .store() .all_annotations() - .map_err_trace_exit(1) - .unwrap() + .map_err_trace_exit_unwrap(1) .enumerate() - .map(|(i, a)| list_annotation(i, a.map_err_trace_exit(1).unwrap(), with_text)) + .map(|(i, a)| list_annotation(i, a.map_err_trace_exit_unwrap(1), with_text)) .collect::>(); } } diff --git a/bin/core/imag-diagnostics/src/main.rs b/bin/core/imag-diagnostics/src/main.rs index b9d2ee8f..7d3b06da 100644 --- a/bin/core/imag-diagnostics/src/main.rs +++ b/bin/core/imag-diagnostics/src/main.rs @@ -100,8 +100,7 @@ fn main() { let diags = rt.store() .entries() - .map_err_trace_exit(1) - .unwrap() + .map_err_trace_exit_unwrap(1) .into_get_iter(rt.store()) .map(|e| { e.map_err_trace_exit_unwrap(1) diff --git a/bin/core/imag-gps/src/main.rs b/bin/core/imag-gps/src/main.rs index 301f37a5..d3f3e532 100644 --- a/bin/core/imag-gps/src/main.rs +++ b/bin/core/imag-gps/src/main.rs @@ -103,8 +103,7 @@ fn add(rt: &Runtime) { .get(sid) .map_err_trace_exit_unwrap(1) .map(|mut entry| { - let _ = entry.set_coordinates(c) - .map_err_trace_exit(1); + let _ = entry.set_coordinates(c).map_err_trace_exit_unwrap(1); }) .unwrap_or_else(|| { error!("No such entry: {}", entry_name); diff --git a/bin/core/imag-link/src/main.rs b/bin/core/imag-link/src/main.rs index 76796a97..f775d030 100644 --- a/bin/core/imag-link/src/main.rs +++ b/bin/core/imag-link/src/main.rs @@ -106,7 +106,7 @@ fn main() { } }) .ok_or(LE::from("No commandline call".to_owned())) - .map_err_trace_exit(1); + .map_err_trace_exit_unwrap(1); } fn get_entry_by_name<'a>(rt: &'a Runtime, name: &str) -> Result>, StoreError> { diff --git a/bin/core/imag-mv/src/main.rs b/bin/core/imag-mv/src/main.rs index 7896e8f1..030763bf 100644 --- a/bin/core/imag-mv/src/main.rs +++ b/bin/core/imag-mv/src/main.rs @@ -75,7 +75,7 @@ fn main() { let _ = rt .store() .move_by_id(sourcename, destname) - .map_err_trace_exit(1); + .map_err_trace_exit_unwrap(1); info!("Ok."); } diff --git a/bin/core/imag-store/src/delete.rs b/bin/core/imag-store/src/delete.rs index f50cc9c0..766c1304 100644 --- a/bin/core/imag-store/src/delete.rs +++ b/bin/core/imag-store/src/delete.rs @@ -36,7 +36,7 @@ pub fn delete(rt: &Runtime) { let _ = rt.store() .delete(path) .map_warn_err(|e| format!("Error: {:?}", e)) - .map_err_trace_exit(1); + .map_err_trace_exit_unwrap(1); } #[cfg(test)] diff --git a/bin/core/imag-store/src/retrieve.rs b/bin/core/imag-store/src/retrieve.rs index 905fe98d..4c3b25c1 100644 --- a/bin/core/imag-store/src/retrieve.rs +++ b/bin/core/imag-store/src/retrieve.rs @@ -35,7 +35,7 @@ pub fn retrieve(rt: &Runtime) { let id = scmd.value_of("id").unwrap(); let path = PathBuf::from(id); let store = Some(rt.store().path().clone()); - let path = StoreId::new(store, path).map_err_trace_exit(1)?; + let path = StoreId::new(store, path).map_err_trace_exit_unwrap(1); debug!("path = {:?}", path); rt.store() diff --git a/bin/core/imag-view/src/main.rs b/bin/core/imag-view/src/main.rs index ef3b3304..eba2245a 100644 --- a/bin/core/imag-view/src/main.rs +++ b/bin/core/imag-view/src/main.rs @@ -163,7 +163,7 @@ fn main() { } else { let _ = StdoutViewer::new(view_header, view_content) .view_entry(&entry) - .map_err_trace_exit(1); + .map_err_trace_exit_unwrap(1); } } diff --git a/bin/domain/imag-contact/src/main.rs b/bin/domain/imag-contact/src/main.rs index fe8cddc5..2747b94c 100644 --- a/bin/domain/imag-contact/src/main.rs +++ b/bin/domain/imag-contact/src/main.rs @@ -107,28 +107,24 @@ fn list(rt: &Runtime) { let _ = rt .store() .all_contacts() - .map_err_trace_exit(1) - .unwrap() // safed by above call + .map_err_trace_exit_unwrap(1) .into_get_iter(rt.store()) .map(|fle| { let fle = fle - .map_err_trace_exit(1) - .unwrap() + .map_err_trace_exit_unwrap(1) .ok_or_else(|| CE::from("StoreId not found".to_owned())) - .map_err_trace_exit(1) - .unwrap(); + .map_err_trace_exit_unwrap(1); fle .get_contact_data() .map(|cd| (fle, cd)) .map(|(fle, cd)| (fle, cd.into_inner())) .map(|(fle, cd)| (fle, Vcard::from_component(cd))) - .map_err_trace_exit(1) - .unwrap() + .map_err_trace_exit_unwrap(1) }) .enumerate() .map(|(i, (fle, vcard))| { - let hash = fle.get_path_hash().map_err_trace_exit(1).unwrap(); + let hash = fle.get_path_hash().map_err_trace_exit_unwrap(1); let vcard = vcard.unwrap_or_else(|e| { error!("Element is not a VCARD object: {:?}", e); exit(1) @@ -137,8 +133,7 @@ fn list(rt: &Runtime) { let data = build_data_object_for_handlebars(i, hash, &vcard); let s = list_format.render("format", &data) - .map_err_trace_exit(1) - .unwrap(); + .map_err_trace_exit_unwrap(1); println!("{}", s); }) .collect::>(); @@ -157,18 +152,16 @@ fn import(rt: &Runtime) { let _ = rt .store() .create_from_path(&path) - .map_err_trace_exit(1) - .unwrap(); + .map_err_trace_exit_unwrap(1); } else if path.is_dir() { for entry in WalkDir::new(path).min_depth(1).into_iter() { - let entry = entry.map_err_trace_exit(1).unwrap(); + let entry = entry.map_err_trace_exit_unwrap(1); if entry.file_type().is_file() { let pb = PathBuf::from(entry.path()); let _ = rt .store() .create_from_path(&pb) - .map_err_trace_exit(1) - .unwrap(); + .map_err_trace_exit_unwrap(1); info!("Imported: {}", entry.path().to_str().unwrap_or("")); } else { warn!("Ignoring non-file: {}", entry.path().to_str().unwrap_or("")); @@ -186,14 +179,11 @@ fn show(rt: &Runtime) { let contact_data = rt.store() .get_by_hash(hash.clone()) - .map_err_trace_exit(1) - .unwrap() + .map_err_trace_exit_unwrap(1) .ok_or(CE::from(format!("No entry for hash {}", hash))) - .map_err_trace_exit(1) - .unwrap() + .map_err_trace_exit_unwrap(1) .get_contact_data() - .map_err_trace_exit(1) - .unwrap() + .map_err_trace_exit_unwrap(1) .into_inner(); let vcard = Vcard::from_component(contact_data) .unwrap_or_else(|e| { @@ -204,9 +194,7 @@ fn show(rt: &Runtime) { let show_format = get_contact_print_format("contact.show_format", rt, &scmd); let data = build_data_object_for_handlebars(0, hash, &vcard); - let s = show_format.render("format", &data) - .map_err_trace_exit(1) - .unwrap(); + let s = show_format.render("format", &data).map_err_trace_exit_unwrap(1); println!("{}", s); info!("Ok"); } @@ -226,10 +214,7 @@ fn get_contact_print_format(config_value_path: &'static str, rt: &Runtime, scmd: }); let mut hb = Handlebars::new(); - let _ = hb - .register_template_string("format", fmt) - .map_err_trace_exit(1) - .unwrap(); + let _ = hb.register_template_string("format", fmt).map_err_trace_exit_unwrap(1); hb.register_escape_fn(::handlebars::no_escape); ::libimaginteraction::format::register_all_color_helpers(&mut hb); diff --git a/bin/domain/imag-notes/src/main.rs b/bin/domain/imag-notes/src/main.rs index e3234393..d04208e6 100644 --- a/bin/domain/imag-notes/src/main.rs +++ b/bin/domain/imag-notes/src/main.rs @@ -79,7 +79,7 @@ fn create(rt: &Runtime) { let _ = note .edit_content(rt) .map_warn_err_str("Editing failed") - .map_err_trace_exit(1); + .map_err_trace_exit_unwrap(1); } } @@ -87,7 +87,7 @@ fn delete(rt: &Runtime) { let _ = rt.store() .delete_note(name_from_cli(rt, "delete")) .map_info_str("Ok") - .map_err_trace_exit(1); + .map_err_trace_exit_unwrap(1); } fn edit(rt: &Runtime) { @@ -100,7 +100,7 @@ fn edit(rt: &Runtime) { let _ = note .edit_content(rt) .map_warn_err_str("Editing failed") - .map_err_trace_exit(1); + .map_err_trace_exit_unwrap(1); }) .unwrap_or_else(|| { error!("Cannot find note with name '{}'", name); @@ -110,27 +110,22 @@ fn edit(rt: &Runtime) { fn list(rt: &Runtime) { use std::cmp::Ordering; - rt.store() + let _ = rt + .store() .all_notes() - .map_err_trace_exit(1) - .map(|iter| { - let notes = iter - .filter_map(|noteid| rt.store().get(noteid).map_err_trace_exit_unwrap(1)) - .sorted_by(|note_a, note_b| { - if let (Ok(a), Ok(b)) = (note_a.get_name(), note_b.get_name()) { - return a.cmp(&b) - } else { - return Ordering::Greater; - } - }); - - for note in notes.iter() { - note.get_name() - .map(|name| println!("{}", name)) - .map_err_trace() - .ok(); - } + .map_err_trace_exit_unwrap(1) + .filter_map(|noteid| rt.store().get(noteid).map_err_trace_exit_unwrap(1)) + .sorted_by(|note_a, note_b| if let (Ok(a), Ok(b)) = (note_a.get_name(), note_b.get_name()) { + return a.cmp(&b) + } else { + return Ordering::Greater; }) - .ok(); + .iter() + .for_each(|note| { + note.get_name() + .map(|name| println!("{}", name)) + .map_err_trace() + .ok(); + }); } diff --git a/doc/src/09020-changelog.md b/doc/src/09020-changelog.md index 78a93816..29a4a066 100644 --- a/doc/src/09020-changelog.md +++ b/doc/src/09020-changelog.md @@ -40,6 +40,8 @@ This section contains the changelog from the last release to the next release. * `imag-timetrack list` lists with a table now * `imag-timetrack stop` now stops all runnings tags if none are specified * The `toml-query` dependency was updated to 0.6.0 + * `ResultExt::map_err_trace_exit()` was removed in favour of + `ResultExt::map_err_trace_exit_unwrap()`. * Bugfixes ## 0.5.0 diff --git a/lib/core/libimagerror/src/trace.rs b/lib/core/libimagerror/src/trace.rs index 2ec33a6a..7df6b288 100644 --- a/lib/core/libimagerror/src/trace.rs +++ b/lib/core/libimagerror/src/trace.rs @@ -118,7 +118,6 @@ pub trait MapErrTrace { fn map_err_trace(self) -> Self; fn map_err_dbg_trace(self) -> Self; - fn map_err_trace_exit(self, code: i32) -> Self; fn map_err_trace_exit_unwrap(self, code: i32) -> Self::Output; fn map_err_trace_maxdepth(self, max: u64) -> Self; } @@ -140,16 +139,9 @@ impl MapErrTrace for Result { self.map_err(|e| { trace_error_dbg(&e); e }) } - /// Simply call `trace_error_exit(code)` on the Err (if there is one). - /// - /// This does not return if there is an Err(e). - fn map_err_trace_exit(self, code: i32) -> Self { - self.map_err(|e| { trace_error_exit(&e, code) }) - } - - /// Helper for calling map_err_trace_exit(n).unwrap() in one call + /// Trace the error and exit or unwrap the Ok(_). fn map_err_trace_exit_unwrap(self, code: i32) -> Self::Output { - self.map_err_trace_exit(code).unwrap() + self.map_err(|e| { trace_error_exit(&e, code) }).unwrap() } /// Simply call `trace_error_maxdepth(max)` on the Err (if there is one) and return the error. From fdf038ac18cfc18e0a4289678af5f0c88ce61f1d Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 22 Jan 2018 19:55:05 +0100 Subject: [PATCH 13/18] We don't have to specify the src here --- doc/default.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/default.nix b/doc/default.nix index 0146b71c..309682fc 100644 --- a/doc/default.nix +++ b/doc/default.nix @@ -58,7 +58,7 @@ in pkgs.stdenv.mkDerivation rec { name = "imag-doc"; - src = ./.; + src = /var/empty; version = "0.0.0"; buildInputs = [ env ]; From 164b6b7f10e9f8e98dca3b33dd543fb84f57897b Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 27 Jan 2018 12:10:01 +0100 Subject: [PATCH 14/18] Move documentation to appropriate place --- lib/core/libimagstore/src/store.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/lib/core/libimagstore/src/store.rs b/lib/core/libimagstore/src/store.rs index 9a41e75c..365576e0 100644 --- a/lib/core/libimagstore/src/store.rs +++ b/lib/core/libimagstore/src/store.rs @@ -455,9 +455,17 @@ impl Store { Walk::new(self.path().clone(), mod_name) } - /// Return the `FileLockEntry` and write to disk + /// Write (update) the `FileLockEntry` to disk /// - /// See `Store::_update()`. + /// # Return value + /// + /// On success: Entry + /// + /// On error: + /// - UpdateCallError(LockPoisoned()) if the internal write lock cannot be aquierd. + /// - IdNotFound() if the entry was not found in the stor + /// - Errors Entry::verify() might return + /// - Errors StoreEntry::write_entry() might return /// pub fn update<'a>(&'a self, entry: &mut FileLockEntry<'a>) -> Result<()> { debug!("Updating FileLockEntry at '{}'", entry.get_location()); @@ -471,16 +479,6 @@ impl Store { /// This method assumes that entry is dropped _right after_ the call, hence /// it is not public. /// - /// # Return value - /// - /// On success: Entry - /// - /// On error: - /// - UpdateCallError(LockPoisoned()) if the internal write lock cannot be aquierd. - /// - IdNotFound() if the entry was not found in the stor - /// - Errors Entry::verify() might return - /// - Errors StoreEntry::write_entry() might return - /// fn _update<'a>(&'a self, entry: &mut FileLockEntry<'a>, modify_presence: bool) -> Result<()> { let mut hsmap = self.entries.write().map_err(|_| SE::from_kind(SEK::LockPoisoned))?; From 30ef3bf0d3e100f7092d9d893ffe0b6f0d32d25a Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sat, 27 Jan 2018 14:08:35 +0100 Subject: [PATCH 15/18] Comment type fixed --- bin/domain/imag-contact/src/util.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/domain/imag-contact/src/util.rs b/bin/domain/imag-contact/src/util.rs index e85a6a8a..e194a86d 100644 --- a/bin/domain/imag-contact/src/util.rs +++ b/bin/domain/imag-contact/src/util.rs @@ -25,7 +25,7 @@ pub fn build_data_object_for_handlebars<'a>(i: usize, hash: String, vcard: &Vcar { data.insert("i" , format!("{}", i)); - /// The hash (as in libimagentryref) of the contact + // The hash (as in libimagentryref) of the contact data.insert("id" , hash); data.insert("ADR" , vcard.adr() From 7ecaad830c72c364ddf815d106cc5e2af52db0e0 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Sun, 28 Jan 2018 21:05:05 +0100 Subject: [PATCH 16/18] Refactor to use Iterator::fold() --- lib/entry/libimagentrylink/src/internal.rs | 45 +++++++++++----------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/lib/entry/libimagentrylink/src/internal.rs b/lib/entry/libimagentrylink/src/internal.rs index dec86c1c..d7cddb69 100644 --- a/lib/entry/libimagentrylink/src/internal.rs +++ b/lib/entry/libimagentrylink/src/internal.rs @@ -634,35 +634,34 @@ pub mod store_check { // // The lambda returns an error if something fails let aggregate_link_network = |store: &Store| -> Result> { - let iter = store + store .entries()? - .into_get_iter(store); + .into_get_iter(store) + .fold(Ok(HashMap::new()), |map, element| { + map.and_then(|mut map| { + debug!("Checking element = {:?}", element); + let entry = element?.ok_or_else(|| { + LE::from(String::from("TODO: Not yet handled")) + })?; - let mut map = HashMap::new(); - for element in iter { - debug!("Checking element = {:?}", element); - let entry = element?.ok_or_else(|| { - LE::from(String::from("TODO: Not yet handled")) - })?; + debug!("Checking entry = {:?}", entry.get_location()); - debug!("Checking entry = {:?}", entry.get_location()); + let internal_links = entry + .get_internal_links()? + .into_getter(store); // get the FLEs from the Store - let internal_links = entry - .get_internal_links()? - .into_getter(store); // get the FLEs from the Store + let mut linking = Linking::default(); + for internal_link in internal_links { + debug!("internal link = {:?}", internal_link); - let mut linking = Linking::default(); - for internal_link in internal_links { - debug!("internal link = {:?}", internal_link); + linking.outgoing.push(internal_link?.get_location().clone()); + linking.incoming.push(entry.get_location().clone()); + } - linking.outgoing.push(internal_link?.get_location().clone()); - linking.incoming.push(entry.get_location().clone()); - } - - map.insert(entry.get_location().clone(), linking); - } - - Ok(map) + map.insert(entry.get_location().clone(), linking); + Ok(map) + }) + }) }; // Helper to check whethre all StoreIds in the network actually exists From 3215311bc999348e7d703123badc9dd415fcdeed Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Mon, 29 Jan 2018 20:35:40 +0100 Subject: [PATCH 17/18] Add missing bugfixes in the changelog --- doc/src/09020-changelog.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/src/09020-changelog.md b/doc/src/09020-changelog.md index 29a4a066..9a2c8cc7 100644 --- a/doc/src/09020-changelog.md +++ b/doc/src/09020-changelog.md @@ -35,7 +35,6 @@ This section contains the changelog from the last release to the next release. * Minor changes * Internals were refactored from `match`ing all the things into function chaining - * `libimagbookmark` does not longer wrap types from the store. * The `toml-query` dependency was updated to 0.5.0 * `imag-timetrack list` lists with a table now * `imag-timetrack stop` now stops all runnings tags if none are specified @@ -43,6 +42,10 @@ This section contains the changelog from the last release to the next release. * `ResultExt::map_err_trace_exit()` was removed in favour of `ResultExt::map_err_trace_exit_unwrap()`. * Bugfixes + * `libimagbookmark` contained a type which wrapped a `FileLockEntry` from + `libimagstore`. This was considered a bug and was fixed. + * We depended on a crate which was licensed as GPLv2, which would yield imag + GPL as well. The dependency was removed. ## 0.5.0 From 44c62b061e2fa1e923324fe58c2bff0ae1e402c2 Mon Sep 17 00:00:00 2001 From: Matthias Beyer Date: Wed, 31 Jan 2018 11:29:24 +0100 Subject: [PATCH 18/18] Fix typo --- doc/src/09020-changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/src/09020-changelog.md b/doc/src/09020-changelog.md index 9a2c8cc7..6a848e15 100644 --- a/doc/src/09020-changelog.md +++ b/doc/src/09020-changelog.md @@ -37,7 +37,7 @@ This section contains the changelog from the last release to the next release. chaining * The `toml-query` dependency was updated to 0.5.0 * `imag-timetrack list` lists with a table now - * `imag-timetrack stop` now stops all runnings tags if none are specified + * `imag-timetrack stop` now stops all running tags if none are specified * The `toml-query` dependency was updated to 0.6.0 * `ResultExt::map_err_trace_exit()` was removed in favour of `ResultExt::map_err_trace_exit_unwrap()`.