Index parsing and gitignore files
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use std::path::Path;
|
||||
|
||||
use crate::{
|
||||
git_fs::{gitignore::expands_and_filter_path, index::Index, normalize_path_in_worktree},
|
||||
subcommands::hash_object::HashObjectSubcommand,
|
||||
};
|
||||
|
||||
use super::Subcommand;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct AddSubcommand {
|
||||
pub paths: Vec<String>,
|
||||
}
|
||||
|
||||
impl Subcommand for AddSubcommand {
|
||||
fn run(&self) -> Result<String> {
|
||||
if self.paths.is_empty() {
|
||||
return Ok(String::from("Nothing specified, nothing added"));
|
||||
}
|
||||
|
||||
let mut index = Index::load()?;
|
||||
|
||||
for path in self.paths.iter().map(|p| Path::new(p).to_path_buf()) {
|
||||
let expanded = expands_and_filter_path(path)?;
|
||||
for p in expanded {
|
||||
println!("Adding {}", p.display());
|
||||
let path_str = String::from(p.to_str().unwrap());
|
||||
let name = String::from(normalize_path_in_worktree(&p)?.to_str().unwrap());
|
||||
println!("adding {}", name);
|
||||
let hash = HashObjectSubcommand {
|
||||
write: true,
|
||||
path: path_str,
|
||||
}
|
||||
.run_raw()?;
|
||||
index.add_file(name, hash)?;
|
||||
}
|
||||
}
|
||||
|
||||
index.save()?;
|
||||
|
||||
Ok(String::from(""))
|
||||
}
|
||||
}
|
||||
@@ -1,32 +1,38 @@
|
||||
use anyhow::{Result, bail};
|
||||
use clap::Parser;
|
||||
use hex::encode;
|
||||
|
||||
use crate::{
|
||||
git_fs::object::{Blob, GitObject},
|
||||
subcommands::Subcommand
|
||||
subcommands::Subcommand,
|
||||
};
|
||||
|
||||
use super::CmdResult;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct HashObjectSubcommand {
|
||||
#[arg(short)]
|
||||
#[arg(short, default_value_t = false)]
|
||||
/// Save object in database
|
||||
pub write: bool,
|
||||
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
impl Subcommand for HashObjectSubcommand {
|
||||
fn run (&self) -> CmdResult {
|
||||
let object = match Blob::create(self.path.clone()) {
|
||||
Ok(o) => o,
|
||||
_ => return Err("".to_owned())
|
||||
impl HashObjectSubcommand {
|
||||
pub fn run_raw(&self) -> Result<[u8; 20]> {
|
||||
let object = Blob::create(self.path.clone())?;
|
||||
let hash = object.hash(self.write)?;
|
||||
|
||||
let hash_final: [u8; 20] = match hash.first_chunk() {
|
||||
Some(h) => *h,
|
||||
None => bail!("Hash length not valid"),
|
||||
};
|
||||
|
||||
match object.hash(self.write) {
|
||||
Ok(hash) => Ok(encode(hash)),
|
||||
_ => return Err("".to_owned())
|
||||
}
|
||||
Ok(hash_final)
|
||||
}
|
||||
}
|
||||
|
||||
impl Subcommand for HashObjectSubcommand {
|
||||
fn run(&self) -> Result<String> {
|
||||
let hash = self.run_raw()?;
|
||||
Ok(encode(hash))
|
||||
}
|
||||
}
|
||||
|
||||
+22
-28
@@ -1,14 +1,11 @@
|
||||
use anyhow::Result;
|
||||
use anyhow::bail;
|
||||
use clap::Parser;
|
||||
use std::{
|
||||
fs,
|
||||
path::Path
|
||||
};
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use crate::GIT_DIR;
|
||||
use crate::git_fs::head::Head;
|
||||
use crate::subcommands::Subcommand;
|
||||
use crate::GIT_DIR;
|
||||
|
||||
use super::CmdResult;
|
||||
|
||||
#[derive(Parser, Debug)]
|
||||
pub struct InitSubcommand {
|
||||
@@ -16,45 +13,42 @@ pub struct InitSubcommand {
|
||||
}
|
||||
|
||||
impl Subcommand for InitSubcommand {
|
||||
fn run(&self) -> CmdResult {
|
||||
fn run(&self) -> Result<String> {
|
||||
let path = match &self.directory {
|
||||
None => Path::new("."),
|
||||
Some(path) => Path::new(path),
|
||||
}.join(GIT_DIR);
|
||||
}
|
||||
.join(GIT_DIR);
|
||||
|
||||
let new_repo = path.exists();
|
||||
|
||||
match fs::create_dir_all(&path) {
|
||||
Err(_) => return Err("Error while creating dir".to_owned()),
|
||||
Ok(()) => (),
|
||||
if fs::create_dir_all(&path).is_err() {
|
||||
bail!("Error while creating dir")
|
||||
};
|
||||
|
||||
let folders = [
|
||||
"objects/info",
|
||||
"objects/pack",
|
||||
"refs/heads",
|
||||
"refs/tags",
|
||||
];
|
||||
let folders = ["objects/info", "objects/pack", "refs/heads", "refs/tags"];
|
||||
|
||||
for folder in folders {
|
||||
match fs::create_dir_all(&path.join(folder)) {
|
||||
Err(_) => return Err("".to_owned()),
|
||||
Ok(()) => (),
|
||||
};
|
||||
fs::create_dir_all(path.join(folder))?;
|
||||
}
|
||||
|
||||
let head = Head { ref_to: String::from("refs/heads/master") };
|
||||
match head.save() {
|
||||
Err(_) => return Err("".to_owned()),
|
||||
Ok(()) => (),
|
||||
let head = Head {
|
||||
ref_to: String::from("refs/heads/master"),
|
||||
};
|
||||
head.save()?;
|
||||
|
||||
let canonical_path = path.canonicalize();
|
||||
|
||||
if new_repo {
|
||||
Ok(format!("Reinitialized exisiting Git repo in {}", canonical_path.unwrap().display()))
|
||||
Ok(format!(
|
||||
"Reinitialized exisiting Git repo in {}",
|
||||
canonical_path?.display()
|
||||
))
|
||||
} else {
|
||||
Ok(format!("Initialized empty Git repo in {}", canonical_path.unwrap().display()))
|
||||
Ok(format!(
|
||||
"Initialized empty Git repo in {}",
|
||||
canonical_path?.display()
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+13
-7
@@ -1,17 +1,21 @@
|
||||
use crate::subcommands::{
|
||||
init::InitSubcommand,
|
||||
test::TestSubcommand,
|
||||
hash_object::HashObjectSubcommand,
|
||||
add::AddSubcommand, hash_object::HashObjectSubcommand, init::InitSubcommand,
|
||||
remove::RemoveSubcommand, test::TestSubcommand,
|
||||
};
|
||||
use anyhow::Result;
|
||||
|
||||
mod add;
|
||||
mod hash_object;
|
||||
mod init;
|
||||
mod remove;
|
||||
mod test;
|
||||
|
||||
pub type CmdResult = Result<String, String>;
|
||||
|
||||
#[derive(clap::Parser, Debug)]
|
||||
pub enum SubcommandType {
|
||||
/// Add file(s) to index
|
||||
Add(AddSubcommand),
|
||||
/// Remove file from the working and the index
|
||||
Remove(RemoveSubcommand),
|
||||
/// Init a Git repository
|
||||
Init(InitSubcommand),
|
||||
HashObject(HashObjectSubcommand),
|
||||
@@ -19,12 +23,14 @@ pub enum SubcommandType {
|
||||
}
|
||||
|
||||
pub trait Subcommand {
|
||||
fn run(&self) -> CmdResult;
|
||||
fn run(&self) -> Result<String>;
|
||||
}
|
||||
|
||||
impl Subcommand for SubcommandType {
|
||||
fn run(&self) -> CmdResult {
|
||||
fn run(&self) -> Result<String> {
|
||||
match self {
|
||||
Self::Add(cmd) => cmd.run(),
|
||||
Self::Remove(cmd) => cmd.run(),
|
||||
Self::Init(cmd) => cmd.run(),
|
||||
Self::HashObject(cmd) => cmd.run(),
|
||||
Self::Test(cmd) => cmd.run(),
|
||||
|
||||
Reference in New Issue
Block a user