From 35adfab9833d92fca0fff8304d942b6b0d1efdb8 Mon Sep 17 00:00:00 2001 From: grimhilt Date: Thu, 15 Jun 2023 17:32:57 +0200 Subject: [PATCH] add remove line --- src/store/head.rs | 12 ++++++++++++ src/store/index.rs | 14 +++++++++++++- src/store/object.rs | 45 +++++++++++++++++++++++++++++++++++++++++++-- src/utils/read.rs | 31 +++++++++++++++++++++++++++---- 4 files changed, 95 insertions(+), 7 deletions(-) diff --git a/src/store/head.rs b/src/store/head.rs index d3ab9a4..62b9399 100644 --- a/src/store/head.rs +++ b/src/store/head.rs @@ -43,3 +43,15 @@ pub fn add_line(line: String) -> io::Result<()> { writeln!(file, "{}", line)?; Ok(()) } + +pub fn rm_line(line: &str) -> io::Result<()> { + let mut root = match path::nextsync_root() { + Some(path) => path, + None => todo!(), + }; + + root.push(".nextsync"); + root.push("HEAD"); + read::rm_line(root, line)?; + Ok(()) +} diff --git a/src/store/index.rs b/src/store/index.rs index 9adca2e..bb55cce 100644 --- a/src/store/index.rs +++ b/src/store/index.rs @@ -1,7 +1,7 @@ use std::fs::OpenOptions; use std::fs::File; use std::path::PathBuf; -use crate::utils::read; +use crate::utils::{read, path}; use std::io; pub fn _read_only(mut path: PathBuf) -> File { @@ -25,3 +25,15 @@ pub fn read_line(mut path: PathBuf) -> io::Result> path.push("index"); read::read_lines(path) } + +pub fn rm_line(line: &str) -> io::Result<()> { + let mut root = match path::nextsync_root() { + Some(path) => path, + None => todo!(), + }; + + root.push(".nextsync"); + root.push("index"); + read::rm_line(root, line)?; + Ok(()) +} diff --git a/src/store/object.rs b/src/store/object.rs index 3792897..2663967 100644 --- a/src/store/object.rs +++ b/src/store/object.rs @@ -19,7 +19,7 @@ fn parse_path(path: &Path, is_blob: bool) -> (String, String, String) { hasher.input_str(path.clone().to_str().unwrap()); let hash = hasher.result_str(); - let mut line = String::from(if is_blob { "tree" } else { "blob" }); + let mut line = String::from(if is_blob { "blob" } else { "tree" }); line.push_str(" "); line.push_str(&hash); line.push_str(" "); @@ -56,10 +56,36 @@ pub fn add_tree(path: &Path) -> io::Result<()> { Ok(()) } +pub fn rm_blob(path: &Path) -> io::Result<()> { + let (line, hash, name) = parse_path(path.clone(), true); + + // remove blob reference to parent + if path.iter().count() == 1 { + head::rm_line(&line)?; + } else { + rm_node(path.parent().unwrap(), &line)?; + } + + // remove blob object + let mut root = match path::objects() { + Some(path) => path, + None => todo!(), + }; + + let c = hash.clone(); + let (dir, rest) = c.split_at(2); + root.push(dir); + root.push(rest); + fs::remove_file(root)?; + + 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 + // add blob reference to parent if path.iter().count() == 1 { head::add_line(line)?; } else { @@ -125,6 +151,21 @@ pub fn read_tree(tree: String) -> Option<(String, io::Lines> } +fn rm_node(path: &Path, node: &str) -> io::Result<()> { + let mut root = match path::objects() { + Some(path) => path, + None => todo!(), + }; + + let (dir, rest) = hash_obj(path.clone().to_str().unwrap()); + + root.push(dir); + root.push(rest); + + read::rm_line(root, node)?; + Ok(()) +} + fn add_node(path: &Path, node: &str) -> io::Result<()> { let mut root = match path::objects() { Some(path) => path, diff --git a/src/utils/read.rs b/src/utils/read.rs index 63ff5b8..ab4e949 100644 --- a/src/utils/read.rs +++ b/src/utils/read.rs @@ -1,9 +1,7 @@ use std::path::{Path, PathBuf}; -use std::io::{self, BufRead}; -use std::fs::{self, File}; +use std::io::{self, BufRead, BufReader, Write}; +use std::fs::{self, File, OpenOptions}; -// The output is wrapped in a Result to allow matching on errors -// Returns an Iterator to the Reader of the lines of the file. pub fn read_lines

(filename: P) -> io::Result>> where P: AsRef, { let file = File::open(filename)?; @@ -18,3 +16,28 @@ pub fn read_folder(path: PathBuf) -> io::Result> { entries.sort(); Ok(entries) } + + +pub fn rm_line(path: PathBuf, line_to_del: &str) -> io::Result<()> { + let file = File::open(path.clone())?; + let reader = BufReader::new(&file); + let mut temp_file = OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(format!("{}_temp", path.display()))?; + + for line in reader.lines() { + let l = line?; + if l.trim() != line_to_del.trim() { + writeln!(temp_file, "{}", l)?; + } + } + + drop(file); + drop(temp_file); + + fs::remove_file(path.clone())?; + fs::rename(format!("{}_temp", path.display()), path)?; + Ok(()) +}