gor 0.1.0

A simple version control system written in Rust
Documentation
use crate::commands::init::Config;
use glob::Pattern;
use std::{
    error::Error,
    fs::{self, read_dir, File},
    io::{self, BufRead, Write},
    path::Path,
};

pub fn repo(config: &Config) -> Result<(), Box<dyn Error>> {
    println!("Creating repository in {}", config.file_path);
    let path = config.file_path.clone() + "/.gor";
    fs::create_dir_all(path.clone())?;
    initial_vcs_files(&path)?;
    existing_vcs_files(&config.file_path.clone())?;
    Ok(())
}

fn initial_vcs_files(path: &String) -> Result<(), Box<dyn Error>> {
    fs::create_dir_all(format!("{path}/refs/heads"))?;
    fs::create_dir_all(format!("{path}/refs/tags"))?;
    fs::create_dir_all(format!("{path}/objects"))?;

    let mut head = File::create(format!("{path}/HEAD"))?;
    let buf = b"ref: refs/heads/master\n";
    head.write_all(buf)?;

    let mut config = File::create(format!("{path}/config"))?;
    let buf = b"[core]\n\trepositoryformatversion = 0\n\tfilemode = true\n\tbare = false\n";
    config.write_all(buf)?;

    let mut ignore = File::create(format!("{path}/../.gorignore"))?;
    let buf = b"*.git\n*.gor\ntarget\n";
    ignore.write_all(buf)?;
    Ok(())
}

fn existing_vcs_files(path: &String) -> Result<(), Box<dyn Error>> {
    let mut ignore_patterns = Vec::new();
    if let Ok(file) = File::open(path.clone() + "/.gorignore") {
        for line in io::BufReader::new(file).lines() {
            if let Ok(pattern) = line {
                ignore_patterns.push(Pattern::new(&format!("{}/{}", path, pattern))?);
            }
        }
    }

    let curr_path = Path::new(path);
    visit_dir(curr_path, &ignore_patterns)?;

    Ok(())
}

fn visit_dir(dir: &Path, ignore_patterns: &Vec<Pattern>) -> Result<(), Box<dyn Error>> {
    for entry in read_dir(dir)? {
        let entry = entry?;
        let path = entry.path();
        let match_path = Path::new(&path);
        let mut flag: bool = false;

        for pattern in ignore_patterns {
            if pattern.matches_path(match_path) {
                flag = true;
            }
        }
        if flag {
            continue;
        }
        if path.is_dir() {
            visit_dir(&path, ignore_patterns)?;
        } else {
            println!("{:?}", path);
        }
    }

    Ok(())
}