started working on better versions and index persistence
This commit is contained in:
parent
0c715852d6
commit
1464cd26c8
7 changed files with 156 additions and 13 deletions
76
Cargo.lock
generated
76
Cargo.lock
generated
|
@ -28,10 +28,35 @@ dependencies = [
|
|||
"rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_cbor 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.2"
|
||||
|
@ -56,6 +81,14 @@ name = "cfg-if"
|
|||
version = "0.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "failure"
|
||||
version = "0.1.5"
|
||||
|
@ -76,6 +109,11 @@ dependencies = [
|
|||
"synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
|
@ -86,6 +124,14 @@ name = "gcc"
|
|||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.11"
|
||||
|
@ -111,6 +157,11 @@ name = "libc"
|
|||
version = "0.2.62"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.5"
|
||||
|
@ -298,6 +349,17 @@ dependencies = [
|
|||
"syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "0.15.44"
|
||||
|
@ -352,6 +414,11 @@ dependencies = [
|
|||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.1.0"
|
||||
|
@ -407,18 +474,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
[metadata]
|
||||
"checksum backtrace 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "1371048253fa3bac6704bfd6bbfc922ee9bdcee8881330d40f308b81cc5adc55"
|
||||
"checksum backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "82a830b4ef2d1124a711c71d263c5abdc710ef8e907bd508c88be475cebc422b"
|
||||
"checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
"checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09"
|
||||
"checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||
"checksum c2-chacha 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7d64d04786e0f528460fc884753cf8dddcc466be308f6026f8e355c41a0e4101"
|
||||
"checksum cc 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "8dae9c4b8fedcae85592ba623c4fd08cfdab3e3b72d6df780c6ead964a69bfff"
|
||||
"checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33"
|
||||
"checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
"checksum failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "795bd83d3abeb9220f257e597aa0080a508b27533824adf336529648f6abf7e2"
|
||||
"checksum failure_derive 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ea1063915fd7ef4309e222a5a07cf9c319fb9c7836b1f89b85458672dbb127e1"
|
||||
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
"checksum gcc 0.3.55 (registry+https://github.com/rust-lang/crates.io-index)" = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
|
||||
"checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec"
|
||||
"checksum getrandom 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "fc344b02d3868feb131e8b5fe2b9b0a1cc42942679af493061fc13b853243872"
|
||||
"checksum half 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9353c2a89d550b58fa0061d8ed8d002a7d8cdf2494eb0e432859bd3a9e543836"
|
||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba"
|
||||
"checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
"checksum ppv-lite86 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e3cbf9f658cdb5000fcf6f362b8ea2ba154b9f146a61c7a20d647034c6b6561b"
|
||||
"checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
|
||||
"checksum proc-macro2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "175a40b9cf564ce9bf050654633dbf339978706b8ead1a907bb970b63185dd95"
|
||||
|
@ -442,11 +516,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "fec2851eb56d010dc9a21b89ca53ee75e6528bab60c11e89d38390904982da9f"
|
||||
"checksum serde_cbor 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "318690c4f04ae6553665f3846c0614c9995bb1ea51a2f1c5c4b4ed338c248b49"
|
||||
"checksum serde_derive 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)" = "cb4dc18c61206b08dc98216c98faa0232f4337e1e1b8574551d5bad29ea1b425"
|
||||
"checksum sha2 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b4d8bfd0e469f417657573d8451fb33d16cfe0989359b93baf3a1ffc639543d"
|
||||
"checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5"
|
||||
"checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf"
|
||||
"checksum synstructure 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "02353edf96d6e4dc81aea2d8490a7e9db177bf8acb0e951c24940bf866cb313f"
|
||||
"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
|
||||
"checksum time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "db8dcfca086c1143c9270ac42a2bbd8a7ee477b78ac8e45b19abfb0cbede4b6f"
|
||||
"checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9"
|
||||
"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
|
||||
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"
|
||||
|
|
|
@ -12,3 +12,4 @@ serde = { version = "1.0", features = ["derive"] }
|
|||
serde_cbor = "0.10"
|
||||
tempfile = "3.1"
|
||||
walkdir = "2.2"
|
||||
sha2 = "0.8"
|
||||
|
|
|
@ -8,6 +8,7 @@ use crate::repository_item::RepositoryItem;
|
|||
pub struct IndexItem {
|
||||
relative_path: String,
|
||||
original_source_path: String,
|
||||
version: Box<[u8]>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
|
@ -56,7 +57,7 @@ impl Index {
|
|||
let original_source_path = Path::new(index_item.original_source_path.as_str());
|
||||
let absolute_path = repository_path.join(relative_path);
|
||||
let absolute_path = absolute_path.as_path();
|
||||
RepositoryItem::from(original_source_path, absolute_path, relative_path)
|
||||
RepositoryItem::from(original_source_path, absolute_path, relative_path, index_item.version)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -65,6 +66,7 @@ impl From<RepositoryItem> for IndexItem {
|
|||
IndexItem {
|
||||
relative_path: i.relative_path().to_string_lossy().to_string(),
|
||||
original_source_path: i.original_source_path().to_string_lossy().to_string(),
|
||||
version: i.version(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
pub mod backup;
|
||||
pub mod error;
|
||||
pub mod repository;
|
||||
pub mod restore;
|
||||
pub mod source;
|
||||
|
||||
mod index;
|
||||
pub mod repository;
|
||||
mod repository_item;
|
||||
|
|
|
@ -4,7 +4,10 @@ use std::path::Path;
|
|||
use crate::error::BakareError;
|
||||
use crate::index::{Index, IndexIterator};
|
||||
use crate::repository_item::RepositoryItem;
|
||||
use sha2::Digest;
|
||||
use sha2::Sha512;
|
||||
use std::fs::File;
|
||||
use std::io::{BufReader, Read};
|
||||
|
||||
/// represents a place where backup is stored an can be restored from.
|
||||
/// right now only on-disk directory storage is supported
|
||||
|
@ -66,20 +69,41 @@ impl<'a> Repository<'a> {
|
|||
if source_path.is_dir() {
|
||||
fs::create_dir(destination_path)?;
|
||||
}
|
||||
|
||||
if source_path.is_file() {
|
||||
println!("storing {} as {}", source_path.display(), destination_path.display());
|
||||
fs::create_dir_all(destination_path.parent().unwrap())?;
|
||||
let version = Repository::calculate_initial_version(source_path)?;
|
||||
fs::copy(source_path, destination_path)?;
|
||||
|
||||
self.index.remember(RepositoryItem::from(
|
||||
source_path,
|
||||
destination_path,
|
||||
destination_path.strip_prefix(self.path)?,
|
||||
Box::from(version),
|
||||
));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn calculate_initial_version(source_path: &Path) -> Result<Box<[u8]>, BakareError> {
|
||||
let source_file = File::open(source_path)?;
|
||||
let mut reader = BufReader::new(source_file);
|
||||
let mut buffer = Vec::with_capacity(1024);
|
||||
let mut hasher = Sha512::new();
|
||||
|
||||
loop {
|
||||
let count = reader.read(&mut buffer)?;
|
||||
if count == 0 {
|
||||
break;
|
||||
}
|
||||
hasher.input(&buffer);
|
||||
}
|
||||
|
||||
let version = hasher.result();
|
||||
Ok(Box::from(version.as_slice()))
|
||||
}
|
||||
|
||||
pub fn item_by_source_path(&self, path: &Path) -> Result<Option<RepositoryItem>, BakareError> {
|
||||
println!(
|
||||
"trying to find {} in a repo [{}] of {} items",
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
use crate::error::BakareError;
|
||||
use sha2::digest::DynDigest;
|
||||
use sha2::{Digest, Sha512};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
|
@ -7,14 +9,16 @@ pub struct RepositoryItem {
|
|||
relative_path: Box<Path>,
|
||||
absolute_path: Box<Path>,
|
||||
original_source_path: Box<Path>,
|
||||
version: Box<[u8]>,
|
||||
}
|
||||
|
||||
impl RepositoryItem {
|
||||
pub fn from(original_source_path: &Path, absolute_path: &Path, relative_path: &Path) -> Self {
|
||||
pub fn from(original_source_path: &Path, absolute_path: &Path, relative_path: &Path, version: Box<[u8]>) -> Self {
|
||||
RepositoryItem {
|
||||
relative_path: Box::from(relative_path),
|
||||
absolute_path: Box::from(absolute_path),
|
||||
original_source_path: Box::from(original_source_path),
|
||||
version,
|
||||
}
|
||||
}
|
||||
pub fn save(&self, save_to: &Path) -> Result<(), BakareError> {
|
||||
|
@ -44,4 +48,8 @@ impl RepositoryItem {
|
|||
pub fn original_source_path(&self) -> &Path {
|
||||
&self.original_source_path
|
||||
}
|
||||
|
||||
pub fn version(&self) -> Box<[u8]> {
|
||||
self.version.clone()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ use bakare::source::TempSource;
|
|||
|
||||
use bakare::error::BakareError;
|
||||
use bakare::repository::Repository;
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::path::Path;
|
||||
|
@ -12,7 +13,7 @@ use tempfile::tempdir;
|
|||
use walkdir::WalkDir;
|
||||
|
||||
#[test]
|
||||
fn restore_backed_up_files() -> Result<(), BakareError> {
|
||||
fn restore_multiple_files() -> Result<(), BakareError> {
|
||||
let source = TempSource::new()?;
|
||||
|
||||
source.write_text_to_file("first", "some contents")?;
|
||||
|
@ -22,17 +23,44 @@ fn restore_backed_up_files() -> Result<(), BakareError> {
|
|||
assert_same_after_restore(source.path())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn restore_files_after_reopening_repository() -> Result<(), BakareError> {
|
||||
let source = TempSource::new()?;
|
||||
let repository_path = tempdir()?.into_path();
|
||||
let restore_target = tempdir()?.into_path();
|
||||
Repository::init(repository_path.as_path())?;
|
||||
|
||||
let relative_path_text = "some file path";
|
||||
let original_contents = "some old contents";
|
||||
|
||||
{
|
||||
let mut backup_repository = Repository::open(repository_path.as_path())?;
|
||||
let mut backup_engine = backup::Engine::new(source.path(), &mut backup_repository);
|
||||
source.write_text_to_file(relative_path_text, original_contents)?;
|
||||
backup_engine.backup()?;
|
||||
}
|
||||
|
||||
{
|
||||
let restore_repository = Repository::open(repository_path.as_path())?;
|
||||
let restore_engine = restore::Engine::new(&restore_repository, &restore_target)?;
|
||||
restore_engine.restore_all()?;
|
||||
}
|
||||
|
||||
let restored_file_path = restore_target.join(relative_path_text);
|
||||
let contents = fs::read_to_string(restored_file_path)?;
|
||||
|
||||
assert_eq!(contents, original_contents);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn restore_older_version_of_file() -> Result<(), BakareError> {
|
||||
let source = TempSource::new()?;
|
||||
let repository_path = tempdir()?.into_path();
|
||||
//let restore_repository = Repository::open(repository_path.as_path())?;
|
||||
Repository::init(repository_path.as_path())?;
|
||||
|
||||
let relative_path_text = "some path";
|
||||
let file_path = source.file_path(relative_path_text);
|
||||
let new_contents = "totally new contents";
|
||||
let restore_target = tempdir()?;
|
||||
//let restore_engine = restore::Engine::new(&restore_repository, &restore_target.path())?;
|
||||
let old_contents = "some old contents";
|
||||
|
||||
{
|
||||
|
@ -43,19 +71,23 @@ fn restore_older_version_of_file() -> Result<(), BakareError> {
|
|||
}
|
||||
|
||||
let reading_repository = Repository::open(repository_path.as_path())?;
|
||||
let file_id = reading_repository.item_by_source_path(&file_path)?;
|
||||
assert!(file_id.is_some());
|
||||
//let file_id = file_id.unwrap();
|
||||
//let old_version = file_id.version();
|
||||
let item = reading_repository.item_by_source_path(&file_path)?;
|
||||
assert!(item.is_some());
|
||||
let item = item.unwrap();
|
||||
let old_version = item.version();
|
||||
|
||||
{
|
||||
let new_contents = "totally new contents";
|
||||
let mut backup_repository = Repository::open(repository_path.as_path())?;
|
||||
let mut backup_engine = backup::Engine::new(source.path(), &mut backup_repository);
|
||||
source.write_text_to_file(relative_path_text, new_contents)?;
|
||||
backup_engine.backup()?;
|
||||
}
|
||||
|
||||
//restore_engine.restore_as_of_version(&file_id, old_version)?;
|
||||
let restore_repository = Repository::open(repository_path.as_path())?;
|
||||
let restore_target = tempdir()?;
|
||||
let restore_engine = restore::Engine::new(&restore_repository, &restore_target.path())?;
|
||||
//restore_engine.restore_as_of_version(&item, old_version)?;
|
||||
|
||||
assert_target_file_contents(restore_target.path(), relative_path_text, old_contents)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue