This way we alter the underlying iterator for all contacts to only
iterate in the "contact" collection of the store, which results in fewer
disk access because the internal iterator does not yield all pathes from
the store before filtering them.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Because this API only errors when write!() errors occur, we can return
the exit code as an error here.
This way the user of the API can immediately exit if there was an IO
error, but the API automatically takes care of the right return value,
returning (exiting) with zero (0) if there was an "Broken pipe" error
and with one (1) otherwise, which is the expected behaviour here.
All calls to that API were changed accordingly.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
With this patch, libimagentryannotation does not have special iterator
types anymore. This makes the whole thing more comfortable to use.
In imag-annotate, the parameter for the functioncall was removed.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
It makes no sense to name annotations, a user only cares about whether
there are annotations or not, or their contents. A name has no meaning
in this context.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This removes the feature to be able to override log destinations from
the commandline.
This feature is removed because the --override-config feature from the
runtime already contains this functionality. It is a little more complex
to use, though this is a feature hardly used at all, so I rather go for
less code (less complexity) here than feature bloat.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This feature gives the users of the Runtime API the possibility to check
whether the user wants the ID reporting to be ignored as well (and more
important) to override the default behaviour where the runtime assumes
that if STDOUT is a pipe, it is a pipe to an imag command.
Before, this would not have been possible:
imag contact find Jonas --json | jq 'map(.fullname)'
because the runtime automatically prints the output of the command to
stderr and the touched IDs to stdout.
But now with this change, a user can override this default behaviour and
do:
imag contact --ignore-ids find Jonas --json | jq 'map(.fullname)'
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
1.2 of lazy_static brings functionality to have no panics in the code,
which is what we try to have.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
to also return the index page. This way a user of the library can use
the index page entry right away.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
...to report newly created entries, so that we can re-use these new
entries in the library-using code (for example for ID reporting).
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
With this patch, IDs can be fetched from the CLI via libimagrt. This
gives us the possibility to automatically handle "stdin provides IDs" in
libimagrt with less boilerplate in the binaries codebases.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This patch adds the id reporting feature to libimagrt::runtime::Runtime,
where processed ("touched") ids can be reported to the Runtime and then
get printed to stdout if stdout is a pipe.
Other output is automatically redirected to stderr if stdout is a pipe
now.
The function already returns `Result<_>`, the only thing that had to be
done was refactoring the code for actually returning an error in that
case.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
With this patch, the log level aggregation is abstracted away by using
zero sized types and a macro to implement the whole thing.
This does not alter functionality, but makes the code more readable.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
::stf::fs::create_dir_all() takes any ref to `Path`, which is what we
have here, so we can leave out the allocation of a new PathBuf object
here.
Also remove the match by a `if let Some(_)`, which increases the
readability a bit.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
With this change, the cache is tested before accessing the filesystem,
which probably increases the speed if the cache has the entry, because
we avoid the slow IO operation.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This fixes a really ugly bug where the in-memory backend for the store
did not remove the entry from the in-memory hashmap on "move", but
simply copied it from the old location to the new one.
That caused tests to fail after the fixes introduced for the
Store::get() function which checked the filesystem and the internal
cache whether an entry exists before the actual "get" operation, because
an old entry would still exist after a move (only in the testcases).
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
Fixes: 09e8619cf5 ("libimagstore: Move from error-chain to failure")
This changes the implementation of Debug for the FileLockEntry to be
more explanatory of how the entry actually looks like. It does not only
print the path of the store anymore, but also the location of the Entry.
Printing header and content would be still too much, tho.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This way we can control where the input comes from and the output goes
to (like we want to with libimagrt).
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This actually caused an error.
When executing `imag ids --verbose trace` for example, the `imag` binary
got the default value (as in `--verbose info`) supplied from clap. So
far, so good. Problem is that the implementation then forwarded that
flag to `imag-ids`, which resulted in the `--verbose` flag to be passed
_two times_ to `imag-ids`.
Somehow this is really strange, but it does not really matter. First of
all: A default of "Info" is still too high IMO. Default should be
warnings and errors, but no information printed. We like silent tools,
don't we?
Second is that the commandline argument forwarding mechanism of `imag`
is broken and this was a fix which helped debugging of the brokenness,
so this is acutally a step forward in this regard as well.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This feature is required for the `imag` binary. It allows the binary to
use the imag internal logger for logging its own log output.
We need to be able to initialize the logger from an external module (in
all imag modules, the Runtime::new() implementation takes care of this,
but as we cannot use that in the `imag` binary itself, we allow this
method to be public behind a feature flag).
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
When specifying the `--debug` flag on the commandline, logging was not
enabled. That was because the config file parsing did not consider the
args.
Now, if `--debug` is passed on the CLI, logging is enabled for all
modules and level is set to `debug` for all modules.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
for safely creating a `String` object from `StoreId` which can be shown
to the user.
Mainly introduced because this is useful for error handling (when
putting a `StoreId` into an error kind, the compiler complains that
`StoreId` does not meet the required trait bounds. But `String` does and
we do not process the ID any further anyways).
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
The implementation of the in-memory filesystem for testing imag code did
not actually use `HashMap::remove()` when an entry was moved, but
`HashMap::get().cloned()`, which caused the original entry to exist
_after_ the move.
I'm not sure why this did not fail much earlier, but it was clearly
wrong. This commit adjust the test to check the "filesystem" before
checking the store and fixes the bug.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This actually caused tests to fail if there was indeed a file at
/tmp/store/test and the test tried to create a "test" entry in the store.
Do use backend instead to check whether entry actually exists.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
The issue was that the handlebars implementation logs as well and if we
use handlebars in the logger implementation that causes recursion which
crashes the program.
With handlebars 1.0.5, there is a feature[0] to disable logging in
handlebars (compiletime) which we use with this patch. The
exception-checking in the log implementation can be removed therefore.
[0]: https://github.com/sunng87/handlebars-rust/pull/236#issuecomment-427014611
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This reverts commit a1f0872486995b80216e8a08a2176debdef3752a.
As updating handlebars needs some more involvement, we roll back to the
version we use currently and schedule the update for later.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
The previous iterator was implemented to simply fetch _all_ pathes from
the filesystem, no matter what.
With this implementation, this changes. The iterator now has
functionality to optimize the iteration, if only a subdirectory of the
store is required, for example `$STORE/foo`.
This is done via functionality where the underlying iterator gets
altered.
First of all, the interface was changed to return a `Entries` object,
which itself only covers the libimagstore-internal `PathIterator` type.
This type was changed so that the backend implementation provides an
"PathIterBuilder`, which builds the actual iterator object for the
`PathIterator` type.
The intermediate `StoreIdConstructingIterator` was merged into
`PathIterator` for simplicity.
The `Entries` type got functionality similar to the
`StoreIdIteratorWithStore` type for easier transition to the new API.
This should probably be removed at a later point, though.
As the `walkdir::WalkDir` type is not as nice as it could be, iterators
for two collections in the store could be built like this (untested):
store
.entries()?
.in_collection("foo")
.chain(store.entries()?.in_collection("bar"))
Functionality to exclude subdirectories is not possible with the current
`walkdir::WalkDir` implementation and has to be done during iteration,
with filtering (as usual).
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This patch changes the filesystem-backend implementation of libimagstore
to open files on each read/write rather than holding the file handle in
memory at all times.
Whenever a lot of imag store entries are read into memory, the imag
process may ran out of file descriptors. With this patch applied, a
`Store::get()` call on an entry which is not yet in the store cache
would cause the file to be read, but the FD being dropped after that.
Likewise, a `Store::update()` (which is also called if the imag entry is
dropped) would re-open the file on the filesystem and write the contents
from the imag store cache back to the file.
With this patch, opening hundrets or thousands of imag entries should be
no problem anymore, only the available memory should be a limit then.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
This patch fixes a bug we did not even hit (yet). It is: When deleting
an Entry from the store, this could potentially leave artifacts in the
cache.
Szenario: An Entry, which was loaded (via `Store::get()` for example),
gets `Store::delete()`ed twice. The first call would work as expected,
but leave the Entry in the Store cache. The second call would then fail,
as the Entry is already removed on the FS, but still in the cache. This
would fail - which is the right thing to do here - but with the wrong
error (with a FileError rather than a FileNotFound error).
This patch fixes this.
First of all, the appropriate `PathBuf` object is calculated in all
cases, as this object is needed to check whether the file is actually
there (which could be the case if the Entry is in the cache and if it is
not).
If the entry is in the cache and is borrowed: error. If not, remove the
entry from the cache. Afterwards the file is deleted on disk.
If the entry is not in the cache, but the file exists, the file is removed.
If the file does not exist: error.
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
As of rustc 1.26, the `flatten()` method on iterators is preserved by
the rust standard library.
This could cause this code to hard-error some time in the future with
the `flatten()` function actually implemented by the standard library.
Hence we move to use the `Itertools::flatten()` function here
explicitely.