diff --git a/docs/store.md b/docs/store.md new file mode 100644 index 0000000..61c3f3a --- /dev/null +++ b/docs/store.md @@ -0,0 +1,13 @@ + +## Blob object + +``` +file_name hash timestamp +``` + +## Tree object +``` +folder_name +tree hash_path folder_name +blob hash_path file_name +``` \ No newline at end of file diff --git a/src/commands/clone.rs b/src/commands/clone.rs index 3895935..4ff0768 100644 --- a/src/commands/clone.rs +++ b/src/commands/clone.rs @@ -1,7 +1,7 @@ use std::fs::OpenOptions; use std::fs::DirBuilder; use std::io::prelude::*; -use std::io::Cursor; +use std::io::{self, Cursor}; use std::path::{Path, PathBuf}; use clap::Values; use regex::Regex; @@ -10,6 +10,7 @@ use crate::services::api::ApiError; use crate::services::list_folders::ListFolders; use crate::services::download_files::DownloadFiles; use crate::utils::object; +use crate::utils::path; use crate::commands; use crate::global::global::{DIR_PATH, set_dir_path}; @@ -61,7 +62,6 @@ pub fn clone(remote: Values<'_>) { // create folder if first_iter { - // first element how path or last element of given path if DirBuilder::new().create(local_path.clone()).is_err() { eprintln!("fatal: directory already exist"); // destination path 'path' already exists and is not an empty directory. @@ -105,6 +105,19 @@ fn get_local_path(p: String, local_p: PathBuf, username: &str, dist_p: &str) -> local_p.clone().join(final_p.clone()) } +fn write_file(path: PathBuf, content: &Vec, local_p: PathBuf) -> io::Result<()> { + let mut f = OpenOptions::new() + .write(true) + .create(true) + .open(path.clone())?; + + f.write_all(&content)?; + + let relative_p = Path::new(&path).strip_prefix(local_p).unwrap(); + object::add_blob(relative_p, "tmpdate"); + Ok(()) +} + fn download_files(domain: &str, local_p: PathBuf, username: &str, dist_p: &str, files: Vec) { for file in files { let mut url_request = String::from(domain.clone()); @@ -112,14 +125,11 @@ fn download_files(domain: &str, local_p: PathBuf, username: &str, dist_p: &str, tokio::runtime::Runtime::new().unwrap().block_on(async { match DownloadFiles::new(url_request.as_str()).send_with_err().await { Ok(b) => { - let p_to_save = get_local_path(file, local_p.clone(), username, dist_p); + let p_to_save = get_local_path(file.clone(), local_p.clone(), username, dist_p); - let mut f = OpenOptions::new() - .write(true) - .create(true) - .open(p_to_save).unwrap(); - - f.write_all(&b); + if let Err(_) = write_file(p_to_save, &b, local_p.clone()) { + eprintln!("error writing {}", file); + } }, Err(ApiError::IncorrectRequest(err)) => { eprintln!("fatal: {}", err.status()); diff --git a/src/commands/push.rs b/src/commands/push.rs index 326a180..cdb05e1 100644 --- a/src/commands/push.rs +++ b/src/commands/push.rs @@ -12,5 +12,7 @@ pub fn push() { }; let (staged_obj, new_obj, del_obj) = status::get_diff(); + // read index + // if dir upload dir } diff --git a/src/utils/config.rs b/src/utils/config.rs new file mode 100644 index 0000000..945593b --- /dev/null +++ b/src/utils/config.rs @@ -0,0 +1,6 @@ + + +src/utils/object.rs +todo +src/utils/head.rs +src/utils/read.rs diff --git a/src/utils/object.rs b/src/utils/object.rs index b065021..c715bca 100644 --- a/src/utils/object.rs +++ b/src/utils/object.rs @@ -11,14 +11,14 @@ use std::fs::File; /// # Examples /// Input: /foo/bar /// Result: ("tree hash(/foo/bar) bar", hash(/foo/bar), bar) -fn parse_path(path: &Path) -> (String, String, String) { +fn parse_path(path: &Path, is_blob: bool) -> (String, String, String) { let file_name = path.file_name().unwrap().to_str().unwrap(); let mut hasher = Sha1::new(); hasher.input_str(path.clone().to_str().unwrap()); let hash = hasher.result_str(); - let mut line = String::from("tree"); + let mut line = String::from(if is_blob { "tree" } else { "blob" }); line.push_str(" "); line.push_str(&hash); line.push_str(" "); @@ -40,7 +40,7 @@ pub fn parse_line(line: String) -> (String, String, String) { } pub fn add_tree(path: &Path) -> io::Result<()> { - let (line, hash, name) = parse_path(path.clone()); + let (line, hash, name) = parse_path(path.clone(), false); // add tree reference to parent if path.iter().count() == 1 { @@ -55,6 +55,28 @@ pub fn add_tree(path: &Path) -> io::Result<()> { Ok(()) } +pub fn add_blob(path: &Path, date: &str) -> io::Result<()> { + let (line, hash, name) = parse_path(path.clone(), true); + + // add tree reference to parent + if path.iter().count() == 1 { + head::add_line(line)?; + } else { + add_node(path.parent().unwrap(), &line)?; + } + + let mut content = name.clone().to_owned(); + content.push_str(" "); + content.push_str("tmp_hash"); + content.push_str(" "); + content.push_str(date); + + // create blob object + create_object(hash, &content)?; + + Ok(()) +} + fn hash_obj(obj: &str) -> (String, String) { let mut hasher = Sha1::new(); hasher.input_str(obj); @@ -110,12 +132,16 @@ fn add_node(path: &Path, node: &str) -> io::Result<()> { let (dir, rest) = hash_obj(path.clone().to_str().unwrap()); + dbg!(root.clone()); root.push(dir); if !root.exists() { todo!(); } root.push(rest); + dbg!("create node"); + dbg!(root.clone()); + dbg!(node.clone()); let mut file = OpenOptions::new() .read(true) .write(true)