Browse Source

Test TreeWalker + some fixes.

master
Simon Boyé 2 years ago
parent
commit
2b27b788e5
  1. 203
      Cargo.lock
  2. 3
      libbsv/Cargo.toml
  3. 42
      libbsv/src/ignore.rs
  4. 17
      libbsv/src/lib.rs
  5. 4
      libbsv/src/permissions.rs
  6. 2
      libbsv/src/repository.rs
  7. 2
      libbsv/src/tree_item.rs
  8. 120
      libbsv/src/tree_walker.rs

203
Cargo.lock

@ -17,6 +17,12 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "bitflags"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
[[package]]
name = "block-buffer"
version = "0.9.0"
@ -54,6 +60,15 @@ dependencies = [
"toml",
]
[[package]]
name = "cc"
version = "1.0.82"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "305fe645edc1442a0fa8b6726ba61d422798d37a52e12eaecf4b022ebbb88f01"
dependencies = [
"libc",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -79,24 +94,40 @@ dependencies = [
]
[[package]]
name = "generic-array"
version = "0.14.4"
name = "errno"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f"
dependencies = [
"typenum",
"version_check",
"errno-dragonfly",
"libc",
"windows-sys",
]
[[package]]
name = "getrandom"
version = "0.2.3"
name = "errno-dragonfly"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
dependencies = [
"cfg-if",
"cc",
"libc",
"wasi",
]
[[package]]
name = "fastrand"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
[[package]]
name = "generic-array"
version = "0.14.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817"
dependencies = [
"typenum",
"version_check",
]
[[package]]
@ -107,14 +138,21 @@ dependencies = [
"cas-core",
"cas-simple",
"regex",
"tempfile",
"toml",
]
[[package]]
name = "libc"
version = "0.2.98"
version = "0.2.147"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790"
checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
[[package]]
name = "linux-raw-sys"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503"
[[package]]
name = "memchr"
@ -128,12 +166,6 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "ppv-lite86"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857"
[[package]]
name = "proc-macro2"
version = "1.0.27"
@ -152,53 +184,13 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
dependencies = [
"rand_core",
]
[[package]]
name = "redox_syscall"
version = "0.2.9"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ab49abadf3f9e1c4bc499e8845e152ad87d2ad2d30371841171169e9d75feee"
checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
dependencies = [
"bitflags",
"bitflags 1.2.1",
]
[[package]]
@ -219,12 +211,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
[[package]]
name = "remove_dir_all"
version = "0.5.3"
name = "rustix"
version = "0.38.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
checksum = "19ed4fa021d81c8392ce04db050a3da9a60299050b7ae1cf482d862b54a7218f"
dependencies = [
"winapi",
"bitflags 2.4.0",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
@ -259,16 +255,15 @@ dependencies = [
[[package]]
name = "tempfile"
version = "3.2.0"
version = "3.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
checksum = "dc02fddf48964c42031a0b3fe0428320ecf3a73c401040fc0096f97794310651"
dependencies = [
"cfg-if",
"libc",
"rand",
"fastrand",
"redox_syscall",
"remove_dir_all",
"winapi",
"rustix",
"windows-sys",
]
[[package]]
@ -319,29 +314,67 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
]
[[package]]
name = "winapi"
version = "0.3.9"
name = "windows-targets"
version = "0.48.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
name = "windows_aarch64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
[[package]]
name = "windows_i686_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
[[package]]
name = "windows_i686_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
name = "windows_x86_64_msvc"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"

3
libbsv/Cargo.toml

@ -11,3 +11,6 @@ camino = "1.0.7"
regex = "1.6.0"
cas-core = { path = "../cas-core" }
cas-simple = { path = "../cas-simple" }
[dev-dependencies]
tempfile = "3.7.1"

42
libbsv/src/ignore.rs

@ -14,14 +14,14 @@
// along with bsv. If not, see <https://www.gnu.org/licenses/>.
use camino::{Utf8Path, Utf8PathBuf};
use camino::Utf8Path;
use regex::RegexSet;
use cas_core::{err, Error, Result};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum Action {
pub enum IgnoreAction {
Ignore,
Accept,
}
@ -30,7 +30,7 @@ pub enum Action {
#[derive(Debug)]
pub struct IgnoreRules {
patterns: RegexSet,
actions: Vec<Action>,
actions: Vec<IgnoreAction>,
}
@ -54,7 +54,7 @@ impl IgnoreRules {
};
let mut patterns = Vec::<String>::default();
let mut actions = Vec::<Action>::default();
let mut actions = Vec::<IgnoreAction>::default();
for line in source.lines() {
let rule = line.trim();
@ -65,10 +65,10 @@ impl IgnoreRules {
if rule_it.peek() == Some(&'!') {
rule_it.next();
actions.push(Action::Accept);
actions.push(IgnoreAction::Accept);
}
else {
actions.push(Action::Ignore);
actions.push(IgnoreAction::Ignore);
}
let mut pat = String::new();
@ -125,13 +125,13 @@ impl IgnoreRules {
})
}
pub fn action_for<P: AsRef<Utf8Path>>(&self, path: P) -> Action {
pub fn action_for<P: AsRef<Utf8Path>>(&self, path: P) -> IgnoreAction {
assert!(path.as_ref().is_absolute());
let index = self.patterns.matches(path.as_ref().as_str())
.iter()
.next()
.unwrap_or(self.actions.len());
*self.actions.get(index).unwrap_or(&Action::Accept)
*self.actions.get(index).unwrap_or(&IgnoreAction::Accept)
}
}
@ -139,6 +139,8 @@ impl IgnoreRules {
#[cfg(test)]
mod tests {
use camino::Utf8PathBuf;
use super::*;
#[test]
@ -147,17 +149,17 @@ mod tests {
let patterns = "!hello/world\nhello\n/world/\n\\!\\*\n*.bak";
let ignore = IgnoreRules::from_source(patterns, root).unwrap();
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test")), Action::Accept);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test/hello/aoeu")), Action::Ignore);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test/hello_world/aoeu")), Action::Accept);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test/world/aoeu")), Action::Accept);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test/hello/world/aoeu")), Action::Accept);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/world/aoeu")), Action::Ignore);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/world")), Action::Ignore);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/fooXdir/bar/world")), Action::Accept);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test/!*/aoeu")), Action::Ignore);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test/file.bak")), Action::Ignore);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test/fileXbak")), Action::Accept);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test.bak/file")), Action::Ignore);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test")), IgnoreAction::Accept);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test/hello/aoeu")), IgnoreAction::Ignore);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test/hello_world/aoeu")), IgnoreAction::Accept);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test/world/aoeu")), IgnoreAction::Accept);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test/hello/world/aoeu")), IgnoreAction::Accept);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/world/aoeu")), IgnoreAction::Ignore);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/world")), IgnoreAction::Ignore);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/fooXdir/bar/world")), IgnoreAction::Accept);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test/!*/aoeu")), IgnoreAction::Ignore);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test/file.bak")), IgnoreAction::Ignore);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test/fileXbak")), IgnoreAction::Accept);
assert_eq!(ignore.action_for(Utf8PathBuf::from("/foo.dir/bar/test.bak/file")), IgnoreAction::Ignore);
}
}

