Merge pull request #1009 from matthiasbeyer/doc-overhaul

Doc overhaul
This commit is contained in:
Matthias Beyer 2017-08-25 18:34:11 +02:00 committed by GitHub
commit 0f436d5b88
73 changed files with 574 additions and 536 deletions

View File

@ -1,290 +0,0 @@
# Contributing to imag
So you want to contribute to imag! Thank you, that's awesome!
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.
All contributors agree to the
[developer certificate of origin](#developer-certificate-of-origin)
by contributing to imag.
## Without Github
If you do not want to use github for your contribution, this is completely okay.
Feel free to contact [us via our mailinglist](http://imag-pim.org/mailinglist/)
via mail, feel also free to 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
[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).
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.
The following sections describe the way how to contribute with github.
## Finding an issue
Finding an issue is simple: We have
[a special label in our issues section](https://github.com/matthiasbeyer/imag/issues?q=is%3Aissue+is%3Aopen+label%3Acomplexity%2Feasy)
for easy-to-solve issues. You can start there, don't hesitate to ask questions
if you do not understand the issue comment!
Also, if you 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)
* Ruby and Bundler if you want to write a Ruby module.
Dependencies 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.
`make` can be helpful to automate the build process.
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
patches for OS X compatibility).
* If you want to build the documentation (you don't have to)
* pandoc
* pandoc-citeproc
* texlive
* lmodern (font package)
* 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!
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.
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.
## 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.
Use feature branches. If you could name them "<module name>/<what you do>",
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 and we can report
them to you rather quickly. Rewriting a whole PR is not satisfactory and we'd
like to make your contribution process enjoyable.
# 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 or Ruby
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.
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
We use the same
[code of conduct as the rust community does](https://www.rust-lang.org/conduct.html).
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).
## More information about the structure of this project
Here goes some notes on how this project is structured.
### Issue- and PR-Labels
Our labels are color coded as well as "namespaced". The color groups labels
exactly as the prefix does. The prefix is the first component which is seperated
from the others by `"/`". See below:
| Label | Description | search |
| --- | --- | --- |
| complexity/easy | Easy to do | [search][search-complexity/easy] |
| complexity/high | Not so easy to do | [search][search-complexity/high] |
| complexity/medium | Relatively easy | [search][search-complexity/medium] |
| kind/bug | Bug | [search][search-kind/bug] |
| kind/doc | Documentation related | [search][search-kind/doc] |
| kind/enhancement | Enhancement | [search][search-kind/enhancement] |
| kind/feature | Feature | [search][search-kind/feature] |
| kind/hotfix | Hotfix | [search][search-kind/hotfix] |
| kind/infrastructure | Infrastructure code | [search][search-kind/infrastructure] |
| kind/invalid | Not valid Issue/PR | [search][search-kind/invalid] |
| kind/nicetohave | Would be a nice thing | [search][search-kind/nicetohave] |
| kind/refactor | Refactor codebase | [search][search-kind/refactor] |
| meta/assigned | Is assigned | [search][search-meta/assigned] |
| meta/blocked | Blocked by other Issue/PR | [search][search-meta/blocked] |
| meta/blocker | Blocks other Issue/PR | [search][search-meta/blocker] |
| meta/decision-pending | Not clear what to do | [search][search-meta/decision-pending] |
| meta/dependencies | Dependency-related | [search][search-meta/dependencies] |
| meta/doc | Documentation related | [search][search-meta/doc] |
| meta/importance/high | Very Important | [search][search-meta/importance/high] |
| meta/importance/low | Not so important | [search][search-meta/importance/low] |
| meta/importance/medium | Rather important | [search][search-meta/importance/medium] |
| meta/on-hold | Do not work on this! | [search][search-meta/on-hold] |
| meta/ready | Ready for review/merge | [search][search-meta/ready] |
| meta/reopen-later | Reopen closed issue/pr later | [search][search-meta/reopen-later] |
| meta/WIP | Work in Progress | [search][search-meta/WIP] |
| nochange/duplicate | Duplicated | [search][search-nochange/duplicate] |
| nochange/question | Question | [search][search-nochange/question] |
| nochange/rfc | Request for comments | [search][search-nochange/rfc] |
| nochange/wontfix | Won't fix this issue | [search][search-nochange/wontfix] |
| part/bin/imag-counter | Targets binary: imag-counter | [search][search-part/bin/imag-counter] |
| part/bin/imag-link | Targets binary: imag-link | [search][search-part/bin/imag-link] |
| part/bin/imag-store | Targets binary: imag-store | [search][search-part/bin/imag-store] |
| part/bin/imag-tag | Targets binary: imag-tag | [search][search-part/bin/imag-tag] |
| part/bin/imag-view | Targets binary: imag-view | [search][search-part/bin/imag-view] |
| part/interface | Changes the interface | [search][search-part/interface] |
| part/lib/imagcounter | Targets library: imagcounter | [search][search-part/lib/imagcounter] |
| part/lib/imagentryfilter | Targets library: imagentryfilter | [search][search-part/lib/imagentryfilter] |
| part/lib/imagentrylink | Targets library: imagentrylink | [search][search-part/lib/imagentrylink] |
| part/lib/imagentrylist | Targets library: imagentrylist | [search][search-part/lib/imagentrylist] |
| part/lib/imagentrymarkup | Targets library: imagentrymarkup | [search][search-part/lib/imagentrymarkup] |
| part/lib/imagentryprinter | Targets library: imagentryprinter | [search][search-part/lib/imagentryprinter] |
| part/lib/imagentrytag | Targets library: imagentrytag | [search][search-part/lib/imagentrytag] |
| part/lib/imagentryview | Targets library: imagentryview | [search][search-part/lib/imagentryview] |
| part/lib/imagnotes | Targets library: imagnotes | [search][search-part/lib/imagnotes] |
| part/lib/imagrt | Targets library: imagrt | [search][search-part/lib/imagrt] |
| part/lib/imagstore | Targets library: imagstore | [search][search-part/lib/imagstore] |
| part/lib/imagutil | Targets library: | [search][search-part/lib/imagutil] |
| part/_new_binary | Introduces new binary | [search][search-part/_new_binary] |
| part/_new_library | Introduces new library | [search][search-part/_new_library] |
| test/change | Changes a test | [search][search-test/change] |
| test/missing | Test missing | [search][search-test/missing] |
| test/new | New test | [search][search-test/new] |
## Developer Certificate of Origin
```
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
660 York Street, Suite 102,
San Francisco, CA 94110 USA
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
```
## FAQ
_to be written_
[search-complexity/easy]: https://github.com/matthiasbeyer/imag/labels/
[search-complexity/high]: https://github.com/matthiasbeyer/imag/labels/complexity%2Fhigh
[search-complexity/medium]: https://github.com/matthiasbeyer/imag/labels/complexity%2Fmedium
[search-kind/bug]: https://github.com/matthiasbeyer/imag/labels/kind%2Fbug
[search-kind/doc]: https://github.com/matthiasbeyer/imag/labels/kind%2Fdoc
[search-kind/enhancement]: https://github.com/matthiasbeyer/imag/labels/kind%2Fenhancement
[search-kind/feature]: https://github.com/matthiasbeyer/imag/labels/kind%2Ffeature
[search-kind/hotfix]: https://github.com/matthiasbeyer/imag/labels/kind%2Fhotfix
[search-kind/infrastructure]: https://github.com/matthiasbeyer/imag/labels/kind%2Finfrastructure
[search-kind/invalid]: https://github.com/matthiasbeyer/imag/labels/kind%2Finvalid
[search-kind/nicetohave]: https://github.com/matthiasbeyer/imag/labels/kind%2Fnicetohave
[search-kind/refactor]: https://github.com/matthiasbeyer/imag/labels/kind%2Frefactor
[search-meta/assigned]: https://github.com/matthiasbeyer/imag/labels/meta%2Fassigned
[search-meta/blocked]: https://github.com/matthiasbeyer/imag/labels/meta%2Fblocked
[search-meta/blocker]: https://github.com/matthiasbeyer/imag/labels/meta%2Fblocker
[search-meta/decision-pending]: https://github.com/matthiasbeyer/imag/labels/meta%2Fdecision-pending
[search-meta/dependencies]: https://github.com/matthiasbeyer/imag/labels/meta%2Fdependencies
[search-meta/doc]: https://github.com/matthiasbeyer/imag/labels/meta%2Fdoc
[search-meta/importance/high]: https://github.com/matthiasbeyer/imag/labels/meta%2Fimportance%2Fhigh
[search-meta/importance/low]: https://github.com/matthiasbeyer/imag/labels/meta%2Fimportance%2Flow
[search-meta/importance/medium]: https://github.com/matthiasbeyer/imag/labels/meta%2Fimportance%2Fmedium
[search-meta/on-hold]: https://github.com/matthiasbeyer/imag/labels/meta%2Fon-hold
[search-meta/ready]: https://github.com/matthiasbeyer/imag/labels/meta%2Fready
[search-meta/reopen-later]: https://github.com/matthiasbeyer/imag/labels/meta%2Freopen-later
[search-meta/WIP]: https://github.com/matthiasbeyer/imag/labels/meta%2FWIP
[search-nochange/duplicate]: https://github.com/matthiasbeyer/imag/labels/nochange%2Fduplicate
[search-nochange/question]: https://github.com/matthiasbeyer/imag/labels/nochange%2Fquestion
[search-nochange/rfc]: https://github.com/matthiasbeyer/imag/labels/nochange%2Frfc
[search-nochange/wontfix]: https://github.com/matthiasbeyer/imag/labels/nochange%2Fwontfix
[search-part/bin/imag-counter]: https://github.com/matthiasbeyer/imag/labels/part%2Fbin%2Fimag-counter
[search-part/bin/imag-link]: https://github.com/matthiasbeyer/imag/labels/part%2Fbin%2Fimag-link
[search-part/bin/imag-store]: https://github.com/matthiasbeyer/imag/labels/part%2Fbin%2Fimag-store
[search-part/bin/imag-tag]: https://github.com/matthiasbeyer/imag/labels/part%2Fbin%2Fimag-tag
[search-part/bin/imag-view]: https://github.com/matthiasbeyer/imag/labels/part%2Fbin%2Fimag-view
[search-part/interface]: https://github.com/matthiasbeyer/imag/labels/part%2F_interface
[search-part/lib/imagcounter]: https://github.com/matthiasbeyer/imag/labels/part%2Flib%2Fimagcounter
[search-part/lib/imagentryfilter]: https://github.com/matthiasbeyer/imag/labels/part%2Flib%2Fimagentryfilter
[search-part/lib/imagentrylink]: https://github.com/matthiasbeyer/imag/labels/part%2Flib%2Fimagentrylink
[search-part/lib/imagentrylist]: https://github.com/matthiasbeyer/imag/labels/part%2Flib%2Fimagentrylist
[search-part/lib/imagentrymarkup]: https://github.com/matthiasbeyer/imag/labels/part%2Flib%2Fimagentrymarkup
[search-part/lib/imagentryprinter]: https://github.com/matthiasbeyer/imag/labels/part%2Flib%2Fimagentryprinter
[search-part/lib/imagentrytag]: https://github.com/matthiasbeyer/imag/labels/part%2Flib%2Fimagentrytag
[search-part/lib/imagentryview]: https://github.com/matthiasbeyer/imag/labels/part%2Flib%2Fimagentryview
[search-part/lib/imagnotes]: https://github.com/matthiasbeyer/imag/labels/part%2Flib%2Fimagnotes
[search-part/lib/imagrt]: https://github.com/matthiasbeyer/imag/labels/part%2Flib%2Fimagrt
[search-part/lib/imagstore]: https://github.com/matthiasbeyer/imag/labels/part%2Flib%2Fimagstore
[search-part/lib/imagutil]: https://github.com/matthiasbeyer/imag/labels/part%2Flib%2Fimagutil
[search-part/_new_binary]: https://github.com/matthiasbeyer/imag/labels/part%2F_new_binary
[search-part/_new_library]: https://github.com/matthiasbeyer/imag/labels/part%2F_new_library
[search-test/change]: https://github.com/matthiasbeyer/imag/labels/test%2Fchange
[search-test/missing]: https://github.com/matthiasbeyer/imag/labels/test%2Fmissing
[search-test/new]: https://github.com/matthiasbeyer/imag/labels/test%2Fnew

1
CONTRIBUTING.md Symbolic link
View File

@ -0,0 +1 @@
doc/src/09010-contributing.md

View File

@ -21,17 +21,10 @@ Our (long-term) goal is to
> management, consists of reusable parts and integrates well with known
> commandline tools.
imag is a PIM _helper_. We do not actually implement the PIM functionality, but
try to interface with existing PIM tools (via their API or via some standard
format they use, e.g. vcard) to make the data they manage _linkable_
and _queryable_ in an uniform way.
Yes, imag is a rather ambitous 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 whereever possible.
imag consists of _modules_ (e.g. `imag-notes`, `imag-tag`, `imag-view`), where
each module covers one PIM aspect.
The initial approach is to use one PIM tool for one module.
So you can use `imag-todo` with [taskwarrior](https://taskwarrior.org/),
`imag-mail` with Maildirs and `imag-calendar` with
[icalendar](https://en.wikipedia.org/wiki/ICalendar) files.
## Building/Running
@ -47,7 +40,7 @@ give you a commandline application.
We use `make` to automate the build process.
Make sure to _not_ include some `-j 8` arguments, this will _not_ work as you
might think!
might think, as the rust compiler automatically parallelizes stuff and if you `make -j 8`, you end up with a pretty high load!
There are several targets for each of the sub-crates in the Makefile:
@ -80,20 +73,12 @@ install-directory is in your `$PATH`), or install the `imag` binary to call `ima
## 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/).
[release notes](http://imag-pim.org/releases/) and monthly(ish) updates what's happening in the source tree.
There is no RSS feed, though.
We also have a [mailinglist](https://imag-pim.org/mailinglist/) where I post
updates and where discussion and questions are encouraged.
There is a blog series which gets an update once a month on my blog, where
[entries are tagged "imag"](https://beyermatthias.de/tags/imag/).
I also post non-regular posts about imag things there.
I also post these blog posts
[on reddit](https://www.reddit.com/r/rust/search?q=What%27s+coming+up+in+imag&restrict_sr=on)
and submit them to [this-week-in-rust](https://this-week-in-rust.org/).
## Documentation
This is a hobby project, so sometimes things are not optimal and might go
@ -112,10 +97,6 @@ be a bit outdated.
We are looking for contributors!
There is always a number of
[complexity/easy tagged issues](https://github.com/matthiasbeyer/imag/issues?q=is%3Aopen+is%3Aissue+label%3Acomplexity%2Feasy)
available in the issue tracker you can start with and we are open to questions!
Feel free to open issues for asking questions, suggesting features or other
things!

View File

@ -1,7 +1,7 @@
---
title: imag User Documentation
version: 0.3.0
date: July 2016
date: August 2017
listings: true
codeBlockCaptions: true
figureTitle: "Figure"

View File

@ -1,17 +1,25 @@
# Introduction {#sec:introduction}
This document aims to be the user documentation for imag, the personal
information management suite for the commandline.
This document is the user documentation for imag, the personal
information management suite for the commandline. Besides beeing a documentation,
it servey also as "roadmap" where this project should go. Parts which are not
yet implemented might be documented already, therefore. A list on what is
implemented and what is not can be found at the end of this document.
If you have any objections, suggestions for improvements, bugs, etc, please file
them in the github repository you got this documentation from.
them. A way to reach out to the imag project maintainer(s) is described in the
CONTRIBUTING file of the repository or in this document, on the appropriate
section.
## The Problem {#sec:intro:problem}
The problem "imag" wants to solve is rather simple. When the project was
The problem imag wants to solve is rather simple. When the project was
initiated, there was no PIM-Suite available which
* was for this domain of users ("power-users", "commandline users")
* uses plain text as storage format
* was scriptable
* was modular
* contained functionality to link content
The latter point is the bigger one: "imag" wants to offer the ability for users
@ -23,13 +31,14 @@ note which is linked to a contact.
## The Approach {#sec:intro:approach}
The approach "imag" takes on solving this problem is to store content in a
(per-user) global "store" and persisting content in a unified way.
Meta-Information is attached to the content which can be used to, for
example, query 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
"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 indexes them and stores the meta-information in the
store, making these things linkable this way.
store.
Detailed explanation on this approach follows in the chapters of this work.
@ -38,9 +47,9 @@ Detailed explanation on this approach follows in the chapters of this work.
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.
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 could say it fits here.

View File

@ -0,0 +1,68 @@
# Architecture of the imag code
The imag codebase has a rather simple overall architecture. But before introducing the reader to it, a few things have to be introduced.
## Crate types
There are different types of crates in the imag world. A crate is a rust project.
First of all, there are core crates. These crates provide the very core of imag and almost all other crates use them:
* libimagstore - The imag store is the abstraction overbthe filesystem. It provides primitives to get, write and manipulate store entries and their 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 extensional functionality for the types from libimagstore. For example, there is "libimagentrylink" which provides functionality to link two entries in the store.
The next kind of crate is the one that offers end-user functionality for a imag aspect, 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.
## Architecture of an imag module
With the things from above, a module could have the following architecture:
```
+---------------------------------------------+
| imag-foo |
+-----------------------------------+---------+
| libimagfoo | |
+-----------------+-----------------+ |
| | | |
| libimagentrybar | libimagentrybaz | |
| | | lib |
+-----------------+-----------------+ |
| | |
| ... | |
| | imag |
+-----------------------------------+ |
| | |
| libimagrt | |
| | error |
+-----------------------------------+ |
| | |
| libimagstore | |
| | |
+-----------------------------------+---------+
```
The foundation of all imag modules is the store, as one can see from the image. Above this there is the libimagrt, which provides the basic runtime and access to the `Store` object. Cross-cutting, there is the error library (and possibly the util library, but we do not care about this one here), which is used through 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.
## Types
The imag core, hence the libimagstore, libimagrt and libimagerror, provide a set 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 provides basic access to whether debugging or verbosity is enabled as well as the most important core object: The `Store`.
It is provided by the libimagstore library, the heart of everything.
When interacting with the store, two types are visible: `FileLockEntry` and `Entry` whereas the former derefs to the latter, which basically means that the former wraps the latter.
The `FileLockEntry` is a necessary wrapper for ensuring that when working concurrently with the store, an entry is only _borrowed_ once from the store. It also ensures that the object is alive as long as the store is.
The `Entry` type provides functionality like reading the actual content, its header and so on. Extensions for its functionality are implemented on this type, not on the `FileLockEntry`.
The `Entry` provides access to its header, which is a `toml::Value`, where toml is the toml-rs crate (external project). Conveniance functionality is provided via the `toml-query` crate, which is an external project which was initiated and extracted from the imag project.
Error types are also important. All errors in the imag prijects are generated by libimagerror usage and are interoperable. User code hardly handles the actual `Error` type but its inner one, `ErrorKind`, which is an enum where each member can be mapped to a representing text. Imag error types do never contain payload (they can via extensions, though it is not really practical and there is no usage for it).

View File

@ -0,0 +1,60 @@
# Conventions, best practices
This section goes about best practices in the imag codebase. It is mainly focused on developers, but a user may read it for getting to know how imag works.
Lets work our way up from the store and how to extend it to the commandline user interface.
## Store and Entry functionality
A `Entry` does not offer much functionality by itself. So its the job of libraries to _extend_ their functionality. This should never be done by wrapping the `Entry` type itself but by providing and implementing an extension trait on it.
Same goes for extending the `Store` type: never wrap it, always provide an extension trait for it.
These two rules ensure that the type does not lose any functionality from a wrapping. `Deref` could do that, but not over muliple levels, so extension traits it is. It also most likely results in functions inside the extension trait which all return a `Result<_, _>`.
## Libraries
In the next few sections, conventions and best practices for writing a imag library are written down.
A developer of imag should read this carefully, a user may skip this section or 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 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.
### 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" might be a place where such a function would be put, or, if not yet available, a "libimagentryutil" could be created.
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 the "libimagerror" tools to create error types and kinds. Most likely, a library needs some kinds for wrapping the errors from underlying libraries, such as the store itself.
A library must _never_ introduce multiple error types, but is free to introduce as many error kinds as required. Indeed, more kinds is better than fewer.
### Libraries with commandline frontends
Libraries with commandline frontends provide end-user functionality. Normally, they depend on one or more "libimagentrything" libraries. They should be named "libimagthing", though. For example: "libimagdiary", "libimagtimetrack" or "libimagwiki", whereas the commandline frontends would be "imag-diary", "imag-timetrack" and "imag-wiki", respectively.
If such a library needs to depend on another "libimagthing", for example if "libimagdiary" needs to depend on "libimagnote", one should think about this and whether the functionality could ve outsourced to a more general "libimagentrything". It is not forbidden, though.
A library which implements a functionality for imag may contain helper functions for commandline stuff, but that is discouraged.
### Library testing
All libraries should be tested as much as possible. Sometimes it may not be possible without a lot of effort, but still: more tests = better!
## Commandline tools
The next few sections describe how the commandline frontends are implemented. Each imag functionality (or module) has its own library and a commandline frontend for it.
The commandline frontends do contain little to no functionality. They simply translate the commandline parameters and options to calls to the appropriate library functions.
## Commandline tool testing
## Commandline interface

View File

@ -2,11 +2,3 @@
The Bibliography module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View File

@ -1,12 +1,6 @@
## Bookmarks {#sec:modules:bookmarks}
The Bookmarks module.
The Bookmarks module is for keeping URLs as bookmarks, tagging and categorizing them and
finally also open them in the browser.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View File

@ -1,11 +1,3 @@
## Borrow {#sec:modules:borrow}
The Borrow module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View File

@ -1,13 +1,11 @@
## Calendar {#sec:modules:calendar}
The Calendar module.
The calendar module implements a commandline calendar like khal. The calendar data itself is retrieved from icalendar files which should be located outside of the imag store. imag does not handle syncing of these files. `vdirsyncer` may be your tool of choise here.
imag can show events from the calendar(s) like any other commandline calendar tool and of course can also add, delete or edit entries (interactively or via commandline parameters).
### Description
### Internals
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->
What imag does internally is described in this section.
imag creates one entry in the store for one `icalendar` file. These entries are basically references to the real data. If an `icalendar` file is removed from the filesystem, imag does not delete it from the sfore if not told explicitely.

View File

@ -0,0 +1,6 @@
## Category {#sec:modules:category}
The Category module is a plumbing command for setting an entrys category. A category must exist before it can be set for an entry. That, and that each entry may have one or no category is the difference from tags.
Also: Categories may have sub-categories.

View File

@ -1,13 +1,7 @@
## Contacts {#sec:modules:contacts}
The Contacts module.
The Contacts module serves as a vcard viewer which is also able to alter, vcard files (either interactively or via commandline parameters).
The contacts module can also call other programs and pass contact information to them, for example `mutt`.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View File

@ -2,8 +2,6 @@
The Counter module helps you counting things.
### Description
In its current state the counter module is capable of simple counting. You can
create, list and delete counters which are simply numbers and incremet,
decrement, set and reset them.
@ -27,7 +25,3 @@ imag counter --reset example
imag counter --dec example # or -d example
```
### Backends
<!-- Backends the module supports including links to external resources -->

View File

@ -1,12 +1,5 @@
## Cuecards {#sec:modules:cuecards}
The Cuecards module.
The Cuecards module implements "cuacards-learning" like you probably did it in school.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View File

@ -1,23 +1,12 @@
## Diary {#sec:modules:diary}
The Diary module.
The diary module is for keeping your diary notes.
### Description
The diary module giv3s you the possibility to write your diary in imag.
It offers daily, hourly and minutely entries (the latter beeing more like
a private tumble-blog).
The diary module is for keeping your diary notes. It offers a self-implemented
diary which creates the entries in the store.
As of now there is only the possibility to create daily entries, but the
possibility to implement hourly or even minutely entries is there.
The module offers commands to create, delete, edit and list diary entries.
### Backends
At this moment, only the imag store is an available backend and therefor diary
entries are written to the imag store.
There is no implementation for other diary software planned _yet_, but there
might be a [jrnl](http://jrnl.sh/) backend some time, but not as long as `jrnl`
does not provide a multi-file storage system.
Exporting the diary is possible, so one can write it in markdown and
later pass that to pandoc, if desired, to generate a website or book
from it.

View File

@ -0,0 +1,4 @@
## Filter {#sec:modules:filter}
The Filter module is only of use when chaining up imag calls via bash pipes. It can be used to filter out entries based on some parameters, like for example whether a certain header field is set or not.

View File

@ -0,0 +1,5 @@
## Git {#sec:modules:git}
The Git module provises a convenient way to call the git executable on the imag store without having to `cd` to it first. Nothing more.

View File

@ -0,0 +1,6 @@
## GPS {#sec:modules:gps}
The GPS module is a plumbing command for attaching a GPS coordinate to an entry.

View File

@ -0,0 +1,8 @@
## Habit {#sec:modules:habit}
The Habit module is a habit tracker. One can add habits, specify how often they should be done and instantiate them.
Example: After creating a new habit "Sunday Run", which should be done on sundays, one can mark (only on sundays of course) that the habit was done. Statistics and number-crunching can be done later on, after there is some habit data there.
Exports to CSV are possible.

View File

@ -1,12 +1,4 @@
## Images {#sec:modules:images}
The Images module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->
The Images module is for tagging, categorizing and sorting images. GPS coordinates can be attached to image references. Images can be put into collections. Image viewing programs can be called from imag. If an image gets modified (for example via darktable) and a new image file is created, the Image module can be used to group them.

View File

@ -0,0 +1,7 @@
## Item {#sec:modules:item}
The Item module is a plumbing command to create entries for items in the imag store.
Items can be anything. For example, one could create a Tomato and a Bread as item to add them later in the shopping list (as in imag-shoppinglist), but also a computer and a printer can be created to use them later in a project (as in imag-project).

View File

@ -1,12 +1,4 @@
## Ledger {#sec:modules:ledger}
The Ledger module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->
The Ledger module implements a ledger like `beancount`.

View File

@ -1,9 +1,5 @@
## Link {#sec:modules:link}
The Linking module.
### Description
The linking module `imag-link` is one of the plumbing modules.
It offers the possibility to link entries in the store.
@ -14,11 +10,11 @@ used to do this (see @sec:modules:bookmarks).
The linking module offers functionality to add, remove and list both internal
(store entry to store entry) and external (store entry to URL) links.
#### Internal linking
### Internal linking
<!-- internal linking description remains to be written -->
#### External linking
### External linking
A store entry can only have _one_ external link. Therefor, when you create an
external link, the linking module creates a new entry in the store which links
@ -26,8 +22,3 @@ to this URL. The linking module then links you entry with this new entry by
using an internal link. This way one entry can have multiple external links
attached to it and external links are deduplicated automatically.
### Backends
As this is a plumbing module and only intended to be used with the imag store,
there is no reason to have other backends.

View File

@ -1,12 +1,29 @@
## Mails {#sec:modules:mails}
The Mails module.
The Mails module implements a commandline email client. Emails can be written (via `$EDITOR`) and viewed, also in threads. Emails can be crawled for creating new contacts.
### Description
A Text User Interface is not planned, but might be there at some point.
<!-- Description of the module -->
The mail module implements a minimal Email client. It does not handle IMAP syncing or SMTP things, it is just a _viewer_ for emails (a MUA).
### Backends
The goal of the initial implementation is only a CLI, not a TUI like mutt offers, for example (but that might be implemented later). As this is an imag module, it also creates references to mails inside the imag store which can be used by other tools then (for example `imag-link` to link an entry with a mail - or the imag entry representing that mail).
<!-- Backends the module supports including links to external resources -->
So this module offers functionality to read (Maildir) mailboxes, search for and list mails and mail-threads and reply to mails (by spawning the `$EDITOR`).
Outgoing mails are pushed to a special directory and can later on be send via `imag-mail` which calls a MTA (for example msmtp) and also creates store entries for the outgoing mails.
### CLI
The CLI of the imag-mail module is planned as follows:
imag mail track <path> [opts...] # track a new mail, mail file passed as path
imag mail scan <path> [opts...] # scan a maildir and track all untracked mails
imag mail box <name|path> # work with the mailbox specified by <name|path>, name mappings from config
imag mail list <args...> # list mails in a given mailbox for a given account or the default account
imag mail show <args...> # open new mails in the pager
imag mail thread list <args...> # list mails from a thread
imag mail thread show <args...> # open new mails from a thread in the pager or call a script with them
imag mail new <args...> # craft a new mail and safe it in the <outgoing> folder
imag mail send <args...> # send emails from the outgoing folder, optionally also move them to archice boxes
imag mail mv <srcbox> <dstbox> # move a mail (or thread) from one mailbox to another

View File

@ -1,12 +1,4 @@
## Movies {#sec:modules:movies}
The Movies module.
## Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->
The Movies module is for categorizing, rating and tagging movies.

View File

@ -1,12 +1,6 @@
## Music {#sec:modules:music}
The Music module.
The Music module is for rating, categorizing, tagging and enjoying music. It offers functionality to fetch lyrics, create automatically linkings from genre entries to music files (music files are represented as a entry jn imag), combining songs in albums and albums in artists, etc.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->
A scrobble server may be implemented at some point to provide more ways to retrieving data over ones music taste. Suggested songs (from the own library of music or via external tools like musicbrainz) may be a feature that comes aith the scrobble server.

View File

@ -1,12 +1,4 @@
## News {#sec:modules:news}
The News module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->
The News module is an RSS reader.

View File

@ -2,11 +2,3 @@
The Password module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View File

@ -0,0 +1,8 @@
## Project {#sec:modules:project}
The Project module can be used to plan and organize projects, though does not offer ways to share these plans with others. If that is desired, a new store should be created, put under version controll (possibly git) and shared via this mechanism.
The project tool integrates the timetracking module as well as the todo module.
A project is represented by a single imag entry. Notes, subprojects, todos, timetrackings and other things are linked to the project. A project does not necessarily have to be a programming project, but could be a project for building a house or losing weight for example.

View File

@ -0,0 +1,6 @@
## Rate {#sec:modules:rate}
The Rate module is another plumbing command. It simply offers rating functionality, whereas allowed values are 0-10 (0 beeing equal to no rating).

View File

@ -0,0 +1,5 @@
## Read {#sec:modules:read}
The Read module is a plumbing command for reading entries from the store and writing them to stdout for further processing.

View File

@ -0,0 +1,5 @@
## Receipt {#sec:modules:receipt}
The Receipt module is for tracking, categorizing, tagging, quering and managing receipts.

View File

@ -2,11 +2,3 @@
The Reference module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View File

@ -1,12 +1,4 @@
## Shoppinglists {#sec:modules:shoppinglists}
The Shoppinglists module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->
The Shoppinglists module provides functionality for creating shopping lists and organizing them. A shoppinglist can be printed and them be used to go shopping, of course.

View File

@ -2,11 +2,3 @@
The Store module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View File

@ -0,0 +1,5 @@
## Summary {#sec:modules:summary}
The Summary module is a wrapper to call a list (specified in the config file) of imag commands and viewing their outputs.

View File

@ -4,11 +4,3 @@ The Tagging module.
A valid tag matches the regex `[a-zA-Z][0-9a-zA-Z]*`.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View File

@ -0,0 +1,9 @@
## Timetrack {#sec:modules:timetrack}
The Timetrack module implements a `timewarrior`-like timetracking functionality for imag.
Each timetracking is a 'tag' which can be started and stopped. These tags are _no_ tags as in imag-tag, but timetracking-tags.
Summaries can be printed, also filtered by tags if desired.

View File

@ -1,12 +1,7 @@
## Todos {#sec:modules:todos}
## Todo {#sec:modules:todo}
The Todos module.
The Todo module implements `taskwarrior` functionality by integrating taskwarrior itself into imag.
### Description
Each taskwarrior task s referenced from imag and represented as imag entry, thus making it linkable by other imag entries.
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View File

@ -0,0 +1,13 @@
## Url {#sec:modules:url}
The Url module is a plumbing module to put URLs into the imag store.
### Implementation
The implementation of the URL module saves URLs on a per-entry basis. This means that each URL is hashed (with something like SHA512) and the hash is used as filename. The scheme is as follows:
/url/<hash of the domain>/<hash of the full URL>
This scheme results in grouping URLs of the same domain (for example https://imag-pim.org) but distinction of the actual full URL, while still deduplicating URLs. Entering the same URL twice results in the same entry.
This module does nothing more on its own. Its functionality may be used elsewhere (for example a bookmark module).

View File

@ -2,11 +2,3 @@
The View module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View File

@ -2,11 +2,3 @@
The Weather module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->

View File

@ -1,12 +1,4 @@
## Wiki {#sec:modules:wiki}
The Wiki module.
### Description
<!-- Description of the module -->
### Backends
<!-- Backends the module supports including links to external resources -->
The Wiki module provides a personal wiki implementation.

View File

@ -0,0 +1,11 @@
## Workout {#sec:modules:workout}
The Workout module is for tracking workouts. Burned calories, walked kilometers, lifting sets and all the things can be entered.
### Submodules
Each type of workout can be handled with one subcommand of the module, whereas training seasions can be used to group types of workouts (for example swimming and running).
A step-counter functionality is implemented as first submodule.
Import functionality for the step-counter submodule is available for importing from (for example) an Android step-counter App.

View File

@ -0,0 +1,5 @@
## Write {#sec:modules:write}
The Write module is a plumbing command for reading a store feom stdin and writing it to the filesystem.

View File

@ -0,0 +1,2 @@
## libimagbibliography

View File

@ -0,0 +1,2 @@
## libimagborrow

View File

@ -0,0 +1,2 @@
## libimagcalendar

View File

@ -0,0 +1,2 @@
## libimagcontacts

View File

@ -0,0 +1,2 @@
## libimagcuecards

View File

@ -0,0 +1,9 @@
## libimaghabit
The habit library implements a habit tracker.
A habit can be instantiated with a name and a time-period in which it should be fullfilled (eg. daily, ever 3 days, weekly...).
The module offers ways to generate statistics about habits.

View File

@ -0,0 +1,2 @@
## libimagimages

View File

@ -0,0 +1,2 @@
## libimagledger

View File

@ -0,0 +1,9 @@
## libimagmails
The mail library implements everything that is needed for beeing used to implement a mail reader (MUA).
It therefor providea reading mailboxes, getting related content or mails, saving attachements to external locations, crafting new mails and responses,...
It also offers, natively, ways to search for mails (which are represented as imag entries) via tags, categories or even other metadata.
For more information on the domain of the `imag-mail` command, look at the documentation of the @sec:modules:mails module.

View File

@ -0,0 +1,2 @@
## libimagmovies

View File

@ -0,0 +1,2 @@
## libimagmusic

View File

@ -0,0 +1,7 @@
## libimagnews
The library for the news module implements a RSS reader.
Details, for example where the feeds are stored (inside or outside the imag store) have to be evaluated.

View File

@ -0,0 +1,2 @@
## libimagnotes

View File

@ -0,0 +1,2 @@
## libimagpassword

View File

@ -0,0 +1,2 @@
## libimagproject

10
doc/src/05100-lib-read.md Normal file
View File

@ -0,0 +1,10 @@
## libimagread
This library is for the plumbing command `imag-read`.
It extends the `Runtime` object and adds a `write_store_to(writer)` function (amongst others). After calling this function, the calling program cannot continue to do things, so this consumes the `Runtime` object and the calling program is expected to exit with the returned error code.
The calling program is expected to _not_ print anything to stdout before or after calling this function.
This library is intended for use with the `imag-read` command only.

View File

@ -0,0 +1,2 @@
## libimagreceipt

View File

@ -0,0 +1,2 @@
## libimagshoppinglists

View File

@ -0,0 +1,7 @@
## libimagtodo
The library for the todo module.
Whether this wraps `taskwarrior` or implements a todo tracking mechanism in imag itself is to be defined. Probably the latter.

View File

@ -0,0 +1,2 @@
## libimagweather

View File

@ -0,0 +1,7 @@
## libimagwiki
The wiki library implements a complete wiki for personal use.
This basically is a note-taking functionality combined with linking.

View File

@ -0,0 +1,2 @@
## libimagworkout

View File

@ -0,0 +1,11 @@
## libimagwrite
This library is for the plumbing command `imag-write`.
It extends the `Runtime` object and adds a `read_store_from(reader)` function (amongst others). After calling this function, the calling program cannot continue to do things, so this consumes the `Runtime` object and the calling program is expected to exit with the returned error code.
The calling program is expected to _not_ print or read anything to/from stdout/stdin before or after calling this function.
This library is intended for use with the `imag-write` command only.

View File

@ -1,2 +0,0 @@
# Technical details {#sec:techdetails}

View File

@ -0,0 +1,170 @@
# Contributing to imag
So you want to contribute to imag! Thank you, that's awesome!
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
If you do not want to use github for your contribution, this is completely okay.
Feel free to contact [us via our mailinglist](http://imag-pim.org/mailinglist/)
via mail, feel also free to 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
[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 cannot take your patch, sorry.
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.
The following sections describe the way how to contribute with github.
## Finding an issue
Finding an issue is simple: We have
[a special label in our issues section](https://github.com/matthiasbeyer/imag/issues?q=is%3Aissue+is%3Aopen+label%3Acomplexity%2Feasy)
for easy-to-solve issues. You can start there, don't hesitate to ask questions
if you do not understand the issue comment!
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)
Dependencies 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.
`make` can be helpful to automate the build process.
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
patches for OS X compatibility).
If you want to build the documentation (you don't have to) you'll need:
* pandoc
* pandoc-citeproc
* texlive
* lmodern (font package)
* 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.
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.
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.
## 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.
Use feature branches. If you could name them "<module name>/<what you do>",
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 and we can report
them to you rather quickly. Rewriting a whole PR is not satisfactory and we'd
like to make your contribution process enjoyable.
# 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.
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
We use the same
[code of conduct as the rust community does](https://www.rust-lang.org/conduct.html).
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
```
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
660 York Street, Suite 102,
San Francisco, CA 94110 USA
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
```

View File

@ -1,2 +0,0 @@
## The store {#sec:techdetails:store}

1
libimagmail/README.md Symbolic link
View File

@ -0,0 +1 @@
../doc/src/04020-module-mails.md