diff options
authorMatthias Beyer <>2018-07-02 22:01:58 +0200
committerGitHub <>2018-07-02 22:01:58 +0200
commite50204041566b0ae02526da4a3bb344f1e33ffd5 (patch)
parenta138dd408dfab3325bd5513c7b5b035853e2b351 (diff)
parent8d86af5f15f98893e25b937b2f59534eeda47268 (diff)
Merge pull request #1499 from matthiasbeyer/minor
12 files changed, 79 insertions, 107 deletions
diff --git a/bin/domain/imag-bookmark/src/ b/bin/domain/imag-bookmark/src/
index 3438ee7..2741e89 100644
--- a/bin/domain/imag-bookmark/src/
+++ b/bin/domain/imag-bookmark/src/
@@ -94,7 +94,7 @@ fn add(rt: &Runtime) {
let mut collection = BookmarkCollectionStore::get(, &coll)
- .ok_or(BE::from(format!("No BookmarkcollectionStore '{}' found", coll)))
+ .ok_or(BE::from(format!("No bookmark collection '{}' found", coll)))
for url in scmd.values_of("urls").unwrap() { // unwrap saved by clap
@@ -135,7 +135,7 @@ fn list(rt: &Runtime) {
let collection = BookmarkCollectionStore::get(, &coll)
- .ok_or(BE::from(format!("No BookmarkcollectionStore '{}' found", coll)))
+ .ok_or(BE::from(format!("No bookmark collection '{}' found", coll)))
let links = collection.links(;
@@ -157,7 +157,7 @@ fn remove(rt: &Runtime) {
let mut collection = BookmarkCollectionStore::get(, &coll)
- .ok_or(BE::from(format!("No BookmarkcollectionStore '{}' found", coll)))
+ .ok_or(BE::from(format!("No bookmark collection '{}' found", coll)))
for url in scmd.values_of("urls").unwrap() { // enforced by clap
diff --git a/doc/ b/doc/
index b88d1fd..00a3bd5 100644
--- a/doc/
+++ b/doc/
@@ -3,19 +3,5 @@
This subdirectory contains the documentation of the basic idea behind ``imag''.
It is written in Markdown and compiled to both PDF and HTML via pandoc.
-# Contributing to this paper
-First, the paper is not build by travis-ci. This means if there are errors, they
-will be detected by me only if I build the paper. I know this is not optimal,
-but as documented in [70](,
-building the paper in travis would slow down the travis-ci machines too much.
-So if you want to contribute I would like you to build the paper, if you can.
-The dependencies you need are listed in the `default.nix` file (you don't need
-either nix nor nixos, all of these packages should be available in all major
-distros). Make sure you use pandoc `1.10+`.
-Contributing to this paper is done via normal pull requests, RFC-Like.
-That's all to it so far.
+Make sure you use pandoc `1.10+` if you want to build the paper.
diff --git a/doc/src/ b/doc/src/
index 76a67b1..ca645b5 100644
--- a/doc/src/
+++ b/doc/src/
@@ -1,17 +1,16 @@
# Introduction {#sec:introduction}
This document is the user documentation for imag, the personal
-information management suite for the commandline. Besides being a documentation,
-it serves also as "roadmap" where this project should go.
+information management suite for the commandline.
**Basically: This is Hobby stuff. Expect incompleteness, false statements and
-generally read with big grain of salt.**
+generally read with grain of salt.**
If you have any objections, suggestions for improvements, bugs, etc, please file
+them (See [@sec:contributing]).
A way to reach out to the imag project maintainer(s) is described in the
-CONTRIBUTING file of the repository or in this document, in the appropriate
+[@sec:contributing] section.
## The Problem {#sec:intro:problem}
@@ -19,20 +18,21 @@ The problem this project tries to solve is to provide a modular commandline
application for personal information management.
It targets "power users" or "commandline users", uses plain text as a storage
-format and tries to be scriptable.
+format and tries to be as scriptable as possible.
imag offers the ability to link data from different "PIM aspects" (such as
-"diary" and "bookmark" for example).
+"diary", "contacts" and "bookmark" for example).
One major goal of imag is to make the PIM data traverseable and queryable.
For example: a wiki article can be linked to an appointment which is linked to a
todo which is linked to a note which is linked to a contact.
imag wants to offer an all-in-one scriptable modular commandline personal
-information management suite for all PIM aspects one can think of.
+information management suite for all PIM aspects one could possibly think of.
Because imag uses plain text (TOML headers for structured data and plain text
which can be rendered using markdown, for example, for continuous text)
the user is always able to access their data without the imag tools at hand.
## The Approach {#sec:intro:approach}
The approach "imag" takes on solving this problem is to store content in a
@@ -42,8 +42,8 @@ structured data.
This can be used to implement a variety of "domain modules" using the store.
While content is stored in _one_ place, imag does not duplicate content.
imag does not copy or move icalendar files, emails, vcard files, music or
-movies to the store, but creates references to the actual files and stores
-meta-information in the store.
+movies to the store, but tries to remember the actual files are and stores
+meta-information about them in the store.
Detailed explanation on this approach follows in the chapters of this work.
@@ -57,7 +57,7 @@ library of the imag distribution to store content in the store of imag and
make it visible to imag this way.
This is a technical detail a user does not necessarily need to know, but as imag
-is intended for power-users anyways, we could say it fits here.
+is intended for power-users anyways, we would say it fits here.
## Alternative Projects {#sec:intro:alternatives}
@@ -68,6 +68,19 @@ for the [emacs]( text editor.
There is also [zim](, a desktop wiki editor which is
intended to be used for a personal wiki.
-The difference between imag and the mentioned projects is that imag is not there
-yet. Some parts can be used, though it is far away from being feature-complete.
+The difference between imag and the mentioned projects is:
+* emacs orgmode is (from what I know and see) for _orgabizing_ things. imag is
+ intended not only for organizing, but also for recording, tracking and
+ querying.
+* zim is a wiki, which could be used for PIM but is not specialized for it.
+ Recording habits might be possible, but not that simple as with imag
+imag is not there
+yet, though. Some parts can be used, though it is far away from being feature-complete.
+In addition: imag is text-editor independent and other tools than imag might be
+used to access data stored in the imag store.
+For example, one could "grep", "awk" and "sed" entries without much hassle and
+even write bash scripts for automatically filling imag entries with data.
diff --git a/doc/src/ b/doc/src/
index f56edbc..a6cf4d3 100644
--- a/doc/src/
+++ b/doc/src/
@@ -43,23 +43,24 @@ cross-read it for better understanding of the imag project.
### Library naming
-Libraries which provide functionality for entries or the store (most likely
-entries or both) should be named "libimagentrything" whereas "thing" stands for
+Libraries which provide functionality for entries or the store but no
+domain-functionality should be named "libimagentrything" whereas "thing" stands for
what the library provides.
-All other libraries should be prefixed with "libimag" at least. Most likely, one
-will not write such a library but rather a "libimagentrything" library.
+All domain libraries should be prefixed with "libimag".
### Library scope
A library should never introduce utility functionality which could be useful for
other libraries as well. If there is no such functionality available, the
"libimagutil" or "libimagentryutil" might be a place where such a function
-would be put.
+would go to.
If a library has to introduce free functions in its public interface, one should
think hard whether this is really necessary.
### Library error types/kinds
Libraries must use "error-chain" to create error types and kinds.
@@ -72,6 +73,7 @@ as many error kinds as required.
### Libraries with commandline frontends
Libraries with commandline frontends provide end-user functionality.
+They are called "domain" libraries.
they depend on one or more "libimagentrything" libraries. They should be named
"libimagthing", though. For example: "libimagdiary", "libimagtimetrack" or
@@ -83,8 +85,6 @@ If such a library needs to depend on another "libimagthing", for example if
whether the functionality could be outsourced to a more general
-A library which implements a functionality for imag may contain helper functions
-for commandline stuff, but that is discouraged.
### Library testing
@@ -96,6 +96,11 @@ possible without a lot of effort, but still: more tests = better!
The commandline tools are the CLI-frontends for their respective libraries.
So `libimagdiary` has a CLI frontend `imag-diary`.
-Those CLI frontends use functionality from `libimagrt` to build a consistent
-commandline interface.
+Those CLI frontends use functionality from `libimagrt` to build a
+commandline interface which is consistent with the rest of the ecosystem.
+Commandline interfaces should receive store IDs as positional arguments.
+Commandline interfaces should also provide a flag "-I" (that's a big i) which
+marks that the store IDs shall be read from stdin and are not passed via the
diff --git a/doc/src/ b/doc/src/
index 2d38b52..9182ea8 100644
--- a/doc/src/
+++ b/doc/src/
@@ -44,6 +44,3 @@ The architecture of indirections is as follows:
-As the library is build upon `libimagentryref`, it does not create a new
-subcollection in the store `/contacts`, but uses the infrastructure of
-`libimagentryref` which automatically puts all references in `/ref`.
diff --git a/doc/src/ b/doc/src/
index d9e8d69..43bce9e 100644
--- a/doc/src/
+++ b/doc/src/
@@ -5,12 +5,7 @@ This library crates implements a full diary.
One can have one or more diaries in the store, each diary can have unlimited
-### Future plans
-The diary should be able to provide _daily_, _hourly_ and even _minutely_
-diary entries, so one can use the diary as normal "Dear diary,
-today..."-diary, or more fine-grained and more like a journal.
-The internal file format as well as the store-path generation for this module is
-prepared for such functionality.
+The diary provides _daily_, _hourly_ and even _minutely_
+diary entries. For twitter-like log keeping, have a look at "libimaglog",
diff --git a/doc/src/ b/doc/src/
index 2812db3..8c4a436 100644
--- a/doc/src/
+++ b/doc/src/
@@ -1,8 +1,7 @@
## libimagentryfilter
Helper library to filter lists of entries by certain predicated. Offers filters
-for filtering by header values and other predicates, plus this library offers
-logical operants to combine filters.
+for filtering by header values and other predicates.
A commandline-to-filter DSL is planned for this, so commandline applications can
use this to implement a uniform filter interface.
diff --git a/doc/src/ b/doc/src/
index 6c6caff..70d1dea 100644
--- a/doc/src/
+++ b/doc/src/
@@ -1,5 +1,4 @@
## libimagentrylink
-Linking library for linking entries with other entries. Used for "imag-link",
-the commandline utility, but intended for use in other binaries and libraries as
+Linking library for linking entries with other entries.
diff --git a/doc/src/ b/doc/src/
index 37dd876..b54ba10 100644
--- a/doc/src/
+++ b/doc/src/
@@ -47,3 +47,8 @@ Not implemented yet:
of pathes, or does depth-first-search rather than
+### Known problems
+The functionality this library provides fails to work when syncing the imag
+store between two devices where the data layout is different on each device.
diff --git a/doc/src/ b/doc/src/
index 277c032..b5858d7 100644
--- a/doc/src/
+++ b/doc/src/
@@ -1,4 +1,4 @@
-# Contributing to imag
+# Contributing to imag {#sec:contributing}
So you want to contribute to imag! Thank you, that's awesome!
@@ -7,10 +7,6 @@ All contributors agree to the
by contributing to imag.
-## Without Github
-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](
and/or submit patches via mail (use `git format-patch` and
`git send-email`, always add a cover letter to describe your submission).
@@ -22,25 +18,11 @@ By adding that line, you agree to our
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 (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.
+Make sure to test-compile your patchset and, if available, run tests.
## Finding an issue
-Finding an issue is simple: We have
-[a special label in our issues section](
-for easy-to-solve issues. You can start there, don't hesitate to ask questions
-if you do not understand the issue comment!
-If there are currently no issues with that tag, just browse the issues or the
-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
@@ -71,36 +53,13 @@ All dependencies are installable with the nix package manager by using a
## 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. If it fails I will come back to you.
-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 (new commandline flags, other semantics in the
-commandline, etc), make sure to add a note in the `` file (in the
-same commit if it is a simple change).
-**If it is a bugfix**, do add the changelog entry in a new commit (best would
-be: one commit for a testcase which shows the bug, one commit for the fix, more
-if the fix is complicated, and one commit for the changelog entry).
-Changelog entries for bug fixes should be extra commits, because backporting
-bugfixes gets simpler this way.
+Make sure your patchset does not contain "Fixup" commits when publishing it, but feel
+free to send "Fixup" commits in the review process.
+If squashing fails I will come back to you.
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 before it
-will be merged to master.
-## Feature branches
-Use feature branches. If you could name them "<module name>/<what you do>",
-for example "libimagstore/add-debugging-calls", that would be awesome.
+write minimal and readable code. 100 characters per line, avoid noise in the
+codebase, ... you get it.
## Code of Conduct
diff --git a/lib/core/libimagrt/src/ b/lib/core/libimagrt/src/
index ed1bdc7..4e72404 100644
--- a/lib/core/libimagrt/src/
+++ b/lib/core/libimagrt/src/
@@ -319,6 +319,12 @@ impl<'a> Runtime<'a> {
/// Initialize the internal logger
+ ///
+ /// If the environment variable "IMAG_LOG_ENV" is set, this simply
+ /// initializes a env-logger instance. Errors are ignored in this case.
+ /// If the environment variable is not set, this initializes the internal imag logger. On
+ /// error, this exits (as there is nothing we can do about that)
+ ///
fn init_logger(matches: &ArgMatches, config: Option<&Value>) {
use log::set_max_level;
use log::set_boxed_logger;
diff --git a/lib/core/libimagstore/src/ b/lib/core/libimagstore/src/
index 3d63979..ddb1443 100644
--- a/lib/core/libimagstore/src/
+++ b/lib/core/libimagstore/src/
@@ -38,6 +38,10 @@ use iter::get::StoreGetIterator;
use iter::retrieve::StoreRetrieveIterator;
/// The Index into the Store
+/// A StoreId object is a unique identifier for one entry in the store which might be present or
+/// not.
#[derive(Debug, Clone, Hash, Eq, PartialOrd, Ord)]
pub struct StoreId {
base: Option<PathBuf>,
@@ -104,6 +108,11 @@ impl StoreId {
+ /// Check whether the StoreId exists (as in whether the file exists)
+ ///
+ /// # Warning
+ ///
+ /// Should be considered deprecated
pub fn exists(&self) -> Result<bool> {
self.clone().into_pathbuf().map(|pb| pb.exists())
@@ -148,14 +157,13 @@ impl StoreId {
- .map(|(component, pred_coll)| match component {
+ .all(|(component, pred_coll)| match component {
Component::Normal(ref s) => s
.map(|ref s| s == &pred_coll.as_ref())
_ => false
- .all(|x| x)
pub fn local_push<P: AsRef<Path>>(&mut self, path: P) {