This is the second call for participation for the imag project. I have no experience writing such calls for participation, so please bear with me!

This time, I can even list some TODOs which could be entry points for new contributors. I also added notes on how complex (low/medium/high) this would be and how much effort (small/medium/high) would be needed.

But first:

How can I contribute?

There are several ways to contribute. The most important thing right now is to get tools (we call them “modules”) implemented. In the sections below I list a few things we do not have in the imag ecosystem but would really love to have, for example an email tool or a health tracker!

But you can also contribute by testing out imag and reporting your experiences. If you find bugs (and trust me - there are bugs) report them! Report how you use imag and what you think could be improved (docs of course). Also request features, request modules, request the hell out of me - or even better: Contribute code!

Contributions (patches, questions, issues/bug reports) can be filed via the mailinglist.

runtime IO

Complexity: low, Effort: medium

The runtime IO experiements are rather successfull right now. We have to move the infrastructure to the new IO system completely and then we can have “imag-command-chaining” in imag 0.9.0.

What a potential contributor could do: Test out command chaining and use imag with it, then report where a command acts not as expected and provide ideas how it should behave.

Rewriting libimagentryref

Complexity: medium, Effort: medium

I’m thinking about rewriting the libimagentryref because the initial design was completely broken. A branch exists where I already edited some stuff, but this is a place where I really would like to see contributions!!!

I also wrote the README on how the library should work, and am of course available for questions.

The next thing after that would be libimagcontact and imag-contact , which depend on libimagentryref (after the rewrite).

Experimental macro for extending types

Complexity: easy, Effort: low

Requires experiences with rust macros. Mostly needs review.

I’m working on an experiemental macro to extend ::libimagstore::store::Entry without having to define a trait each time.

Right now it is limited (no generic support), but it seems to work. That means that one has to write less boilerplate when defining new functionality for Entry .

One could also get their hands into writing a procedural macro for this, so that we can simply

#[extend(::libimagstore::store::Entry)] pub trait Foo { fn bar(&self) -> i32 { 42 } }

or something like this. That might be worth a new (imag independent) crate, actually.

(There is actually a crate for this, contributions to that crate would be prefered over patches to the imag codebase. CC’ing welcome!)

Cleaning up the codebase and building helper functionality

Of course, contributions for simply cleaning up some messy code is also really welcome! Also documentation and especially tests are really welcome!

There are a lot of places where code could be made less verbose, less complex and overall better. Just feel free to simply drop patches to the mailinglist!

Some imag commands suffer from code which is not easy readable. This is mostly caused by things where we have to handle error cases. For example, we often have to handle the case where we Store::get some entries, then unwrap the Result we get from that function and then unwrap the Option we get. We often need to do this in an iterator, which makes the code even more ugly.

This is a code snippet from the list command implementation of the imag-contact module. Before we optimized the implementation:

let iterator = rt .store() .all_contacts() .map_err_trace_exit_unwrap(1) .into_get_iter(rt.store()) .map(|fle| { let fle = fle .map_err_trace_exit_unwrap(1) .ok_or_else(|| Error::from(err_msg("StoreId not found".to_owned()))) .map_err_trace_exit_unwrap(1); fle.deser().map_err_trace_exit_unwrap(1) }) .enumerate();

and after we optimized it:

... .into_get_iter(rt.store()) .trace_unwrap_exit(1) .map(|fle| fle.ok_or_else(|| Error::from(err_msg("StoreId not found".to_owned())))) .trace_unwrap_exit(1) .map(|e| e.deser()) .trace_unwrap_exit(1) .enumerate();

See that long line which is still there? That’s for unwrapping the Option<_> . A helper trait for all Iterator<Item = Option<T>> that applies Option::ok_or() would be really nice. That contribution would go to the resiter crate, actually, but the imag ecosystem needs to be cleaned up after such functionality is made available, too.

On top of such a helper, a functionality where we only have to provide the error message could be built, to make the above code look like this:

... .into_get_iter(rt.store()) .trace_unwrap_exit(1) .map_ok_or_err_msg("StoreId not found") .trace_unwrap_exit(1) .map(|e| e.deser()) .trace_unwrap_exit(1) .enumerate();

That’d be really awesome!

Of course there are more ways how one could clean up the codebase and improve code, documentation or tests!

Backlog

Here are the things from the last Call for Participation which are not yet done and where contributions are still welcome:

imag-mail

Complexity: medium, Effort: low/medium

Did you ever wanted to implement your own commandline email client? With the imag project, you get the chance!

Of course, there are already some thoughts on how I want the imag-mail command to behave like, but I’m open to discussions! Reach out to me to get some details (or, even better: start a discussion on the mailinglist)!

imag-health

Complexity: medium, Effort: low/medium

Did you ever wanted to implement your own commandline health/workout/diet tracker? With the imag project, you get the chance!

I do not have any idea how such a tool would work like, so I’m completely open to ideas and discussion about this! Feel free to reach out via the mailinglist!

imag-todo

Complexity: medium, Effort: low/medium

(Needs reimplementation)

Right now, imag-todo is rather minimal. It is actually not a todo-tracker, but a way of integrating “taskwarrior” into imag. I would like that to change. imag should implement its own todo-tool and taskwarrior (and todotxt) should be importable (and maybe even exportable). Crates for taskwarrior interaction and todotxt interaction are available in the rust ecosystem.

imag-bookmark

Complexity: low, Effort: low/medium

imag-bookmark is another tool which is rather minimal right now. I would like to provide as many useful features as possible and even a firefox/chromium plugin, which calls imag-bookmark for a new bookmark, would be really nice!

imag-entry

Complexity: low, Effort: low

A general imag-entry command would be nice. It should provide functionality to read and write header data and create new entries as well. Thus, it may provide the same features as imag-edit , as editing would be another usecase for a tool imag-entry .

Note: This should be in the next release. Contributions welcome, this is a rather simple task, as the infrastructure is already there, one would only need to write the binary.

Complexity: low, Effort: low

The imag-contact command lacks a way to edit a contact. All functionality is there, one has not to reinvent anything. The imag-contact create command can be (partily) reused.

imag-mv

Complexity: low, Effort: low

The imag-mv plumbing command does not have some features one’d expect from a “move” command, such as moving to a collection (directory). For example, this is not possible: imag mv some/entry to/some/directory/ .

Rewrite the “ModuleEntryPath” concept

Complexity: medium, Effort: medium

In libimagstore::storeid we have a helper macro which creates a ModuleEntryPath type in the client crate that can be used to create StoreId objects for one particular collection.

The concept is rather easy: A client uses a macro to generate a type which then can be used to create instances of StoreId which are automatically in the “right” collection in the store.

The implementation, though, has unwrap() calls and therefore can panic. This is not nice.

The “todo” here is to reevaluate the implementation and maybe replace it with something more flexible or less complex. Generating types at compiletime works, but is not necessary at all.

This “todo” involves touching a lot of files, as the first step would be to implement a new concept and then fix up all crates using the old concept and convert them to use the new implementation.

Complexity: medium, Effort: medium

The imag-ids command uses nom for parsing where -clauses, but the dependency is outdated. Updating the dependency could be non-trivial as nom gets updated in a major version ( 3.* -> 0.4 ).

Back to posts