add option for path for status command

This commit is contained in:
grimhilt 2023-06-08 15:11:44 +02:00
parent b9f9371682
commit 33a151d579
5 changed files with 88 additions and 33 deletions

View File

@ -3,3 +3,4 @@ pub mod status;
pub mod add; pub mod add;
pub mod reset; pub mod reset;
pub mod clone; pub mod clone;
pub mod push;

6
src/commands/push.rs Normal file
View File

@ -0,0 +1,6 @@
use crate::commands::status;
pub fn push() {
dbg!(status::get_diff());
let (staged_obj, new_obj, del_obj) = status::get_diff();
}

View File

@ -17,9 +17,24 @@ enum RemoveSide {
// todo: relative path, filename, get modified // todo: relative path, filename, get modified
pub fn status() { pub fn status() {
let (staged_objs, new_objs, del_objs) = get_diff();
dbg!(get_diff());
print_status(staged_objs.clone(), del_objs.iter().map(|x| x.name.to_owned()).collect(), new_objs.clone());
}
#[derive(Debug)]
pub struct Obj {
otype: String,
name: String,
path: PathBuf,
}
// todo next time
// add relative path in command and in obj
pub fn get_diff() -> (Vec<String>, Vec<String>, Vec<Obj>) {
let mut hashes = HashMap::new(); let mut hashes = HashMap::new();
let mut objects: Vec<String> = vec![]; let mut objs: Vec<String> = vec![];
let mut staged_objects: Vec<String> = vec![]; let mut staged_objs: Vec<String> = vec![];
let root = match utils::path::nextsync_root() { let root = match utils::path::nextsync_root() {
Some(path) => path, Some(path) => path,
@ -29,18 +44,22 @@ pub fn status() {
} }
}; };
let mut next_sync_path = root.clone(); dbg!(utils::path::current());
next_sync_path.push(".nextsync"); let nextsync_path = utils::path::nextsync().unwrap();
let current_p = utils::path::current().unwrap();
let mut dist_path = current_p.strip_prefix(root.clone());
dbg!(dist_path.clone());
if let Ok(lines) = read_head(next_sync_path.clone()) { if let Ok(lines) = read_head(nextsync_path.clone()) {
add_to_hashmap(lines, &mut hashes); add_to_hashmap(lines, &mut hashes, root.clone());
} }
if let Ok(entries) = utils::read::read_folder(root.clone()) { if let Ok(entries) = utils::read::read_folder(root.clone()) {
add_to_vec(entries, &mut objects, root.clone()); add_to_vec(entries, &mut objs, root.clone());
} }
let mut obj_to_analyse = find_missing_elements(&mut hashes, &mut objects, RemoveSide::Both); let mut obj_to_analyse = remove_duplicate(&mut hashes, &mut objs, RemoveSide::Both);
dbg!(obj_to_analyse.clone()); dbg!(obj_to_analyse.clone());
while obj_to_analyse.len() > 0 { while obj_to_analyse.len() > 0 {
@ -49,14 +68,14 @@ pub fn status() {
if obj_path.is_dir() { if obj_path.is_dir() {
if let Some((_, lines)) = object::read_tree(cur_obj.clone()) { if let Some((_, lines)) = object::read_tree(cur_obj.clone()) {
add_to_hashmap(lines, &mut hashes); add_to_hashmap(lines, &mut hashes, obj_path.clone());
} }
if let Ok(entries) = utils::read::read_folder(obj_path.clone()) { if let Ok(entries) = utils::read::read_folder(obj_path.clone()) {
add_to_vec(entries, &mut objects, root.clone()); add_to_vec(entries, &mut objs, root.clone());
} }
let diff = find_missing_elements(&mut hashes, &mut objects, RemoveSide::Both); let diff = remove_duplicate(&mut hashes, &mut objs, RemoveSide::Both);
obj_to_analyse.append(&mut diff.clone()); obj_to_analyse.append(&mut diff.clone());
} else { } else {
// todo look for change // todo look for change
@ -64,26 +83,31 @@ pub fn status() {
} }
if let Ok(entries) = utils::index::read_line(next_sync_path.clone()) { if let Ok(entries) = utils::index::read_line(nextsync_path.clone()) {
for entry in entries { for entry in entries {
// todo hash this // todo hash this
staged_objects.push(String::from(entry.unwrap())); staged_objs.push(String::from(entry.unwrap()));
} }
} }
// print let del_objs: Vec<Obj> = hashes.iter().map(|x| {
let del_objs = hashes.clone().iter().map(|x| String::from(x.1)).collect(); Obj {otype: x.1.otype.clone(), name: x.1.name.clone(), path: x.1.path.clone()}
print_status(staged_objects.clone(), del_objs, objects.clone()); }).collect();
dbg!(hashes); (staged_objs.clone(), objs.clone(), del_objs)
dbg!(objects);
} }
fn add_to_hashmap(lines: Lines<BufReader<File>>, hashes: &mut HashMap<String, String>) { fn add_to_hashmap(lines: Lines<BufReader<File>>, hashes: &mut HashMap<String, Obj>, path: PathBuf) {
for line in lines { for line in lines {
if let Ok(ip) = line { if let Ok(ip) = line {
if ip.clone().len() > 5 { if ip.clone().len() > 5 {
let (ftype, hash, name) = object::parse_line(ip); let (ftype, hash, name) = object::parse_line(ip);
hashes.insert(String::from(hash), String::from(name)); let mut p = path.clone();
p.push(name.clone());
hashes.insert(String::from(hash), Obj{
otype: String::from(ftype),
name: String::from(name),
path: p,
});
} }
} }
} }
@ -100,7 +124,6 @@ fn add_to_vec(entries: Vec<PathBuf>, objects: &mut Vec<String>, root: PathBuf) {
} }
fn print_status(staged_objs: Vec<String>, del_objs: Vec<String>, new_objs: Vec<String>) { fn print_status(staged_objs: Vec<String>, del_objs: Vec<String>, new_objs: Vec<String>) {
if staged_objs.len() == 0 && del_objs.len() == 0 && new_objs.len() == 0 { if staged_objs.len() == 0 && del_objs.len() == 0 && new_objs.len() == 0 {
println!("Nothing to push, working tree clean"); println!("Nothing to push, working tree clean");
return; return;
@ -128,7 +151,7 @@ fn print_status(staged_objs: Vec<String>, del_objs: Vec<String>, new_objs: Vec<S
} }
fn find_missing_elements(hashes: &mut HashMap<String, String>, objects: &mut Vec<String>, remove_option: RemoveSide) -> Vec<String> { fn remove_duplicate(hashes: &mut HashMap<String, Obj>, objects: &mut Vec<String>, remove_option: RemoveSide) -> Vec<String> {
let mut hasher = Sha1::new(); let mut hasher = Sha1::new();
let mut to_remove: Vec<usize> = vec![]; let mut to_remove: Vec<usize> = vec![];
let mut i = 0; let mut i = 0;
@ -177,7 +200,7 @@ mod tests {
use super::*; use super::*;
#[test] #[test]
fn test_find_missing_elements() { fn test_remove_duplicate() {
let mut hasher = Sha1::new(); let mut hasher = Sha1::new();
hasher.input_str("file1"); hasher.input_str("file1");
let hash1 = hasher.result_str(); let hash1 = hasher.result_str();
@ -200,7 +223,7 @@ mod tests {
objects.push(String::from("file1")); objects.push(String::from("file1"));
objects.push(String::from("file2")); objects.push(String::from("file2"));
objects.push(String::from("file3")); objects.push(String::from("file3"));
find_missing_elements(&mut hashes, &mut objects, RemoveSide::Both); remove_duplicate(&mut hashes, &mut objects, RemoveSide::Both);
dbg!(hashes.clone()); dbg!(hashes.clone());
dbg!(objects.clone()); dbg!(objects.clone());
assert_eq!(hashes.contains(&hash4), true); assert_eq!(hashes.contains(&hash4), true);

View File

@ -18,8 +18,17 @@ fn main() {
.value_name("DIRECTORY") .value_name("DIRECTORY")
) )
) )
.subcommand(SubCommand::with_name("status")) .subcommand(
SubCommand::with_name("status")
.arg(
Arg::with_name("directory")
.required(false)
.takes_value(true)
.value_name("DIRECTORY")
)
)
.subcommand(SubCommand::with_name("reset")) .subcommand(SubCommand::with_name("reset"))
.subcommand(SubCommand::with_name("push"))
.subcommand( .subcommand(
SubCommand::with_name("clone") SubCommand::with_name("clone")
.arg( .arg(
@ -53,7 +62,10 @@ fn main() {
global::global::set_dir_path(String::from(val.clone().next().unwrap())); global::global::set_dir_path(String::from(val.clone().next().unwrap()));
} }
commands::init::init(); commands::init::init();
} else if let Some(_) = matches.subcommand_matches("status") { } else if let Some(matches) = matches.subcommand_matches("status") {
if let Some(val) = matches.values_of("directory") {
global::global::set_dir_path(String::from(val.clone().next().unwrap()));
}
commands::status::status(); commands::status::status();
} else if let Some(matches) = matches.subcommand_matches("add") { } else if let Some(matches) = matches.subcommand_matches("add") {
if let Some(files) = matches.values_of("files") { if let Some(files) = matches.values_of("files") {
@ -68,6 +80,8 @@ fn main() {
if let Some(remote) = matches.values_of("remote") { if let Some(remote) = matches.values_of("remote") {
commands::clone::clone(remote); commands::clone::clone(remote);
} }
} else if let Some(matches) = matches.subcommand_matches("push") {
commands::push::push();
} }
} }

View File

@ -3,26 +3,28 @@ use std::path::{PathBuf, Path};
use crate::global::global::DIR_PATH; use crate::global::global::DIR_PATH;
use std::fs::canonicalize; use std::fs::canonicalize;
pub fn nextsync_root() -> Option<PathBuf> { pub fn current() -> Option<PathBuf> {
let d = DIR_PATH.lock().unwrap(); let d = DIR_PATH.lock().unwrap();
let mut path = match d.clone() { match d.clone() {
Some(dir) => { Some(dir) => {
let tmp = PathBuf::from(dir).to_owned(); let tmp = PathBuf::from(dir).to_owned();
if tmp.is_absolute() { if tmp.is_absolute() {
tmp Some(tmp)
} else { } else {
let current_dir = env::current_dir().ok()?; let current_dir = env::current_dir().ok()?;
let abs = current_dir.join(tmp); let abs = current_dir.join(tmp);
let canonicalized_path = canonicalize(abs).ok()?; let canonicalized_path = canonicalize(abs).ok()?;
canonicalized_path Some(canonicalized_path)
} }
}, },
None => env::current_dir().ok()?, None => Some(env::current_dir().ok()?),
}; }
}
dbg!(path.clone()); pub fn nextsync_root() -> Option<PathBuf> {
let mut path = current()?;
let root = loop { let root = loop {
path.push(".nextsync"); path.push(".nextsync");
@ -39,6 +41,15 @@ pub fn nextsync_root() -> Option<PathBuf> {
root root
} }
pub fn nextsync() -> Option<PathBuf> {
if let Some(mut path) = nextsync_root() {
path.push(".nextsync");
return Some(path);
}
None
}
pub fn objects() -> Option<PathBuf> { pub fn objects() -> Option<PathBuf> {
if let Some(mut path) = nextsync_root() { if let Some(mut path) = nextsync_root() {
path.push(".nextsync"); path.push(".nextsync");