Commit graph

320 commits

Author SHA1 Message Date
c2f674cc29 libimagerror: Move from error-chain to failure
Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
2018-10-30 18:46:28 +01:00
c160a967ec Add error kinds 2018-10-30 18:46:28 +01:00
22c13fed42 Fix: --debug on CLI should enable logging and override it
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>
2018-10-26 15:41:00 +02:00
8ec8b0aca7 Hotfix: Ignore code snippet here 2018-10-24 23:46:21 +02:00
d87ea7b305 Add StoreId::local_display_string() function
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>
2018-10-13 11:52:16 +02:00
3090a65446 Add detailed comments on how the logger works 2018-10-11 00:15:48 +02:00
cc11162dd4 Fix: In-Memory filesystem backend did not remove on rename
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>
2018-10-09 17:37:56 +02:00
6751c34f1b Fix: Remove call to deprecated function
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>
2018-10-09 17:37:35 +02:00
1161562372 Remove handlebars exception in log implementation
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>
2018-10-06 12:22:15 +02:00
c162856a21 Update dependencies
regex: 0.2 -> 1
semver: 0.8 -> 0.9
walkdir: 1 -> 2
2018-10-06 12:21:20 +02:00
e34d67d0a1 Update dependency: ansi_term: 0.10 -> 0.11 2018-09-30 15:05:10 +02:00
1c3bc5951f Update dependency: ansi_term: 0.10 -> 0.11 2018-09-30 15:04:51 +02:00
e838f0d0e7 Update dependency: handlebars: 0.29.0 -> 1.0 2018-09-27 15:05:45 +02:00
61738ac9ee Revert "Update dependency: handlebars: 0.29.0 -> 1.0"
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>
2018-09-27 15:05:45 +02:00
abf6a3c384 Update dependency: handlebars: 0.29.0 -> 1.0 2018-09-27 15:05:45 +02:00
3d12998603 Update dependency: toml-query: 0.6 -> 0.7 2018-09-27 15:05:44 +02:00
0a7afee454 Update dependency: error-chain: 0.11 -> 0.12 2018-09-27 15:05:25 +02:00
d4872f6da3 Optimize the Store::entries() interface
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>
2018-09-27 12:19:18 +02:00
d59dca1a23 Add StoreIdIterator::with_store() 2018-09-27 12:19:18 +02:00
8b508fe4c3 Optimize backend impl to not hold open files
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>
2018-08-11 17:50:22 +02:00
aff6ff105d Remove "Header" extension for Value type 2018-07-19 20:58:27 +02:00
f6a7345b4a Simplify: Move header verification from Value extension to Entry type 2018-07-19 20:58:27 +02:00
9ad1c8d6bd Simplify: Move default header generation from Value extension to Entry type 2018-07-19 20:58:27 +02:00
1705ecbbff Fix: Remove (empty) Drop implementation for Store
The StoreEntry drop implementation takes care of unlocking the files.
2018-07-19 20:58:27 +02:00
b774ac0e67 Fix: Deleting an Entry could leave artifacts in cache
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>
2018-07-19 20:58:27 +02:00
9315a23754 Fix: Use backend abstraction for checking whether a path exists 2018-07-19 20:58:27 +02:00
54c5854761 Remove unnecessary call 2018-06-23 21:56:03 +02:00
3bdd5c959b Add documentation to StoreId type 2018-06-23 21:56:03 +02:00
c86e4e7db4 Add documentation for Runtime::init_logger() 2018-06-23 21:56:02 +02:00
8d1022b1ac Fix: Explicitely use Itertools::flatten()
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.
2018-05-11 15:45:42 +02:00
664edc7943 Update version string: 0.8.0 -> 0.9.0 2018-05-09 11:39:33 +02:00
c65a3d1af9 Add CLI validators in default CLI setup 2018-05-04 11:21:49 +02:00
9bf3f6da1b Update help 2018-05-04 11:20:09 +02:00
23c3a4b863 Update help, clap does the rest here 2018-05-04 11:19:47 +02:00
eb20a9d881
Merge pull request #1477 from matthiasbeyer/libimagstore/remove-walk
Remove Store::walk()
2018-05-02 18:39:11 +02:00
258d9f90d3 Remove Store::walk()
This patch removes the Store::walk() interface.

