Merge branch 'doc' into master

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This commit is contained in:
Matthias Beyer 2019-12-01 16:38:53 +01:00
commit b25bf80c95
10 changed files with 139 additions and 148 deletions

View file

@ -1,86 +1,13 @@
# Introduction {#sec:introduction} # Introduction {#sec:introduction}
This document is the user documentation for imag, the personal This document is the user documentation for imag, the personal
information management suite for the commandline. information management suite for the commandline.
**Basically: This is Hobby stuff. Expect incompleteness, false statements and **Basically: This is Hobby stuff. Expect incompleteness, outdated documentation,
generally read with grain of salt.** false statements and generally read with grain of salt.**
If you have any objections, suggestions for improvements, bugs, etc, please file If you have any objections, suggestions for improvements, bugs, etc, please file
them (See [@sec:contributing]). them (See [@sec:contributing]).
A way to reach out to the imag project maintainer(s) is described in the A way to reach out to the imag project maintainer(s) is described in the
[@sec:contributing] section. [@sec:contributing] section.
## The Problem {#sec:intro:problem}
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 as scriptable as possible.
imag offers the ability to link data from different "PIM aspects" (such as
"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 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
"store" and persisting content in a unified way.
Meta-information is attached to the content which can be used to store
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 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.
## Implementation {#sec:intro:implementation}
The program is written in the Rust programming language.
The program consists of libraries which can be re-used by other projects
to implement and adapt imag functionality. An external program may use a
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 would say it fits here.
## Alternative Projects {#sec:intro:alternatives}
imag is not the only project which tries to solve that particular problem. For
example there is
[org mode](https://orgmode.org)
for the [emacs](https://www.gnu.org/software/emacs/) text editor.
There is also [zim](http://zim-wiki.org/), a desktop wiki editor which is
intended to be used for a personal wiki.
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.

View file

@ -0,0 +1,21 @@
## The Problem {#sec:intro:problem}
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 as scriptable as possible.
imag offers the ability to link data from different "PIM aspects" (such as
"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 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.

View file

@ -0,0 +1,15 @@
## The Approach {#sec:intro:approach}
The approach "imag" takes on solving this problem is to store content in a
"store" and persisting content in a unified way.
Meta-information is attached to the content which can be used to store
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 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.

View file

@ -0,0 +1,13 @@
## Implementation {#sec:intro:implementation}
The program is written in the Rust programming language.
The program consists of libraries which can be re-used by other projects
to implement and adapt imag functionality. An external program may use a
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 would say it fits here.

View file

@ -0,0 +1,26 @@
## Alternative Projects {#sec:intro:alternatives}
imag is not the only project which tries to solve that particular problem. For
example there is
[org mode](https://orgmode.org)
for the [emacs](https://www.gnu.org/software/emacs/) text editor.
There is also [zim](http://zim-wiki.org/), a desktop wiki editor which is
intended to be used for a personal wiki.
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.

View file

@ -4,47 +4,48 @@ The imag codebase has a rather simple overall architecture.
In this chapter the types of crates, architecture of an imag module In this chapter the types of crates, architecture of an imag module
and the type structure are described. and the type structure are described.
## Crate types ## Crate types
There are different types of crates in the imag world. A crate is a rust There are different types of crates in the imag world:
project.
First of all, there are core crates. These crates provide the very core of imag * "core" crates:
and almost all other crates use them: * libimagstore - The imag store is the abstraction over the filesystem. It
provides primitives to get, write and manipulate store entries and their
header information.
* libimagrt - The runtime library, which provides default argument parser
setup, interfacing with STDIN/STDOUT, configuration loading and parsing.
Simply put: It provides the runtime for a imag commandline application.
* libimagerror - Error handling library for handling errors the imag way. Used
in all other crates, even the store itself. It also offers functionality to
log and trace errors as well as exiting the application, if necessary.
(Note: This library might be removed in the future.)
* "entry" crates:
"Entry" crates provide extensional functionality for the types from
libimagstore. For example, there is "libimagentrylink" which provides
functionality to link two entries in the store.
* "domain" crates offer end-user functionality for a imag
domain, for example "libimagtodo" provides functionality to track todos.
* "etc"/"util" crates for simple utilities.
* libimagstore - The imag store is the abstraction over the filesystem. It These are all libraries. There are also binary crates in the imag project
provides primitives to get, write and manipulate store entries and their (though they are technically _also_ library crates):
header information.
* libimagrt - The runtime library, which provides functionality to create a
store object from libimagstore, helps with configurarion loading and
commandline argument handling (through the external "clap" crate).
* libimagerror - Error handling library for handling errors the imag way. Used
in all other crates, even the store itself. It also offers functionality to
log and trace errors as well as exiting the application, if necessary.
* libimagutil - Utilities.
The next type of imag crates are entry extension libraries. Those provide * "core" binary crates, which implement core functionality of imag, such as
extensional functionality for the types from libimagstore. For example, there is commandline interfaces for tagging, linking, ... entries as well as querying
"libimagentrylink" which provides functionality to link two entries in the them from the store and altering their data.
store. * "domain" binary crates, which implement a domain such as "todo" handling or
"calendar" handling.
The third kind of crate is the one that offers end-user functionality for a imag
domain, for example "libimagtodo" provides functionality to track todos.
And last, but not least, the commandline frontend crates provide the user
interface. These are the kind of crates that are not library crates, but
binaries.
Besides these, there are some other utility crates.
## Architecture of an imag module ## Architecture of an imag module
With the things from above, a module could have the following architecture: With the things from above, a module could have the following architecture:
``` ```
+---------------------------------------------+
| imag-foo |
+-----------------------------------+---------+ +-----------------------------------+---------+
| imag-foo | |
+-----------------------------------+ |
| libimagfoo | | | libimagfoo | |
+-----------------+-----------------+ | +-----------------+-----------------+ |
| | | | | | | |
@ -52,35 +53,35 @@ With the things from above, a module could have the following architecture:
| | | lib | | | | lib |
+-----------------+-----------------+ | +-----------------+-----------------+ |
| | | | | |
| ... | | | <more library crates> | |
| | imag | | | imag |
+-----------------------------------+ | +-----------------------------------+ |
| | | | | |
| libimagrt | | | libimagstore | rt |
| | error |
+-----------------------------------+ |
| | |
| libimagstore | |
| | | | | |
+-----------------------------------+---------+ +-----------------------------------+---------+
``` ```
External dependencies are not listed in this graphic.
The foundation of all imag modules is the store, as one can see in the The foundation of all imag modules is the store, as one can see in the
visualization from above. visualization from above.
Above the store library there is the libimagrt, which provides the basic runtime Above the store level, entry libraries and domain libraries are used to
and access to the `Store` object. implement functionality.
Cross-cutting, there is the error library (and possibly The highest level of all imag modules is the commandline interface
the util library, but we do not care about this one here), which is used through on top of the domain library. In between can be any number of entry extension
all levels. The highest level of all imag modules is the commandline interface
on top of the domain library. In between can be any number of entry extension
libraries, or none if not needed. libraries, or none if not needed.
libimagrt is used by the binary to construct the runtime, which itself
constructs and initializes the Store, so this library is used in the full stack
more or less.
Theoretically, the commandline interface crate could be replaced to build a Theoretically, the commandline interface crate could be replaced to build a
terminal user interface, graphical user interface or web interface. terminal user interface, graphical user interface or web interface.
## Types ## Types
The imag core, hence the libimagstore, libimagrt and libimagerror, provide a set The imag core, hence the libimagstore and libimagrt, provide a set
of types that a user (as in a library writer) should be aware of. of types that a user (as in a library writer) should be aware of.
First of all, there is the `Runtime` type which is provided by the libimagrt. It First of all, there is the `Runtime` type which is provided by the libimagrt. It
@ -103,10 +104,6 @@ not on the `FileLockEntry`.
The `Entry` provides access to its header, which is a `toml::Value`, where toml The `Entry` provides access to its header, which is a `toml::Value`, where toml
is the toml-rs crate (external project). Convenience functionality is provided is the toml-rs crate (external project). Convenience functionality is provided
via the `toml-query` crate, which is an external project which was initiated and via the `toml-query` crate, an external project which was initiated and
extracted from the imag project. extracted from the imag project.
Error types are also important.
All errors in imag projects should be created with `error-chain`.
libimagerror provides functionality to enhance the experience with `Result`
types and general tracing of errors.

View file

@ -42,33 +42,34 @@ The following section describe their purpose.
The header format is where imag stores its data. The header is an area at the The header format is where imag stores its data. The header is an area at the
top of every file which is seperated from the content part by three dashes top of every file which is seperated from the content part by three dashes
(`---`). Between these three dashes there is structured data. imag uses `TOML` (`---`). Between these three dashes there is structured data. imag uses `TOML`
as data format for this structured data, because it fits best and the available as data format for this structured data.
`TOML` parser for the rust programming language is really good.
The header can contain any amount of data, but modules (see @sec:modules) are The header can contain any amount of data, but modules (see @sec:modules) are
restricted in their way of altering the data. restricted (by convention) in their way of altering the data.
So normally there are several sections in the header. One section (`[imag]`) is Normally there are several sections in the header. One section (`[imag]`) is
always present. It contains a `version` field, which tells imag which version always present, it is automatically created by the store and contains a
this file was created with. `version` field, which tells imag which version this file was created with.
The store automatically verifies that it is compatible (satisfying semver) with
the version of imag an entry was created with, and if it is not, it fails
loading the entry.
Other sections are named like the modules which created them. Every module is Other sections are named like the modules which created them. Every module is
allowed to store arbitrary data under its own section and a module may never allowed to store arbitrary data under its own section and a module may never
read other sections than its own. read or write other sections than its own.
These conventions are not enforced by imag itself, though.
### Content Format {#sec:thestore:fileformat:content} ### Content Format {#sec:thestore:fileformat:content}
The content is the part of the file where the user is free to enter any textual The content is the part of the file where the user is free to enter any textual
content. The content may be rendered as Markdown or other markup format for the content. The content may be rendered as Markdown or other markup format for the
users convenience. The store does never expect and specific markup and actually users convenience. The store does never expect any specific markup.
the markup implementation is not inside the very core of imag.
Technically it would be possible that the content part of a file is used to Technically it would be possible that the content part of a file is used to
store binary data. store binary data.
We don't want this, though, as it is contrary to the goals of imag. We don't want this, though, as it is contrary to the goals of imag.
### Example {#sec:thestore:fileformat:example} ### Example {#sec:thestore:fileformat:example}
An example for a file in the store follows. An example for a file in the store follows.
@ -96,15 +97,13 @@ The "Entries" are stored as files in the "Store", which is a directory the
user has access to. The store may exist in the users Home-directory or any user has access to. The store may exist in the users Home-directory or any
other directory the user has read-write-access to. other directory the user has read-write-access to.
Each module stores its data in an own subdirectory in the store. This is because Each module stores its data in an own subdirectory in the store, by convention.
we like to keep things ordered and clean, not because it is technically
necessary.
We name the path to a file in the store "Store id" or "Storepath" and we often The path to a file in the store is named "Store id" (or short "ID") and we
refer to it by using the store location as root. refer to it by using the store location as root.
So if the store exists in `/home/user/store/`, a file with the storepath So if the store exists in `/home/user/.imag/store/`, a file with the storepath
`example.file` is (on the filesystem) located at `example.file` is (on the filesystem) located at
`/home/user/store/example.file`. `/home/user/.imag/store/example.file`.
By convention, each `libimagentry<name>` and `libimag<name>` module stores its By convention, each `libimagentry<name>` and `libimag<name>` module stores its
entries in in `<name>/`. entries in in `<name>/`.

View file

@ -47,7 +47,7 @@ Libraries which provide functionality for entries or the store but no
domain-functionality should be named "libimagentrything" whereas "thing" stands for domain-functionality should be named "libimagentrything" whereas "thing" stands for
what the library provides. what the library provides.
All domain libraries should be prefixed with "libimag". All domain libraries should be prefixed with "libimag".
### Library scope ### Library scope
@ -93,7 +93,7 @@ possible without a lot of effort, but still: more tests = better!
The commandline tools are the CLI-frontends for their respective libraries. The commandline tools are the CLI-frontends for their respective libraries.
So `libimagdiary` has a CLI frontend `imag-diary`. So `libimagdiary` has a CLI frontend `imag-diary`.
Those CLI frontends use functionality from `libimagrt` to build a Those CLI frontends use functionality from `libimagrt` to build a
commandline interface which is consistent with the rest of the ecosystem. commandline interface which is consistent with the rest of the ecosystem.
Commandline applications use the runtime interfaces for receiving IDs from the Commandline applications use the runtime interfaces for receiving IDs from the

View file

@ -51,7 +51,7 @@ All dependencies are installable with the nix package manager by using a
## Commit guidelines ## Commit guidelines
Make sure your patchset does not contain "Fixup" commits when publishing it, but feel Make sure your patchset does not contain "Fixup" commits when publishing it, but feel
free to send "Fixup" commits in the review process. free to send "Fixup" commits in the review process.
If squashing fails I will come back to you. If squashing fails I will come back to you.
We do not follow some official Rust styleguide for our codebase, but we try to We do not follow some official Rust styleguide for our codebase, but we try to

View file

@ -2,13 +2,6 @@
This section contains the changelog. This section contains the changelog.
We try to include a changelog line in each pull request, to make sure the
changelog is up to date when releasing a new version of the codebase.
Make sure to append the new change to the list, do not prepend it.
The "Major" section of each section includes huge changes in functionality and
interfaces (but not necessarily user-facing ones), whereas the "Minor" section
contains only small stuff.
Some things, like typo fixes, version string updates and such are not stated in Some things, like typo fixes, version string updates and such are not stated in
the changelog (though updating of dependencies is). the changelog (though updating of dependencies is).
Please note that we do not have a "Breaking changes" section as we are in Please note that we do not have a "Breaking changes" section as we are in