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.
imag-contact-edit
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.
Update “nom” dependency in imag-ids
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).