It was cumbersome and unused anyways.
2018-05-02 17:46:45 +02:00
888b31377e Fix: Do not check whether path exists - check whether its a file
This fixes a bug introduced in 195d921218
where we didn't check whether the path is actually a file.
2018-05-02 14:04:59 +02:00
2bf09e7737 Only create directory if it does not exist 2018-05-01 22:29:46 +02:00
b27b392f4b Add trace output 2018-05-01 22:29:46 +02:00
972327e35e Remove Store::reset_backend() 2018-05-01 21:09:51 +02:00
2f0a557068 Fix for passing Arc<_> to store interface instead of Box<_> 2018-05-01 21:08:57 +02:00
42e2f18fb3 Pass around Arc<FileAbstraction> internally
Because the iterators need to be able to check whether the file exists
_in the backend_ (not on disk, but in the backend, because of in-memory
test for example), we need to be able to pass the backend to the
iterator intermediate type.

This patch implements this. It does so by changing the internal backend
member of the store from `Box<FileAbstraction>` to
`Arc<FileAbstraction>`, which gives us the ability to clone the
reference to the backend easily without needing to rely on lifetimes
here, because of the Arc.

Also, less boxes are always good.
2018-05-01 21:08:57 +02:00
d08c27e623 Rewrite StoreIdIterator extensions
This patch reimplements the iterator extensions.

As we iterate (in StoreIdIterator) over Result<StoreId> now anyways, we
don't need the extensions for Result iterators anymore.

This patch rewrites the extensions to be more simple in every way and
generic over the error type in the iterator.
All the errors have to do is implement From<StoreError>, which is what
they do when linking the generated error types with error_chain to the
libimagstore error types.
2018-05-01 17:44:01 +02:00
a2ff298e67 Rewrite Store::entries()
This patch rewrites the Store::entries() function to not be collecting
the iterator.

It therefore introduces a new, internal, iterator type which creates the
StoreId objects from the pathes the PathIterator yields internally.

With this patch, the Store iterator interface changes, as the iterators
now yield `Result<StoreId, StoreError>` instead of `StoreId`.
This is necessary, as the internal conversion errors shouldn't be
hidden.

Of course, the iterator types (like the StoreGetIterator and so on)
should hold a Result<StoreId> internally as well, and also yield
appropritely. This was changed in this commit, too.
2018-05-01 17:44:00 +02:00
f4556f3983 Rewrite backend to not collect on pathes_recursively() 2018-05-01 17:44:00 +02:00
900d9f0984
Merge pull request #1474 from matthiasbeyer/libimagstore/cache-flush
Add functionality to flush the internal cache
2018-04-30 21:07:37 +02:00
6a5bcb2709 Remove unused error kinds 2018-04-30 18:54:11 +02:00
6a40ac6b98 Add information about which storeid is the cause of the error in errors 2018-04-30 18:53:54 +02:00
860e47a256 Add functionality to flush the internal cache
Before we had the problem that when iterating over _a lot_ (like 5k)
entries and also fetching them, at some point the OS would return with
"Too many files open".

That is because the store internally caches a lot.

With this change, the Store gets an API to query how big the cache is,
how much the cache can currently hold and (and that's the main thing in
this patch) to flush the cache to disk.

A function to simply ask the store whether its cache should be flushed
(which would us require to ask the OS how many files we can open...
which would be possible with `libc::getrlimit`) does not yet exist,
though, but could be added easily if desired.
2018-04-30 18:39:59 +02:00
ea80a5a09b Derive Default for InMemoryFileAbstraction, remove constructor 2018-04-25 19:15:07 +02:00
6a34e7a8fd Derive Default for FSFileAbstraction, reduces boilerplate 2018-04-25 19:15:07 +02:00
bf363c4748 Use "if let" if matching on a single pattern 2018-04-25 19:15:07 +02:00
f1142c414d Use ok_or_else() instead of ok_or() 2018-04-25 19:15:07 +02:00
22170a0d55 Do not String::from(String) 2018-04-25 19:13:51 +02:00
6f5590713a Use single quotes here 2018-04-25 19:13:51 +02:00
44521a7c8c Dont use "return" keyword at end of function 2018-04-25 19:13:51 +02:00
dc18e650bb Collapse nested if-else-if 2018-04-25 19:13:51 +02:00
a25f650ca0 Be more ergonomic here 2018-04-25 19:13:51 +02:00
84249e3fb5 Be less verbose when constructing an object
The rust compiler does some fancy things for us: It automatically finds
the right fields if the name of the variable and the file is the same.

