status test for differences works
This commit is contained in:
parent
709f0f3b84
commit
4d390b131e
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@ target
|
|||||||
todo
|
todo
|
||||||
.nextsync
|
.nextsync
|
||||||
.nextsyncignore
|
.nextsyncignore
|
||||||
|
test
|
||||||
|
100
Cargo.lock
generated
100
Cargo.lock
generated
@ -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"
|
||||||
|
@ -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"
|
||||||
|
@ -1 +1,2 @@
|
|||||||
pub mod init;
|
pub mod init;
|
||||||
|
pub mod status;
|
||||||
|
@ -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
141
src/commands/status.rs
Normal 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"]);
|
||||||
|
}
|
||||||
|
}
|
@ -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 {
|
||||||
|
Loading…
Reference in New Issue
Block a user