17
libbsv/src/lib.rs

@ -18,19 +18,24 @@ extern crate toml;
extern crate camino;
extern crate regex;
#[cfg(test)]
extern crate tempfile;
extern crate cas_core;
mod permissions;
mod tree_item;
mod tree_walker;
// mod config;
mod path_map;
mod ignore;
mod path_map;
mod permissions;
mod repository;
mod tree_item;
mod tree_walker;
pub use crate::ignore::{IgnoreAction, IgnoreRules};
pub use crate::path_map::{PathMap, PathPair};
pub use crate::permissions::Permissions;
pub use crate::repository::Repository;
pub use crate::tree_item::{Serialize, TreeItem};
pub use crate::path_map::{PathMap, PathPair};
pub use crate::repository::{Repository};
pub use crate::tree_walker::{Action, TreeWalker};

4
libbsv/src/permissions.rs

@ -40,9 +40,9 @@ impl Permissions {
use std::os::unix::fs::MetadataExt;
let mode = metadata.mode();
Ok(Self {
read: mode & 0o100 != 0,
read: mode & 0o400 != 0,
write: mode & 0o200 != 0,
execute: mode & 0o400 != 0,
execute: mode & 0o100 != 0,
})
}

2
libbsv/src/repository.rs

@ -18,7 +18,7 @@ use camino::{Utf8Path, Utf8PathBuf};
use toml::Value;
use cas_core::{Cas, err, Error, ObjectId, Result};
use cas_simple::{SimpleCas};
use cas_simple::SimpleCas;
pub use crate::permissions::Permissions;
pub use crate::tree_item::{Serialize, TreeItem};

2
libbsv/src/tree_item.rs