Lets use that to reduce boilerplate with this patch.
2018-04-25 19:13:50 +02:00
154c2e482b Change generate_variants() helper to use base by ref 2018-04-25 19:13:50 +02:00
524c391ee0 Remove unused dependency 2018-04-24 22:16:40 +02:00
563c76c375 Remove "stdio" file abstraction from store implementation 2018-04-24 22:16:40 +02:00
19e0471f5b Remove tests with JsonMapper in backend 2018-04-24 22:16:40 +02:00
ba453323ba Remove support for changing store backend 2018-04-24 22:16:40 +02:00
bae9188a08 Remove GlobStoreIdIterator helper iterator type 2018-04-24 13:40:42 +02:00
d70092d691 Remove: Store::retrieve_for_module 2018-04-24 13:40:42 +02:00
19940d3e1c Set version string by hand here if we do not build with cargo 2018-04-22 13:38:24 +02:00
8262de29fe Update dependency: log: 0.4.0-rc.1 -> 0.4 2018-04-20 20:19:02 +02:00
808689cc05 Suggest imag-init if no config is found 2018-04-19 10:57:13 +02:00
d2dceb6640 Update version numbers: 0.7.0 -> 0.8.0 2018-04-19 10:05:53 +02:00
38726c5906 Always use stdout via output proxy
The switching between stdout and stderr on an automated basis caused
errors in the using code, where output was redirected but shouldn't.
2018-04-18 17:58:07 +02:00
542c7e7101 Make stdin always available
Because we do not implement the store piping and pipe magic, the stdin
stream should always be available.
2018-04-18 17:42:04 +02:00
4568b1f625
Merge pull request #1380 from matthiasbeyer/minor
Minor patches
2018-04-18 16:46:41 +02:00
88b57910df
Merge pull request #1403 from matthiasbeyer/remove-pipe-magic
Revert "Implement pipe magic in libimagrt"
2018-04-17 17:39:54 +02:00
98f8366e4c Fix documentation in crate metadata 2018-04-17 15:55:08 +02:00
d7cfab797f Revert "Implement pipe magic in libimagrt"
This reverts commit ce0bd9298a.

Pipe magic is removed with this patch.

We remove pipe magic because its implementation in libimagstore is too
complicated and the benefits are too small.
Having this functionality would be really nice, but the cost-benefit
ratio would still be too high.
The implementation in the store would require a rewrite of the internal
caching functionality in the store, plus some functionality to serialize
and deserialize the cache. This is theoretically possible, but as the
store only knows about "StoreEntry" objects, and only the backend knows
of "Entry" (which would be simply de/serializeable), the complexity
increases a _lot_.

Hence, we drop this feature-idea here.

Maybe, at some later point, this functionality will be in imag. The
history of development of this feature is in the history, we just don't
have it merged.

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
2018-04-16 13:30:59 +02:00
0f19b7e4b2 Use --verbose with "info" level by default 2018-04-15 08:38:11 +02:00
c0607ba2e2 Fix log level setting in runtime
Do not immediately set log level to Level::Info if argument is present,
but check value, too.
2018-04-14 21:27:16 +02:00
604f350340 Add logging in store 2018-04-14 16:55:36 +02:00
fb4917d050 Remove feature to generate commandline completion scripts 2018-04-14 14:35:28 +02:00
aeec10bf76 Use clap with wrap_help feature 2018-04-13 16:19:10 +02:00
b59c234588 Use clap "^2.29" instead of ">=2.29" 2018-04-13 16:17:43 +02:00
c27dc79afe
Merge pull request #1383 from matthiasbeyer/libimagrt/handler-exit-if-subcommand-not-found
libimagrt: Exit if handler does not find subcommand
2018-04-08 22:21:19 +02:00
16a76f6213 Exit if handler does not find subcommand 2018-04-08 20:38:46 +02:00
c5c9c7b9ba Fix: Editor commands should be split at whitespace
This fixes the following problem:

If the editor setting was "vim " instead of "vim", the editor was called
with `"vim" " "`, which resulted in unexpected behaviour.

The patch fixes this.
2018-04-08 20:28:11 +02:00
a769186cd7 Make iterator lifetimes less restricting 2018-04-07 13:55:54 +02:00
93195b3bad Default clap app builder: Allow external subcommands 2018-04-04 19:34:13 +02:00
cb8b5a0cf6 Add helper for handling unknown subcommands 2018-04-03 18:23:01 +02:00
e61ccc9561 Fix: Entry::to_str() should return Result<_>
Because serializing might fail.

Also fixes all usages of the API.
2018-03-26 14:24:42 +02:00
ea38f2ffbf Fix: Pass /dev/tty as stdin for editor
This fixes the issue that spawning the editor trashes the terminal.

The signature of the Runtime::editor() function changed, which has to be
fixed in using code.
2018-03-23 23:55:06 +01:00
9e0d0d9f6c Add Entry::replace_from_buffer() 2018-03-23 15:44:34 +01:00
7e623f39b8 Add message why panic
So we see that when grepping the source for `unimplemented!()`.
2018-03-23 10:05:58 +01:00
41f7bab1c5 Fix: Store::create() should fail if the entry exists 2018-03-22 21:16:11 +01:00
a23afa7772 Ensure command and args are provided correctly 2018-03-13 08:32:40 +01:00
b8c3f7f834 Read editor from configuration, ignore errors 2018-03-13 08:32:40 +01:00
43a3f4a5db Fix editor command
do inherit stdin and stderr from parent process, to not break terminal
editors when editing stuff.

vim printed "Input not from terminal" warning messages. This was fixed
by this commit.
2018-03-12 20:08:10 +01:00
68ace5d147 Fix typo 2018-03-12 13:32:23 +01:00
d3b38b5a90
Merge pull request #1330 from matthiasbeyer/libimagrt/pipe-magic
Implement pipe magic in libimagrt
2018-03-10 16:20:36 +01:00
ce0bd9298a Implement pipe magic in libimagrt
When we merged the changes in libimagrt so that it automatically detects
whether stdin/stdout is a TTY and provides the user with stderr in case
stdout is not a TTY, we forgot that things like

    imag foo | grep bar

becomes impossible with that, because imag detects that stdout is not a
tty and automatically uses stderr for output.

But in this case, we don't want that. The output has to be stdout in
this case.

With this change, we have a flag in the runtime ("--pipe-magic" or "-P",
globally available) which turns on "pipe magic".

The expected behaviour is the following, if "-P" is passed:

* If stdout is a TTY, we print to stdout
* If stdout is not a TTY, we print to stderr
* If stdin is not a TTY, we do not provide it

If "-P" is not passed, we allow the user of libimagrt to use stdin for
interactive stuff (the interactive stuff is not yet implemented).

Signed-off-by: Matthias Beyer <mail@beyermatthias.de>
2018-03-10 15:43:44 +01:00
da408b9e67 This fixes the file parsing (again)
Unfortunately, our latest fix to file parsing did not solve all issues.
So we have to fix it _again_.

The problem was the `std::str::Lines` iterator, which apparently fails
this:

    assert_eq!(1, "".lines().count());

as an empty line seems not to be a line.

Because of that, when reading a file with an empty line at its bottom
got stripped off that line.

This patch removes the use of the `lines()` iterator and uses
`split("\n")` instead. This only works on Unix operating systems, but as
we only target unix operating systems with imag, this is not considered
an issue right now.

This patch also adds extensive tests on multiple levels in the
`libimagstore` implementation:

* On the parsing level, for the function which implements the parsing
* On the filesystem abstraction levels
* On the `Store` levels

to make sure that everything is parsed correctly.
2018-03-10 14:53:15 +01:00