Fix Store::entries() to not yield directories

Before the iterator did also yield storeids for directories, which was a
bug.

This change introduces a new if_file() function in the store-internal
backend, which is needed to check whether a path actually points to a
File, be it inmemory or on the real filesystem.

That's because tests might fail if they check via PathBuf::is_file() as
in tests, the entries only exist inmemory.
This commit is contained in:
Matthias Beyer 2017-10-13 11:58:21 +02:00
parent a24baca779
commit 23f4d7948f
7 changed files with 38 additions and 10 deletions

View file

@ -34,6 +34,10 @@ This section contains the changelog from the last release to the next release.
anymore. This is minor because `libimagentryanntation` is not yet used by
any other crate.
* Bugfixes
* `Store::entries()` does not yield StoreIds which point to directories
anymore, only StoreIds pointing to files.
## 0.4.0
* Major changes

View file

@ -150,6 +150,10 @@ impl FileAbstraction for FSFileAbstraction {
Ok(path.exists())
}
fn is_file(&self, path: &PathBuf) -> Result<bool, SE> {
Ok(path.is_file())
}
fn new_instance(&self, p: PathBuf) -> Box<FileAbstractionInstance> {
Box::new(FSFileAbstractionInstance::Absent(p))
}

View file

@ -159,6 +159,13 @@ impl FileAbstraction for InMemoryFileAbstraction {
Ok(backend.contains_key(pb))
}
fn is_file(&self, pb: &PathBuf) -> Result<bool, SE> {
// Because we only store Entries in the memory-internal backend, we only have to check for
// existance here, as if a path exists in the inmemory storage, it is always mapped to an
// entry. hence it is always a path to a file
self.exists(pb)
}
fn new_instance(&self, p: PathBuf) -> Box<FileAbstractionInstance> {
Box::new(InMemoryFileAbstractionInstance::new(self.backend().clone(), p))
}

View file

@ -44,6 +44,7 @@ pub trait FileAbstraction : Debug {
fn create_dir_all(&self, _: &PathBuf) -> Result<(), SE>;
fn exists(&self, &PathBuf) -> Result<bool, SE>;
fn is_file(&self, &PathBuf) -> Result<bool, SE>;
fn new_instance(&self, p: PathBuf) -> Box<FileAbstractionInstance>;

View file

@ -119,6 +119,10 @@ impl<W: Write, M: Mapper> FileAbstraction for StdIoFileAbstraction<W, M> {
self.0.exists(p)
}
fn is_file(&self, p: &PathBuf) -> Result<bool, SE> {
self.0.is_file(p)
}
fn drain(&self) -> Result<Drain, SE> {
self.0.drain()
}

View file

@ -140,6 +140,10 @@ impl<W: Write, M: Mapper> FileAbstraction for StdoutFileAbstraction<W, M> {
self.mem.exists(p)
}
fn is_file(&self, p: &PathBuf) -> Result<bool, SE> {
self.mem.is_file(p)
}
fn drain(&self) -> Result<Drain, SE> {
self.backend_cloned().map(Drain::new)
}

View file

@ -812,17 +812,21 @@ impl Store {
self.backend
.pathes_recursively(self.path().clone())
.and_then(|iter| {
let iter : Result<Vec<StoreId>> = iter
.map(|path| StoreId::from_full_path(self.path(), path))
.fold(Ok(vec![]), |acc, elem| {
acc.and_then(move |mut a| {
a.push(try!(elem));
Ok(a)
})
});
let mut elems = vec![];
for element in iter {
let is_file = {
let mut base = self.path().clone();
base.push(element.clone());
println!("Checking: {:?}", base);
try!(self.backend.is_file(&base))
};
let iter = try!(iter);
Ok(StoreIdIterator::new(Box::new(iter.into_iter())))
if is_file {
let sid = try!(StoreId::from_full_path(self.path(), element));
elems.push(sid);
}
}
Ok(StoreIdIterator::new(Box::new(elems.into_iter())))
})
}