status test for differences works

This commit is contained in:
grimhilt 2023-06-01 20:41:54 +02:00
parent 709f0f3b84
commit 4d390b131e
7 changed files with 256 additions and 3 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@ target
todo todo
.nextsync .nextsync
.nextsyncignore .nextsyncignore
test

100
Cargo.lock generated
View File

@ -170,6 +170,12 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
[[package]] [[package]]
name = "futures-channel" name = "futures-channel"
version = "0.3.28" version = "0.3.28"
@ -218,6 +224,12 @@ dependencies = [
"slab", "slab",
] ]
[[package]]
name = "gcc"
version = "0.3.55"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
[[package]] [[package]]
name = "h2" name = "h2"
version = "0.3.19" version = "0.3.19"
@ -462,7 +474,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eebffdb73fe72e917997fad08bdbf31ac50b0fa91cec93e69a0662e4264d454c" checksum = "eebffdb73fe72e917997fad08bdbf31ac50b0fa91cec93e69a0662e4264d454c"
dependencies = [ dependencies = [
"libc", "libc",
"wasi", "wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
@ -485,12 +497,13 @@ dependencies = [
] ]
[[package]] [[package]]
name = "next-sync" name = "nextsync"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"clap", "clap",
"dotenv", "dotenv",
"reqwest", "reqwest",
"rust-crypto",
"tokio", "tokio",
] ]
@ -619,6 +632,53 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rand"
version = "0.3.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c"
dependencies = [
"libc",
"rand 0.4.6",
]
[[package]]
name = "rand"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
dependencies = [
"fuchsia-cprng",
"libc",
"rand_core 0.3.1",
"rdrand",
"winapi",
]
[[package]]
name = "rand_core"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
dependencies = [
"rand_core 0.4.2",
]
[[package]]
name = "rand_core"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
[[package]]
name = "rdrand"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
dependencies = [
"rand_core 0.3.1",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.2.16" version = "0.2.16"
@ -675,6 +735,25 @@ dependencies = [
"winreg", "winreg",
] ]
[[package]]
name = "rust-crypto"
version = "0.2.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
dependencies = [
"gcc",
"libc",
"rand 0.3.23",
"rustc-serialize",
"time",
]
[[package]]
name = "rustc-serialize"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.37.19" version = "0.37.19"
@ -835,6 +914,17 @@ dependencies = [
"unicode-width", "unicode-width",
] ]
[[package]]
name = "time"
version = "0.1.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
dependencies = [
"libc",
"wasi 0.10.0+wasi-snapshot-preview1",
"winapi",
]
[[package]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.6.0" version = "1.6.0"
@ -1011,6 +1101,12 @@ dependencies = [
"try-lock", "try-lock",
] ]
[[package]]
name = "wasi"
version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]] [[package]]
name = "wasi" name = "wasi"
version = "0.11.0+wasi-snapshot-preview1" version = "0.11.0+wasi-snapshot-preview1"

View File

@ -1,5 +1,5 @@
[package] [package]
name = "next-sync" name = "nextsync"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
@ -10,3 +10,4 @@ reqwest = { version = "0.11", features = ["blocking", "json", "multipart"] }
tokio = { version = "1", features = ["full"] } tokio = { version = "1", features = ["full"] }
dotenv ="0.15.0" dotenv ="0.15.0"
clap = "2.33" clap = "2.33"
rust-crypto = "0.2.36"

View File

@ -1 +1,2 @@
pub mod init; pub mod init;
pub mod status;

View File

@ -4,12 +4,21 @@ use std::env;
pub fn init() { pub fn init() {
let builder = DirBuilder::new(); let builder = DirBuilder::new();
let mut path = env::current_dir().unwrap(); let mut path = env::current_dir().unwrap();
// .nextsync folder
path.push(".nextsync"); path.push(".nextsync");
match builder.create(path.clone()) { match builder.create(path.clone()) {
Ok(()) => println!("Directory successfuly created"), Ok(()) => println!("Directory successfuly created"),
Err(_) => println!("Error: cannot create directory"), Err(_) => println!("Error: cannot create directory"),
} }
path.push("HEAD");
match File::create(path.clone()) {
Ok(_) => println!("File successfuly created"),
Err(_) => println!("Error: cannot create .nextsyncignore"),
}
path.pop();
path.pop(); path.pop();
path.push(".nextsyncignore"); path.push(".nextsyncignore");
@ -17,4 +26,5 @@ pub fn init() {
Ok(_) => println!("File successfuly created"), Ok(_) => println!("File successfuly created"),
Err(_) => println!("Error: cannot create .nextsyncignore"), Err(_) => println!("Error: cannot create .nextsyncignore"),
} }
} }

141
src/commands/status.rs Normal file
View File

@ -0,0 +1,141 @@
use std::env;
use std::path::Path;
use std::fs::File;
use std::io::{self, BufRead};
use std::path::PathBuf;
use crypto::digest::Digest;
use crypto::sha1::Sha1;
use std::collections::HashSet;
pub fn status() {
let mut a = vec![];
{
let b = 2;
a.push(b.clone());
}
println!("Vector a: {:?}", a);
let mut new_files: Vec<PathBuf> = Vec::new();
let mut hashes = HashSet::new();
let mut objects: Vec<&str> = vec![];
let path = env::current_dir().unwrap();
let mut next_sync_path = path.clone();
next_sync_path.push(".nextsync");
if let Ok(lines) = read_head(next_sync_path.clone()) {
for line in lines {
if let Ok(ip) = line {
hashes.insert(String::from(ip).as_str());
}
}
}
if let Ok(entries) = read_folder(path.clone()) {
for entry in entries {
if !is_nextsync_config(entry.clone()) {
let object_path = entry.strip_prefix(path.clone()).unwrap();
objects.push(object_path.to_str().unwrap().clone());
}
}
}
find_missing_elements(&mut hashes, &mut objects);
dbg!(hashes);
dbg!(objects);
}
fn find_missing_elements(hashes: &mut HashSet<&str>, objects: &mut Vec<&str>) {
let mut hasher = Sha1::new();
let mut to_remove: Vec<usize> = vec![];
let mut i = 0;
for object in &mut *objects {
// hash the object
hasher.input_str(object);
let hash = hasher.result_str();
hasher.reset();
// find it on the list of hashes
if hashes.contains(hash.as_str()) {
hashes.remove(hash.as_str());
to_remove.push(i);
}
i += 1;
}
// remove all objects existing in the list of hashes
i = 0;
for index in to_remove {
objects.remove(index-i);
i += 1;
}
}
fn is_nextsync_config(path: PathBuf) -> bool {
path.ends_with(".nextsync") || path.ends_with(".nextsyncignore")
}
fn read_head(mut path: PathBuf) -> io::Result<io::Lines<io::BufReader<File>>> {
path.push("HEAD");
read_lines(path)
}
use std::fs;
fn read_folder(path: PathBuf) -> io::Result<Vec<PathBuf>> {
let mut entries = fs::read_dir(path)?
.map(|res| res.map(|e| e.path()))
.collect::<Result<Vec<_>, io::Error>>()?;
entries.sort();
Ok(entries)
}
// The output is wrapped in a Result to allow matching on errors
// Returns an Iterator to the Reader of the lines of the file.
fn read_lines<P>(filename: P) -> io::Result<io::Lines<io::BufReader<File>>>
where P: AsRef<Path>, {
let file = File::open(filename)?;
Ok(io::BufReader::new(file).lines())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_find_missing_elements() {
let mut hasher = Sha1::new();
hasher.input_str("file1");
let hash1 = hasher.result_str();
hasher.reset();
let mut hasher = Sha1::new();
hasher.input_str("file2");
let hash2 = hasher.result_str();
hasher.reset();
let mut hasher = Sha1::new();
hasher.input_str("file4");
let hash4 = hasher.result_str();
hasher.reset();
let mut hashes = HashSet::new();
hashes.insert(hash1.as_str());
hashes.insert(hash2.as_str());
hashes.insert(hash4.as_str());
let mut objects: Vec<&str> = vec![];
objects.push("file1");
objects.push("file2");
objects.push("file3");
find_missing_elements(&mut hashes, &mut objects);
dbg!(hashes.clone());
dbg!(objects.clone());
assert_eq!(hashes.contains(hash4.as_str()), true);
assert_eq!(hashes.len(), 1);
assert_eq!(objects, vec!["file3"]);
}
}

View File

@ -14,10 +14,13 @@ fn main() {
.author("grimhilt") .author("grimhilt")
.about("") .about("")
.subcommand(SubCommand::with_name("init")) .subcommand(SubCommand::with_name("init"))
.subcommand(SubCommand::with_name("status"))
.get_matches(); .get_matches();
if let Some(_) = matches.subcommand_matches("init") { if let Some(_) = matches.subcommand_matches("init") {
commands::init::init(); commands::init::init();
} else if let Some(_) = matches.subcommand_matches("status") {
commands::status::status();
} }
//tokio::runtime::Runtime::new().unwrap().block_on(async { //tokio::runtime::Runtime::new().unwrap().block_on(async {