diff --git a/src/commands/status.rs b/src/commands/status.rs index 02776e1..db82329 100644 --- a/src/commands/status.rs +++ b/src/commands/status.rs @@ -4,6 +4,7 @@ use crypto::sha1::Sha1; use std::collections::HashMap; use colored::Colorize; use std::path::PathBuf; +use std::path::Path; use std::io; use crate::utils::{self, object}; @@ -30,7 +31,7 @@ pub fn status() { let mut next_sync_path = root.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 { @@ -51,9 +52,42 @@ pub fn status() { } } } + let mut obj_to_analyse = find_missing_elements(&mut hashes, &mut objects, RemoveSide::Both); + dbg!(obj_to_analyse.clone()); + + while obj_to_analyse.len() > 0 { + let cur_obj = obj_to_analyse.pop().unwrap(); + let obj_path = root.clone().join(Path::new(&cur_obj)); + + if obj_path.is_dir() { + if let Some((_, lines)) = object::read_tree(cur_obj.clone()) { + for line in lines { + if let Ok(ip) = line { + if ip.clone().len() > 5 { + let (ftype, hash, name) = object::parse_line(ip); + hashes.insert(String::from(hash), String::from(name)); + } + } + } + } + + if let Ok(entries) = utils::read::read_folder(obj_path.clone()) { + for entry in entries { + if !is_nextsync_config(entry.clone()) { + let object_path = entry.strip_prefix(root.clone()).unwrap(); + objects.push(String::from(object_path.to_str().unwrap())); + } + } + } + + let diff = find_missing_elements(&mut hashes, &mut objects, RemoveSide::Both); + obj_to_analyse.append(&mut diff.clone()); + } else { + // todo look for change + } + + } - let ok = find_missing_elements(&mut hashes, &mut objects, RemoveSide::Both); - dbg!(ok); if let Ok(entries) = utils::index::read_line(next_sync_path.clone()) { for entry in entries { // todo hash this diff --git a/src/utils/object.rs b/src/utils/object.rs index 1a70cda..b065021 100644 --- a/src/utils/object.rs +++ b/src/utils/object.rs @@ -1,9 +1,10 @@ -use std::path::Path; -use crate::utils::{head, path}; +use std::path::{Path, PathBuf}; +use crate::utils::{read, head, path}; use crypto::sha1::Sha1; use crypto::digest::Digest; use std::fs::{OpenOptions, self}; use std::io::{self, Write}; +use std::fs::File; /// Returns (line, hash, name) /// @@ -28,13 +29,13 @@ fn parse_path(path: &Path) -> (String, String, String) { pub fn parse_line(line: String) -> (String, String, String) { let mut split = line.rsplit(' '); if split.clone().count() != 3 { - dbg!(split.count()); eprintln!("fatal: invalid object(s)"); std::process::exit(1); } - let ftype = split.next().unwrap(); - let hash = split.next().unwrap(); + let name = split.next().unwrap(); + let hash = split.next().unwrap(); + let ftype = split.next().unwrap(); (String::from(ftype), String::from(hash), String::from(name)) } @@ -54,16 +55,60 @@ pub fn add_tree(path: &Path) -> io::Result<()> { Ok(()) } +fn hash_obj(obj: &str) -> (String, String) { + let mut hasher = Sha1::new(); + hasher.input_str(obj); + let hash = hasher.result_str(); + let (dir, res) = hash.split_at(2); + (String::from(dir), String::from(res)) +} + +fn object_path(obj: &str) -> PathBuf { + let mut root = match path::objects() { + Some(path) => path, + None => todo!(), + }; + + let (dir, res) = hash_obj(&obj); + root.push(dir); + root.push(res); + root +} + +pub fn read_tree(tree: String) -> Option<(String, io::Lines>)> { + let mut obj_p = match path::objects() { + Some(path) => path, + None => todo!(), + }; + + let (dir, res) = hash_obj(&tree); + obj_p.push(dir); + obj_p.push(res); + + + match read::read_lines(obj_p) { + Ok(mut reader) => { + let name = match reader.next() { + Some(Ok(line)) => line, + _ => String::from(""), + }; + Some((name, reader)) + }, + Err(err) => { + eprintln!("error reading tree: {}", err); + None + }, + } + +} + fn add_node(path: &Path, node: &str) -> io::Result<()> { let mut root = match path::objects() { Some(path) => path, None => todo!(), }; - let mut hasher = Sha1::new(); - hasher.input_str(path.clone().to_str().unwrap()); - let hash = hasher.result_str(); - let (dir, rest) = hash.split_at(2); + let (dir, rest) = hash_obj(path.clone().to_str().unwrap()); root.push(dir); if !root.exists() { @@ -95,11 +140,11 @@ fn create_object(name: String, content: &str) -> io::Result<()> { fs::create_dir_all(root.clone())?; } root.push(rest); - dbg!(root.clone()); + let mut file = OpenOptions::new() .create_new(true) .write(true) .open(root)?; - file.write_all(content.as_bytes())?; + writeln!(file, "{}", content)?; Ok(()) }