@ -58,7 +58,7 @@ impl TreeItem {
Ok(Self {
name: name,
otype,
size: metadata.len(),
size: if metadata.is_file() { metadata.len() } else { 0 },
created: metadata.created().unwrap_or(UNIX_EPOCH),
modified: metadata.modified().unwrap_or(UNIX_EPOCH),
permissions,

120
libbsv/src/tree_walker.rs

@ -15,14 +15,14 @@
use std::iter::Peekable;
use std::fs::{DirEntry, Metadata, ReadDir, read_dir};
use std::fs::read_dir;
use std::vec::IntoIter;
use camino::{Utf8Path, Utf8PathBuf};
use camino::Utf8Path;
use cas_core::{err, Error, ObjectId, Result};
use cas_core::{Error, ObjectId, Result};
use crate::{PathPair, Repository, TreeItem};
use crate::TreeItem;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -87,13 +87,15 @@ impl Iterator for TreeWalker {
(Some(Ok(curr_item)), Some(prev_item)) => {
if curr_item.name == prev_item.name {
let action =
if curr_item.modified != prev_item.modified {
if curr_item.modified != prev_item.modified
|| curr_item.otype != prev_item.otype
|| curr_item.size != prev_item.size {
Action::Update
}
else {
Action::Skip
};
self.prev_tree_it.next();
self.prev_tree_it.next().unwrap();
Some(Ok((action, self.dir_it.next().unwrap().unwrap())))
}
else if curr_item.name < prev_item.name {
@ -117,15 +119,107 @@ impl Iterator for TreeWalker {
#[cfg(test)]
mod tests {
use std::fs::{create_dir, remove_file as fs_remove_file, write};
use tempfile::tempdir;
use cas_core::ObjectType;
use crate::Permissions;
use super::*;
fn mkdir(root: &Utf8Path, path: &str) -> Result<()> {
let mut full_path = root.to_path_buf();
full_path.push(path);
create_dir(full_path).map_err(|err| err.into())
}
fn write_file(root: &Utf8Path, path: &str, content: &[u8]) -> Result<()> {
let mut full_path = root.to_path_buf();
full_path.push(path);
write(full_path, content).map_err(|err| err.into())
}
fn remove_file(root: &Utf8Path, path: &str) -> Result<()> {
let mut full_path = root.to_path_buf();
full_path.push(path);
fs_remove_file(full_path).map_err(|err| err.into())
}
fn to_tree_items(items: Vec<Result<(Action, TreeItem)>>) -> Vec<TreeItem> {
items.into_iter()
.filter(|ref item| item.as_ref().unwrap().0 != Action::Remove)
.map(|item| item.unwrap().1)
.collect()
}
#[test]
fn test_tree_walker() {
for item in TreeWalker::new("/home/draklaw/tmp", vec![]).unwrap() {
match item {
Ok((action, tree_item)) => println!("{:?} {:?}", action, tree_item.name),
Err(err) => println!("error while iterating directory: {}", err),
}
}
fn test_tree_walker() -> Result<()>{
let root_dir = tempdir()?;
let root = Utf8Path::from_path(root_dir.path()).unwrap();
mkdir(root, "test")?;
write_file(root, "test/foobar.txt", b"baz")?;
write_file(root, "readme", b"hello world!")?;
let items: Vec<_> = TreeWalker::new(root, vec![]).unwrap().collect();
assert_eq!(items.len(), 2);
let (action, item) = items[0].as_ref().unwrap();
assert_eq!(action, &Action::Add);
assert_eq!(item.name, "readme");
assert_eq!(item.otype, ObjectType::new(b"blob").unwrap());
assert_eq!(item.size, 12);
assert_eq!(item.permissions, Permissions{read: true, write: true, execute: false});
let (action, item) = items[1].as_ref().unwrap();
assert_eq!(action, &Action::Add);
assert_eq!(item.name, "test");
assert_eq!(item.otype, ObjectType::new(b"tree").unwrap());
assert_eq!(item.size, 0);
assert_eq!(item.permissions, Permissions{read: true, write: true, execute: true});
write_file(root, "abc", b"xxxx")?;
let items: Vec<_> = TreeWalker::new(root, to_tree_items(items)).unwrap().collect();
assert_eq!(items.len(), 3);
let (action, item) = items[0].as_ref().unwrap();
assert_eq!(action, &Action::Add);
assert_eq!(item.name, "abc");
assert_eq!(item.otype, ObjectType::new(b"blob").unwrap());
assert_eq!(item.size, 4);
assert_eq!(item.permissions, Permissions{read: true, write: true, execute: false});
let (action, item) = items[1].as_ref().unwrap();
assert_eq!(action, &Action::Skip);
assert_eq!(item.name, "readme");
let (action, item) = items[2].as_ref().unwrap();
assert_eq!(action, &Action::Skip);
assert_eq!(item.name, "test");
remove_file(root, "readme")?;
let items: Vec<_> = TreeWalker::new(root, to_tree_items(items)).unwrap().collect();
assert_eq!(items.len(), 3);
let (action, item) = items[0].as_ref().unwrap();
assert_eq!(action, &Action::Skip);
assert_eq!(item.name, "abc");
let (action, item) = items[1].as_ref().unwrap();
assert_eq!(action, &Action::Remove);
assert_eq!(item.name, "readme");
let (action, item) = items[2].as_ref().unwrap();
assert_eq!(action, &Action::Skip);
assert_eq!(item.name, "test");
write_file(root, "abc", b"ab")?;
write_file(root, "test/foobar.txt", b"redacted")?;
let items: Vec<_> = TreeWalker::new(root, to_tree_items(items)).unwrap().collect();
assert_eq!(items.len(), 2);
let (action, item) = items[0].as_ref().unwrap();
assert_eq!(action, &Action::Update);
assert_eq!(item.name, "abc");
assert_eq!(item.size, 2);
let (action, item) = items[1].as_ref().unwrap();
assert_eq!(action, &Action::Skip);
assert_eq!(item.name, "test");
Ok(())
}
}

Loading…
Cancel
Save