fix blob creation and get changes

This commit is contained in:
grimhilt 2023-08-04 19:17:04 +02:00
parent ce047eba12
commit 91a29480df

View File

@ -1,4 +1,7 @@
use std::io; use std::io::{self, Read};
use std::fs::File;
use std::io::Write;
use std::fs::OpenOptions;
use std::path::PathBuf; use std::path::PathBuf;
use std::time::SystemTime; use std::time::SystemTime;
use std::fs; use std::fs;
@ -9,15 +12,17 @@ use crate::store::head;
use crate::store::object::{update_dates, add_node, create_obj, rm_node}; use crate::store::object::{update_dates, add_node, create_obj, rm_node};
pub struct Blob { pub struct Blob {
path: PathBuf, r_path: PathBuf,
a_path: PathBuf,
hash: String, hash: String,
obj_p: PathBuf, obj_p: PathBuf,
data: Vec<String>,
} }
impl Blob { impl Blob {
pub fn new(path: PathBuf) -> Blob { pub fn new(r_path: PathBuf) -> Blob {
let mut hasher = Sha1::new(); let mut hasher = Sha1::new();
hasher.input_str(path.to_str().unwrap()); hasher.input_str(r_path.to_str().unwrap());
let hash = hasher.result_str(); let hash = hasher.result_str();
let (dir, res) = hash.split_at(2); let (dir, res) = hash.split_at(2);
@ -26,15 +31,20 @@ impl Blob {
obj_p.push(dir); obj_p.push(dir);
obj_p.push(res); obj_p.push(res);
let root = path::repo_root();
let a_path = root.join(r_path.clone());
Blob { Blob {
path, r_path,
a_path,
hash, hash,
obj_p, obj_p,
data: vec![],
} }
} }
fn get_line_filename(&mut self) -> (String, String) { fn get_line_filename(&mut self) -> (String, String) {
let file_name = self.path.file_name().unwrap().to_str().unwrap().to_owned(); let file_name = self.r_path.file_name().unwrap().to_str().unwrap().to_owned();
let mut line = String::from("blob"); let mut line = String::from("blob");
line.push_str(" "); line.push_str(" ");
line.push_str(&self.hash); line.push_str(&self.hash);
@ -44,7 +54,7 @@ impl Blob {
} }
fn get_file_hash(&self) -> String { fn get_file_hash(&self) -> String {
let bytes = std::fs::read(self.path.clone()).unwrap(); let bytes = std::fs::read(self.a_path.clone()).unwrap();
let hash = md5::compute(&bytes); let hash = md5::compute(&bytes);
format!("{:x}", hash) format!("{:x}", hash)
} }
@ -53,14 +63,14 @@ impl Blob {
let (line, file_name) = self.get_line_filename(); let (line, file_name) = self.get_line_filename();
// add blob reference to parent // add blob reference to parent
if self.path.iter().count() == 1 { if self.r_path.iter().count() == 1 {
head::add_line(line)?; head::add_line(line)?;
} else { } else {
add_node(self.path.parent().unwrap(), &line)?; add_node(self.r_path.parent().unwrap(), &line)?;
} }
// create blob object // create blob object
let metadata = fs::metadata(self.path.clone())?; let metadata = fs::metadata(self.a_path.clone())?;
let mut content = file_name.clone(); let mut content = file_name.clone();
content.push_str(" "); content.push_str(" ");
@ -68,6 +78,7 @@ impl Blob {
content.push_str(" "); content.push_str(" ");
content.push_str(&metadata.len().to_string()); content.push_str(&metadata.len().to_string());
content.push_str(" "); content.push_str(" ");
let secs = metadata let secs = metadata
.modified() .modified()
.unwrap() .unwrap()
@ -77,11 +88,22 @@ impl Blob {
content.push_str(&secs.to_string()); content.push_str(&secs.to_string());
content.push_str(" "); content.push_str(" ");
content.push_str(&self.get_file_hash()); content.push_str(&self.get_file_hash());
create_obj(self.hash.clone(), &content)?; content.push_str(" ");
// create ref of object
let binding = self.obj_p.clone();
let child = binding.file_name();
self.obj_p.pop();
self.obj_p.push(child.unwrap().to_str().unwrap());
let mut file = OpenOptions::new()
.create_new(true)
.write(true)
.open(self.obj_p.clone())?;
writeln!(file, "{}", &content)?;
// update date for all parent // update date for all parent
if up_parent { if up_parent {
update_dates(self.path.clone(), ts_remote)?; update_dates(self.r_path.clone(), ts_remote)?;
} }
Ok(()) Ok(())
} }
@ -90,10 +112,10 @@ impl Blob {
let (line, _) = self.get_line_filename(); let (line, _) = self.get_line_filename();
// remove blob reference to parent // remove blob reference to parent
if self.path.iter().count() == 1 { if self.r_path.iter().count() == 1 {
head::rm_line(&line)?; head::rm_line(&line)?;
} else { } else {
rm_node(self.path.parent().unwrap(), &line)?; rm_node(self.r_path.parent().unwrap(), &line)?;
} }
// remove blob object // remove blob object
@ -101,4 +123,57 @@ impl Blob {
Ok(()) Ok(())
} }
pub fn read_data(&mut self) {
if self.data.len() == 0 {
if let Ok(mut file) = File::open(self.obj_p.clone()) {
let mut buffer = String::new();
let _ = file.read_to_string(&mut buffer);
let data = buffer.rsplit(' ').collect::<Vec<_>>();
for e in data {
self.data.push(String::from(e));
}
self.data.reverse();
}
}
}
fn has_same_size(&mut self) -> bool {
let metadata = match fs::metadata(self.a_path.clone()) {
Ok(m) => m,
Err(_) => return true,
};
self.read_data();
if self.data.len() < 3 { return true; }
metadata.len().to_string() == self.data[2]
}
fn is_newer(&mut self) -> bool {
let metadata = match fs::metadata(self.a_path.clone()) {
Ok(m) => m,
Err(_) => return true,
};
self.read_data();
let secs = metadata
.modified()
.unwrap()
.duration_since(SystemTime::UNIX_EPOCH)
.unwrap()
.as_secs();
if self.data.len() < 4 { return true; }
secs > self.data[3].parse::<u64>().unwrap()
}
fn has_same_hash(&mut self) -> bool {
self.read_data();
if self.data.len() < 5 { return false; }
self.data[4] == self.get_file_hash()
}
pub fn has_change(&mut self) -> bool {
!self.has_same_size() || (self.is_newer() && !self.has_same_hash())
}
} }