Merge pull request #1219 from matthiasbeyer/minor

Minor patches
This commit is contained in:
Matthias Beyer 2018-02-01 13:18:31 +01:00 committed by GitHub
commit da4b823048
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 301 additions and 253 deletions

1
.gitignore vendored
View file

@ -1,3 +1,4 @@
Cargo.lock
out
target
.idea

View file

@ -29,8 +29,9 @@ addons:
- pkg-config
script:
- cargo build --all --all-features --verbose -j 1
- cargo test --all --all-features --verbose -j 1
- |
cargo build --all --all-features -j 1 || exit 1
cargo test --all --all-features -j 1 || exit 1
notifications:
email:

View file

@ -23,12 +23,10 @@ Our (long-term) goal is to
Yes, imag is a rather ambitious project as it tries to reimplement functionality
for several "personal information management aspects". It is a hobby project,
keep that in mind. We try to use standards like vcard and icalendar wherever
possible.
keep that in mind. We try to use standards like vcard, icalendar and others
wherever possible.
imag consists of _modules_ (e.g. `imag-notes`, `imag-tag`, `imag-view`), where
each module covers one PIM aspect. Have a look at
[the documentation](./doc/) for some more words on this.
Have a look at [the documentation](./doc/) for some more words on this.
## Building/Running
@ -48,6 +46,18 @@ Make sure to use a recent `cargo`, at least one with workspace support.
Building all crates works with `cargo build --all`, building individual crates
by `cd`ing to their directory and calling `cargo build`.
For building all commandline applications:
```bash
find bin -maxdepth 3 -name Cargo.toml -exec cargo build --manifest-path {} \;
```
For building only the core functionality
```bash
find bin/core -maxdepth 3 -name Cargo.toml -exec cargo build --manifest-path {} \;
```
### Running
After you build the module you want to play with, you can simply call the binary
@ -57,48 +67,43 @@ If you installed the module, you can either call `imag-<modulename>` (if the
install-directory is in your `$PATH`), or install the `imag` binary to call `imag
<modulename>` (also if everything is in your `$PATH`).
## Staying up-to-date
We have a [official website for imag](https://imag-pim.org), where I post
[release notes](http://imag-pim.org/releases/) and monthly(ish) updates what's
happening in the source tree ([RSS here](https://imag-pim.org/index.xml)).
We also have a [mailinglist](https://imag-pim.org/mailinglist/) where I post
updates and where discussion and questions are encouraged.
## Documentation
This is a hobby project, so sometimes things are not optimal and might go
unrecognized and slip through. Feel free to open issues about things you notice!
Though, we have some documentation in [the ./doc subtree](./doc/)
We have some documentation in [the ./doc subtree](./doc/)
which can be compiled to PDF or a website.
These docs are not published anywhere and are not even integrated into our CI,
so it might be broken (though it's unlikely).
Developer documentation is also available
[online on github.io](https://matthiasbeyer.github.io/imag/imag_documentation/index.html)
and [on docs.rs](https://docs.rs/releases/search?query=imag), though they might
be a bit outdated.
It might not be up to date, though.
Developer documentation for the last release is available
[on docs.rs](https://docs.rs/releases/search?query=imag).
## Please contribute!
We are looking for contributors!
Feel free to open issues for asking questions, suggesting features or other
things!
Also have a look at [the CONTRIBUTING.md file](./CONTRIBUTING.md)!
## Contact
Have a look at [our website](https://imag-pim.org) where you can find some
information on how to get in touch and so on.
## Contact
Feel free to join our new IRC channel at freenode: #imag
or our [mailinglist](https://imag-pim.org/mailinglist/).
## License
We chose to distribute this software under terms of GNU LGPLv2.1.

View file

@ -82,22 +82,18 @@ fn add(rt: &Runtime) {
let entry_name = scmd
.value_of("entry")
.map(PathBuf::from)
.map(|pb| pb.into_storeid().map_err_trace_exit(1).unwrap())
.map(|pb| pb.into_storeid().map_err_trace_exit_unwrap(1))
.unwrap(); // safed by clap
let _ = rt.store()
.get(entry_name)
.map_err_trace_exit(1)
.unwrap()
.map_err_trace_exit_unwrap(1)
.ok_or(AE::from("Entry does not exist".to_owned()))
.map_err_trace_exit(1)
.unwrap()
.map_err_trace_exit_unwrap(1)
.annotate(rt.store(), annotation_name)
.map_err_trace_exit(1)
.unwrap()
.map_err_trace_exit_unwrap(1)
.edit_content(&rt)
.map_err_trace_exit(1)
.unwrap();
.map_err_trace_exit_unwrap(1);
info!("Ok");
}
@ -109,17 +105,14 @@ fn remove(rt: &Runtime) {
let delete = scmd.is_present("delete-annotation");
let mut entry = rt.store()
.get(PathBuf::from(entry_name).into_storeid().map_err_trace_exit(1).unwrap())
.map_err_trace_exit(1)
.unwrap()
.get(PathBuf::from(entry_name).into_storeid().map_err_trace_exit_unwrap(1))
.map_err_trace_exit_unwrap(1)
.ok_or(AE::from("Entry does not exist".to_owned()))
.map_err_trace_exit(1)
.unwrap();
.map_err_trace_exit_unwrap(1);
let annotation = entry
.denotate(rt.store(), annotation_name)
.map_err_trace_exit(1)
.unwrap();
.map_err_trace_exit_unwrap(1);
if delete {
debug!("Deleting annotation object");
@ -130,8 +123,7 @@ fn remove(rt: &Runtime) {
let _ = rt
.store()
.delete(loc)
.map_err_trace_exit(1)
.unwrap();
.map_err_trace_exit_unwrap(1);
} else {
warn!("Not having annotation object, cannot delete!");
}
@ -149,17 +141,14 @@ fn list(rt: &Runtime) {
Some(pb) => {
let _ = rt
.store()
.get(pb.into_storeid().map_err_trace_exit(1).unwrap())
.map_err_trace_exit(1)
.unwrap()
.get(pb.into_storeid().map_err_trace_exit_unwrap(1))
.map_err_trace_exit_unwrap(1)
.ok_or(AE::from("Entry does not exist".to_owned()))
.map_err_trace_exit(1)
.unwrap()
.map_err_trace_exit_unwrap(1)
.annotations(rt.store())
.map_err_trace_exit(1)
.unwrap()
.map_err_trace_exit_unwrap(1)
.enumerate()
.map(|(i, a)| list_annotation(i, a.map_err_trace_exit(1).unwrap(), with_text))
.map(|(i, a)| list_annotation(i, a.map_err_trace_exit_unwrap(1), with_text))
.collect::<Vec<_>>();
}
@ -168,10 +157,9 @@ fn list(rt: &Runtime) {
let _ = rt
.store()
.all_annotations()
.map_err_trace_exit(1)
.unwrap()
.map_err_trace_exit_unwrap(1)
.enumerate()
.map(|(i, a)| list_annotation(i, a.map_err_trace_exit(1).unwrap(), with_text))
.map(|(i, a)| list_annotation(i, a.map_err_trace_exit_unwrap(1), with_text))
.collect::<Vec<_>>();
}
}

View file

@ -100,8 +100,7 @@ fn main() {
let diags = rt.store()
.entries()
.map_err_trace_exit(1)
.unwrap()
.map_err_trace_exit_unwrap(1)
.into_get_iter(rt.store())
.map(|e| {
e.map_err_trace_exit_unwrap(1)

View file

@ -103,8 +103,7 @@ fn add(rt: &Runtime) {
.get(sid)
.map_err_trace_exit_unwrap(1)
.map(|mut entry| {
let _ = entry.set_coordinates(c)
.map_err_trace_exit(1);
let _ = entry.set_coordinates(c).map_err_trace_exit_unwrap(1);
})
.unwrap_or_else(|| {
error!("No such entry: {}", entry_name);

View file

@ -106,7 +106,7 @@ fn main() {
}
})
.ok_or(LE::from("No commandline call".to_owned()))
.map_err_trace_exit(1);
.map_err_trace_exit_unwrap(1);
}
fn get_entry_by_name<'a>(rt: &'a Runtime, name: &str) -> Result<Option<FileLockEntry<'a>>, StoreError> {

View file

@ -75,7 +75,7 @@ fn main() {
let _ = rt
.store()
.move_by_id(sourcename, destname)
.map_err_trace_exit(1);
.map_err_trace_exit_unwrap(1);
info!("Ok.");
}

View file

@ -36,7 +36,7 @@ pub fn delete(rt: &Runtime) {
let _ = rt.store()
.delete(path)
.map_warn_err(|e| format!("Error: {:?}", e))
.map_err_trace_exit(1);
.map_err_trace_exit_unwrap(1);
}
#[cfg(test)]

View file

@ -35,7 +35,7 @@ pub fn retrieve(rt: &Runtime) {
let id = scmd.value_of("id").unwrap();
let path = PathBuf::from(id);
let store = Some(rt.store().path().clone());
let path = StoreId::new(store, path).map_err_trace_exit(1)?;
let path = StoreId::new(store, path).map_err_trace_exit_unwrap(1);
debug!("path = {:?}", path);
rt.store()

View file

@ -163,7 +163,7 @@ fn main() {
} else {
let _ = StdoutViewer::new(view_header, view_content)
.view_entry(&entry)
.map_err_trace_exit(1);
.map_err_trace_exit_unwrap(1);
}
}

View file

@ -107,28 +107,24 @@ fn list(rt: &Runtime) {
let _ = rt
.store()
.all_contacts()
.map_err_trace_exit(1)
.unwrap() // safed by above call
.map_err_trace_exit_unwrap(1)
.into_get_iter(rt.store())
.map(|fle| {
let fle = fle
.map_err_trace_exit(1)
.unwrap()
.map_err_trace_exit_unwrap(1)
.ok_or_else(|| CE::from("StoreId not found".to_owned()))
.map_err_trace_exit(1)
.unwrap();
.map_err_trace_exit_unwrap(1);
fle
.get_contact_data()
.map(|cd| (fle, cd))
.map(|(fle, cd)| (fle, cd.into_inner()))
.map(|(fle, cd)| (fle, Vcard::from_component(cd)))
.map_err_trace_exit(1)
.unwrap()
.map_err_trace_exit_unwrap(1)
})
.enumerate()
.map(|(i, (fle, vcard))| {
let hash = fle.get_path_hash().map_err_trace_exit(1).unwrap();
let hash = fle.get_path_hash().map_err_trace_exit_unwrap(1);
let vcard = vcard.unwrap_or_else(|e| {
error!("Element is not a VCARD object: {:?}", e);
exit(1)
@ -137,8 +133,7 @@ fn list(rt: &Runtime) {
let data = build_data_object_for_handlebars(i, hash, &vcard);
let s = list_format.render("format", &data)
.map_err_trace_exit(1)
.unwrap();
.map_err_trace_exit_unwrap(1);
println!("{}", s);
})
.collect::<Vec<_>>();
@ -157,18 +152,16 @@ fn import(rt: &Runtime) {
let _ = rt
.store()
.create_from_path(&path)
.map_err_trace_exit(1)
.unwrap();
.map_err_trace_exit_unwrap(1);
} else if path.is_dir() {
for entry in WalkDir::new(path).min_depth(1).into_iter() {
let entry = entry.map_err_trace_exit(1).unwrap();
let entry = entry.map_err_trace_exit_unwrap(1);
if entry.file_type().is_file() {
let pb = PathBuf::from(entry.path());
let _ = rt
.store()
.create_from_path(&pb)
.map_err_trace_exit(1)
.unwrap();
.map_err_trace_exit_unwrap(1);
info!("Imported: {}", entry.path().to_str().unwrap_or("<non UTF-8 path>"));
} else {
warn!("Ignoring non-file: {}", entry.path().to_str().unwrap_or("<non UTF-8 path>"));
@ -186,14 +179,11 @@ fn show(rt: &Runtime) {
let contact_data = rt.store()
.get_by_hash(hash.clone())
.map_err_trace_exit(1)
.unwrap()
.map_err_trace_exit_unwrap(1)
.ok_or(CE::from(format!("No entry for hash {}", hash)))
.map_err_trace_exit(1)
.unwrap()
.map_err_trace_exit_unwrap(1)
.get_contact_data()
.map_err_trace_exit(1)
.unwrap()
.map_err_trace_exit_unwrap(1)
.into_inner();
let vcard = Vcard::from_component(contact_data)
.unwrap_or_else(|e| {
@ -204,9 +194,7 @@ fn show(rt: &Runtime) {
let show_format = get_contact_print_format("contact.show_format", rt, &scmd);
let data = build_data_object_for_handlebars(0, hash, &vcard);
let s = show_format.render("format", &data)
.map_err_trace_exit(1)
.unwrap();
let s = show_format.render("format", &data).map_err_trace_exit_unwrap(1);
println!("{}", s);
info!("Ok");
}
@ -226,10 +214,7 @@ fn get_contact_print_format(config_value_path: &'static str, rt: &Runtime, scmd:
});
let mut hb = Handlebars::new();
let _ = hb
.register_template_string("format", fmt)
.map_err_trace_exit(1)
.unwrap();
let _ = hb.register_template_string("format", fmt).map_err_trace_exit_unwrap(1);
hb.register_escape_fn(::handlebars::no_escape);
::libimaginteraction::format::register_all_color_helpers(&mut hb);

View file

@ -25,7 +25,7 @@ pub fn build_data_object_for_handlebars<'a>(i: usize, hash: String, vcard: &Vcar
{
data.insert("i" , format!("{}", i));
/// The hash (as in libimagentryref) of the contact
// The hash (as in libimagentryref) of the contact
data.insert("id" , hash);
data.insert("ADR" , vcard.adr()

View file

@ -79,7 +79,7 @@ fn create(rt: &Runtime) {
let _ = note
.edit_content(rt)
.map_warn_err_str("Editing failed")
.map_err_trace_exit(1);
.map_err_trace_exit_unwrap(1);
}
}
@ -87,7 +87,7 @@ fn delete(rt: &Runtime) {
let _ = rt.store()
.delete_note(name_from_cli(rt, "delete"))
.map_info_str("Ok")
.map_err_trace_exit(1);
.map_err_trace_exit_unwrap(1);
}
fn edit(rt: &Runtime) {
@ -100,7 +100,7 @@ fn edit(rt: &Runtime) {
let _ = note
.edit_content(rt)
.map_warn_err_str("Editing failed")
.map_err_trace_exit(1);
.map_err_trace_exit_unwrap(1);
})
.unwrap_or_else(|| {
error!("Cannot find note with name '{}'", name);
@ -110,27 +110,22 @@ fn edit(rt: &Runtime) {
fn list(rt: &Runtime) {
use std::cmp::Ordering;
rt.store()
let _ = rt
.store()
.all_notes()
.map_err_trace_exit(1)
.map(|iter| {
let notes = iter
.filter_map(|noteid| rt.store().get(noteid).map_err_trace_exit_unwrap(1))
.sorted_by(|note_a, note_b| {
if let (Ok(a), Ok(b)) = (note_a.get_name(), note_b.get_name()) {
return a.cmp(&b)
} else {
return Ordering::Greater;
}
});
for note in notes.iter() {
note.get_name()
.map(|name| println!("{}", name))
.map_err_trace()
.ok();
}
.map_err_trace_exit_unwrap(1)
.filter_map(|noteid| rt.store().get(noteid).map_err_trace_exit_unwrap(1))
.sorted_by(|note_a, note_b| if let (Ok(a), Ok(b)) = (note_a.get_name(), note_b.get_name()) {
return a.cmp(&b)
} else {
return Ordering::Greater;
})
.ok();
.iter()
.for_each(|note| {
note.get_name()
.map(|name| println!("{}", name))
.map_err_trace()
.ok();
});
}

View file

@ -31,3 +31,4 @@ libimagstore = { version = "0.6.0", path = "../../../lib/core/libimagstore"
libimagrt = { version = "0.6.0", path = "../../../lib/core/libimagrt" }
libimagerror = { version = "0.6.0", path = "../../../lib/core/libimagerror" }
libimagtimetrack = { version = "0.6.0", path = "../../../lib/domain/libimagtimetrack" }
libimagutil = { version = "0.6.0", path = "../../../lib/etc/libimagutil" }

View file

@ -30,6 +30,7 @@ extern crate libimagerror;
extern crate libimagstore;
extern crate libimagrt;
extern crate libimagtimetrack;
extern crate libimagutil;
mod cont;
mod day;

View file

@ -29,9 +29,10 @@ use libimagrt::runtime::Runtime;
use libimagtimetrack::timetracking::TimeTracking;
use libimagtimetrack::tag::TimeTrackingTag;
use libimagtimetrack::timetrackingstore::*;
use libimagtimetrack::iter::get::GetTimeTrackIter;
use libimagtimetrack::iter::filter::has_end_time;
use libimagtimetrack::iter::filter::has_one_of_tags;
use libimagutil::warn_result::*;
use libimagutil::debug_result::*;
pub fn stop(rt: &Runtime) -> i32 {
let (_, cmd) = rt.cli().subcommand();
@ -74,41 +75,25 @@ pub fn stop(rt: &Runtime) -> i32 {
.collect()
});
let iter : GetTimeTrackIter = match rt.store().get_timetrackings() {
Ok(i) => i,
Err(e) => {
error!("Getting timetrackings failed");
trace_error(&e);
return 1
}
};
let filter = has_end_time.not().and(has_one_of_tags(&tags));
rt
.store()
.get_timetrackings()
.map_warn_err_str("Getting timetrackings failed")
.map_err_trace_exit_unwrap(1)
.trace_unwrap()
// Filter all timetrackings for the ones that are not yet ended.
iter.trace_unwrap()
.filter_map(|elem| {
if filter.filter(&elem) {
Some(elem)
} else {
None
}
// Filter all timetrackings for the ones that are not yet ended.
.filter(|e| filter.filter(e))
// for each of these timetrackings, end them
// for each result, print the backtrace (if any)
.fold(0, |acc, mut elem| {
elem.set_end_datetime(stop_time.clone())
.map_dbg(|e| format!("Setting end time worked: {:?}", e))
.map(|_| acc)
.map_err_trace_exit_unwrap(1)
})
// for each of these timetrackings, end them
// for each result, print the backtrace (if any)
.fold(0, |acc, mut elem| match elem.set_end_datetime(stop_time.clone()) {
Err(e) => { // if there was an error
trace_error(&e); // trace
1 // set exit code to 1
},
Ok(_) => {
debug!("Setting end time worked: {:?}", elem);
// Keep the exit code
acc
}
})
}

View file

@ -30,8 +30,6 @@ extern crate libimagtodo;
use std::process::{Command, Stdio};
use std::io::stdin;
use toml::Value;
use libimagrt::runtime::Runtime;
use libimagrt::setup::generate_runtime_setup;
use libimagtodo::taskstore::TaskStore;
@ -81,7 +79,6 @@ fn tw_hook(rt: &Runtime) {
}
fn list(rt: &Runtime) {
use toml_query::read::TomlValueReadExt;
use toml_query::read::TomlValueReadTypeExt;
let subcmd = rt.cli().subcommand_matches("list").unwrap();

View file

@ -58,7 +58,7 @@ in
pkgs.stdenv.mkDerivation rec {
name = "imag-doc";
src = ./.;
src = /var/empty;
version = "0.0.0";
buildInputs = [ env ];

View file

@ -6,30 +6,28 @@ All contributors agree to the
[developer certificate of origin](#developer-certificate-of-origin)
by contributing to imag.
If you already have something in mind, go ahead with [the prerequisites
section](#prerequisites). If you don't know what you could do, start here.
## Without Github
Contributing without a github account is perfectly fine.
Contributing without a github account is perfectly fine and actually encouraged
as we try to move away from github step by step.
Feel free to contact [us via our mailinglist](http://imag-pim.org/mailinglist/)
and/or submit patches via mail (use `git format-patch` and
`git send-email`, always add a cover letter to describe your submission).
Also ensure that each commit has
Also ensure that each commit submitted via email has
[a "Signed-off-by: " line](https://stackoverflow.com/questions/1962094/what-is-the-sign-off-feature-in-git-for).
By adding that line, you agree to our
[developer certificate of origin](#developer-certificate-of-origin).
If you do not add the "Signed-off-by: " line,
I reserve the right to reject your patch.
If you do not add the "Signed-off-by: " line, I reserve the right to kindly
reject your patch.
Once _I am_ okay with your patchset, I will
submit it as PR in the github repository, so more people can review it and CI
can test it (the mailinglist is not yet used as much as github). I might come
back to you if something broke in CI or someone has a suggestion how to improve
your PR. I will keep you as author of the commits.
submit it as PR in the github repository (as long as we're using github),
so CI can test it.
I might come back to you if something broke in CI or someone has a suggestion
how to improve your PR. I will keep you as author of the commits.
The following sections describe the way how to contribute with github.
## Finding an issue
@ -43,13 +41,17 @@ code... you'll always find things to improve!
Also, if you've found bugs or outdated stuff in our documentation, feel free to
file issues about them or even better: Write a pull request to fix them!
## Prerequisites
* cargo and rust compiler in current version (stable)
The prerequisites are simple: `cargo` and `rustc` in current version (stable)
or newer (we do not use nighly features though).
Dependencies are listed in the
Build dependencies for building are listed in the
[default.nix file](http://git.imag-pim.org/imag/tree/default.nix),
though you do not have to have `nix` installed to build imag.
though you do not have to have the `nix` package manager installed to build
imag.
Everything else will be done by `cargo`.
Note that this software is targeted towards commandline linux users and we do
not aim to be portable to Windows or Mac OSX (though I wouldn't mind merging
@ -61,65 +63,40 @@ If you want to build the documentation (you don't have to) you'll need:
* pandoc-citeproc
* texlive
* lmodern (font package)
* make
* (gnu) make
All dependencies are installable with the nix package manager by using a
`nix-shell`, if you have the nix package manager installed on your system.
## Commit guidelines
Please don't refer to issues or PRs from inside a commit message, if possible.
Make sure your PR does not contain "Fixup" commits when publishing it, but feel
free to push "Fixup" commits in the review process. We will ask you to clean
your history before merging! If you're submitting via patch-mail, I will do the
fixup squashing myself.
fixup squashing myself. If it fails I will come back to you.
Make sure to prefix your commits with `"doc: "` if you change the document. Do
not change document and code in one commit, always separate them.
Make sure to prefix your commits with `"doc: "` if you change the documentation.
Do not change document and code in one commit, always separate them.
If your changes are user-visible, make sure to add a note in the
`CHANGELOG.md` file.
If your changes are user-visible (new commandline flags, other semantics in the
commandline, etc), make sure to add a note in the `CHANGELOG.md` file (in the
same commit if it is a simple change).
We do not follow some official Rust styleguide for our codebase, but we try to
write minimal and readable code. 100 characters per line, as few lines as
possible, avoid noise in the codebase, ... you get it.
Not all of your commits have to be buildable. But your PR has to be.
Not all of your commits have to be buildable. But your PR has to be before it
will be merged to master.
## PR guidelines
We'd like to have one PR per module change. This means you _should_ only change
one imag module in one commit or PR (library plus belonging binary is okay).
As this is not always possible, we do not enforce this, though we might ask you
to split your commits/PR into two smaller ones.
## Feature branches
Use feature branches. If you could name them "<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 so we can report
them to you quickly. Rewriting a whole PR is not satisfactory and we'd
like to make your contribution process enjoyable for you.
# Merging tools which use the imag core functionality into this repo
If you're writing an application or module for imag, feel free to propose
integrating it into the imag core distribution, if it fulfills the following
requirements:
1. It is written in Rust
1. It has a commandline interface which is the main interface to the module
OR it is a utility library for creating new kinds of functionality within the
imag core.
The commandline interface should be structured like the existing interfaces
(as in commands, options and arguments).
1. It is licensed under the terms of GNU LGPLv2.1 OR all of your contributors
approve a commit which changes the license of your codebase to GNU LGPLv2.1
(The word "approve" in this sentence is to be defined).
If your tool does not fulfill these requirements, I won't merge it into the
imag core distribution.
## Code of Conduct
@ -129,10 +106,6 @@ We use the same
Basically: Be kind, encourage others to ask questions - you are encouraged to
ask questions as well!
## Contact
Feel free to reach out via mail/[mailinglist](http://imag-pim.org/mailinglist/)
or [IRC](irc://irc.freenode.net/#imag).
## Developer Certificate of Origin

View file

@ -35,11 +35,17 @@ This section contains the changelog from the last release to the next release.
* Minor changes
* Internals were refactored from `match`ing all the things into function
chaining
* `libimagbookmark` does not longer wrap types from the store.
* The `toml-query` dependency was updated to 0.5.0
* `imag-timetrack list` lists with a table now
* `imag-timetrack stop` now stops all runnings tags if none are specified
* `imag-timetrack stop` now stops all running tags if none are specified
* The `toml-query` dependency was updated to 0.6.0
* `ResultExt::map_err_trace_exit()` was removed in favour of
`ResultExt::map_err_trace_exit_unwrap()`.
* Bugfixes
* `libimagbookmark` contained a type which wrapped a `FileLockEntry` from
`libimagstore`. This was considered a bug and was fixed.
* We depended on a crate which was licensed as GPLv2, which would yield imag
GPL as well. The dependency was removed.
## 0.5.0

View file

@ -118,7 +118,6 @@ pub trait MapErrTrace {
fn map_err_trace(self) -> Self;
fn map_err_dbg_trace(self) -> Self;
fn map_err_trace_exit(self, code: i32) -> Self;
fn map_err_trace_exit_unwrap(self, code: i32) -> Self::Output;
fn map_err_trace_maxdepth(self, max: u64) -> Self;
}
@ -140,16 +139,9 @@ impl<U, E: Error> MapErrTrace for Result<U, E> {
self.map_err(|e| { trace_error_dbg(&e); e })
}
/// Simply call `trace_error_exit(code)` on the Err (if there is one).
///
/// This does not return if there is an Err(e).
fn map_err_trace_exit(self, code: i32) -> Self {
self.map_err(|e| { trace_error_exit(&e, code) })
}
/// Helper for calling map_err_trace_exit(n).unwrap() in one call
/// Trace the error and exit or unwrap the Ok(_).
fn map_err_trace_exit_unwrap(self, code: i32) -> Self::Output {
self.map_err_trace_exit(code).unwrap()
self.map_err(|e| { trace_error_exit(&e, code) }).unwrap()
}
/// Simply call `trace_error_maxdepth(max)` on the Err (if there is one) and return the error.

View file

@ -455,9 +455,17 @@ impl Store {
Walk::new(self.path().clone(), mod_name)
}
/// Return the `FileLockEntry` and write to disk
/// Write (update) the `FileLockEntry` to disk
///
/// See `Store::_update()`.
/// # Return value
///
/// On success: Entry
///
/// On error:
/// - UpdateCallError(LockPoisoned()) if the internal write lock cannot be aquierd.
/// - IdNotFound() if the entry was not found in the stor
/// - Errors Entry::verify() might return
/// - Errors StoreEntry::write_entry() might return
///
pub fn update<'a>(&'a self, entry: &mut FileLockEntry<'a>) -> Result<()> {
debug!("Updating FileLockEntry at '{}'", entry.get_location());
@ -471,16 +479,6 @@ impl Store {
/// This method assumes that entry is dropped _right after_ the call, hence
/// it is not public.
///
/// # Return value
///
/// On success: Entry
///
/// On error:
/// - UpdateCallError(LockPoisoned()) if the internal write lock cannot be aquierd.
/// - IdNotFound() if the entry was not found in the stor
/// - Errors Entry::verify() might return
/// - Errors StoreEntry::write_entry() might return
///
fn _update<'a>(&'a self, entry: &mut FileLockEntry<'a>, modify_presence: bool) -> Result<()> {
let mut hsmap = self.entries.write().map_err(|_| SE::from_kind(SEK::LockPoisoned))?;

View file

@ -266,7 +266,7 @@ impl<'a> Iterator for CategoryNameIter<'a> {
fn next(&mut self) -> Option<Self::Item> {
// TODO: Optimize me with lazy_static
let query = String::from(CATEGORY_REGISTER_NAME_FIELD_PATH);
let query = CATEGORY_REGISTER_NAME_FIELD_PATH;
self.1
.next()
@ -275,7 +275,7 @@ impl<'a> Iterator for CategoryNameIter<'a> {
.get(sid)?
.ok_or_else(|| CE::from_kind(CEK::StoreReadError))?
.get_header()
.read_string(&query)
.read_string(query)
.chain_err(|| CEK::HeaderReadError)?
.map(Category::from)
.ok_or_else(|| CE::from_kind(CEK::StoreReadError))

View file

@ -634,35 +634,34 @@ pub mod store_check {
//
// The lambda returns an error if something fails
let aggregate_link_network = |store: &Store| -> Result<HashMap<StoreId, Linking>> {
let iter = store
store
.entries()?
.into_get_iter(store);
.into_get_iter(store)
.fold(Ok(HashMap::new()), |map, element| {
map.and_then(|mut map| {
debug!("Checking element = {:?}", element);
let entry = element?.ok_or_else(|| {
LE::from(String::from("TODO: Not yet handled"))
})?;
let mut map = HashMap::new();
for element in iter {
debug!("Checking element = {:?}", element);
let entry = element?.ok_or_else(|| {
LE::from(String::from("TODO: Not yet handled"))
})?;
debug!("Checking entry = {:?}", entry.get_location());
debug!("Checking entry = {:?}", entry.get_location());
let internal_links = entry
.get_internal_links()?
.into_getter(store); // get the FLEs from the Store
let internal_links = entry
.get_internal_links()?
.into_getter(store); // get the FLEs from the Store
let mut linking = Linking::default();
for internal_link in internal_links {
debug!("internal link = {:?}", internal_link);
let mut linking = Linking::default();
for internal_link in internal_links {
debug!("internal link = {:?}", internal_link);
linking.outgoing.push(internal_link?.get_location().clone());
linking.incoming.push(entry.get_location().clone());
}
linking.outgoing.push(internal_link?.get_location().clone());
linking.incoming.push(entry.get_location().clone());
}
map.insert(entry.get_location().clone(), linking);
}
Ok(map)
map.insert(entry.get_location().clone(), linking);
Ok(map)
})
})
};
// Helper to check whethre all StoreIds in the network actually exists

10
scripts/commit-template Normal file
View file

@ -0,0 +1,10 @@
One line description of your change
Motivation:
Modifications:
Result:
# To use this template as commit template,
# call `git config commit.template <path of this file>

113
scripts/new-crate.sh Normal file
View file

@ -0,0 +1,113 @@
#!/usr/bin/env bash
# Helper script to create a new crate in the imag workspace
# 1. Creates a new crate
# 2. Adds the required crate meta information
# 3. Sets the version of the crate to the same version as libimagstore
# 4. Adds the crate to the top-level workspace
if [[ "$1" == "-h" || "$1" == "--help" ]];
then
echo "$0 [bin|lib] ./path/to/new/crate"
echo
echo "Execute _only_ from the top level of the repository"
exit 0
fi
crate_type="$1"
crate_location="$2"
exit_if_empty() {
[[ -z "$1" ]] && { echo "$2 not passed"; exit 1; }
}
exit_if_empty "$crate_type" "crate type"
exit_if_empty "$crate_location" "crate location"
exists_cmd() {
command -v $1 || { echo "No $1 found"; exit 1; }
}
exists_cmd "git"
exists_cmd "cargo"
{ cat ./Cargo.toml 2>/dev/null | head -n 1 | grep -q "[workspace]"; } || {
echo "Not in root of repository as it seems. Exiting";
exit 1;
}
[[ "$crate_type" == "lib" || "$crate_type" == "bin" ]] || {
echo "Invalid crate type, use 'lib' or 'bin'";
exit 1;
}
if [[ -e "$crate_location" ]]; then
echo "Crate exists: $crate_location"
exit 1;
fi
IFS=/ read -ra crate_name_parts <<< "$crate_location"
crate_name="${crate_name_parts[-1]}"
if [[ "$crate_type" == "lib" ]];
then
crate_description="Library for the imag core distribution"
else if [[ "$crate_type" == "bin" ]]; then
crate_description="Part of the imag core distribution: $crate_name command"
fi
git_name="$(git config user.name)"
git_email="$(git config user.email)"
store="lib/core/libimagstore/Cargo.toml"
crate_version=$(grep -m 1 version $store | cut -d '"' -f 2)
echo "Crate type: $crate_type"
echo "Crate location: $crate_location"
echo "Crate name: $crate_name"
echo "Crate version: $crate_version"
echo "Crate description: $crate_description"
echo "Crate author: $git_name <$git_email>"
echo "Not doing anything as this script is not ready yet."
echo "Exiting now"
exit 1
pushd "$(dirname $crate_location)"
crate new --${crate_type} $crate_name
cat <<EOS > ./$crate_name/Cargo.toml
[package]
name = "$crate_name"
version = "$crate_version"
authors = ["$git_name <$git_email>"]
description = "$crate_description"
keywords = ["imag", "PIM", "personal", "information", "management"]
readme = "../../../README.md"
license = "LGPL-2.1"
documentation = "https://matthiasbeyer.github.io/imag/imag_documentation/index.html"
repository = "https://github.com/matthiasbeyer/imag"
homepage = "http://imag-pim.org"
[badges]
travis-ci = { repository = "matthiasbeyer/imag" }
is-it-maintained-issue-resolution = { repository = "matthiasbeyer/imag" }
is-it-maintained-open-issues = { repository = "matthiasbeyer/imag" }
maintenance = { status = "actively-developed" }
[dependencies]
EOS
echo "Cargo.toml written. Please make sure that the README has the right path!"
popd
git add ${crate_location}/*
sed -i "$ s/]/ \"${crate_location}\",\n]/" Cargo.toml
echo "Top-level Cargo.toml modified. Please sort crate list manually!"