use std::fs;
use std::fs::OpenOptions;
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use anyhow::{bail, Result};
use dirs::home_dir;
pub fn read_contet_with_string<P: AsRef<Path>>(file_path: P) -> Result<String> {
let mut file = OpenOptions::new().read(true).open(file_path)?;
let mut content = String::new();
file.read_to_string(&mut content)?;
Ok(content)
}
pub fn read_contet_with_bytes<P: AsRef<Path>>(file_path: P) -> Result<Vec<u8>> {
let mut file = OpenOptions::new().read(true).open(file_path)?;
let mut bytes = Vec::new();
file.read_to_end(&mut bytes)?;
Ok(bytes)
}
pub fn open_file_trucate<P: AsRef<Path>>(file_path: P, buffer: &[u8]) -> std::io::Result<()> {
let mut file = OpenOptions::new()
.write(true)
.truncate(true)
.open(file_path)?;
file.write_all(buffer)
}
pub fn create_file_with_buffer<P: AsRef<Path>>(file_path: P, buffer: &[u8]) -> std::io::Result<()> {
let mut file = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(file_path)?;
file.write_all(buffer)
}
pub fn create_dir<P: AsRef<Path>>(dir_path: P) -> std::io::Result<()> {
fs::create_dir_all(dir_path)
}
pub fn remove_file<P: AsRef<Path>>(path: P) -> std::io::Result<()> {
fs::remove_file(path)
}
pub fn remove_dir_all<P: AsRef<Path>>(path: P) -> std::io::Result<()> {
fs::remove_dir_all(path)
}
pub fn exists_repo<P: AsRef<Path>>(repo_dir: Option<P>) -> Result<PathBuf> {
let current_dir = match repo_dir {
Some(p) => {
if p.as_ref().to_path_buf() == home_dir().unwrap() {
bail!("not a nss repository (or any of the parent directories): .nss")
} else {
p.as_ref().to_path_buf()
}
}
_ => std::env::current_dir()?,
};
let repo_path = current_dir.join(PathBuf::from(".nss"));
let read_dir = fs::read_dir(¤t_dir)?;
for entry in read_dir {
match entry?.path() == repo_path {
true => return Ok(current_dir),
false => continue,
}
}
return exists_repo(Some(current_dir.parent().unwrap()));
}
#[cfg(test)]
mod tests {
use super::*;
use std::env;
use std::fs;
use std::fs::File;
use std::io::Read;
use testdir::testdir;
#[test]
fn test_read_contet_with_string() {
let temp_dir = testdir!();
println!("Test Directory: {}", temp_dir.display());
let test_file_root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
.join("tests")
.join("test_repo")
.join("first.rs");
fs::copy(test_file_root, temp_dir.join("first.rs")).unwrap();
let result = read_contet_with_string(temp_dir.join("first.rs"));
assert!(result.is_ok());
let test_content = "#[allow(dead_code)]
fn commit(message: &str) -> std::io::Result<()> {
let tree_hash = write_tree()?;
match commit_tree(&tree_hash, message)? {
Some(c) => update_ref(&c)?,
_ => println!(\"Nothing to commit\")
};
Ok(())
}";
assert_eq!(result.unwrap(), test_content);
let result = read_contet_with_string(&temp_dir.join("second.rs"));
assert!(result.is_err());
let result = read_contet_with_string(&temp_dir);
assert!(result.is_err());
fs::remove_dir_all(temp_dir).unwrap();
}
#[test]
fn test_read_contet_with_bytes() {
let temp_dir = testdir!();
println!("Test Directory: {}", temp_dir.display());
let test_file_root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
.join("tests")
.join("test_repo")
.join("first.rs");
fs::copy(test_file_root, temp_dir.join("first.rs")).unwrap();
let result = read_contet_with_bytes(temp_dir.join("first.rs"));
assert!(result.is_ok());
let test_content = b"#[allow(dead_code)]
fn commit(message: &str) -> std::io::Result<()> {
let tree_hash = write_tree()?;
match commit_tree(&tree_hash, message)? {
Some(c) => update_ref(&c)?,
_ => println!(\"Nothing to commit\")
};
Ok(())
}";
assert_eq!(result.unwrap(), test_content);
let result = read_contet_with_bytes(temp_dir.join("second.rs"));
assert!(result.is_err());
let result = read_contet_with_bytes(&temp_dir);
assert!(result.is_err());
fs::remove_dir_all(temp_dir).unwrap();
}
#[test]
fn test_open_file_trucate() {
let temp_dir = testdir!();
println!("Test Directory: {}", temp_dir.display());
let test_file_root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
.join("tests")
.join("test_config")
.join("config");
fs::copy(test_file_root, temp_dir.join("config")).unwrap();
let test_content = "[user]
name = \"nopipi\"
";
let result = open_file_trucate(temp_dir.join("config"), test_content.as_bytes());
assert!(result.is_ok());
let mut file = OpenOptions::new()
.read(true)
.open(temp_dir.join("config"))
.unwrap();
let mut content = String::new();
file.read_to_string(&mut content).unwrap();
assert_eq!(content, test_content);
let result = open_file_trucate(temp_dir.join("config2"), test_content.as_bytes());
assert!(result.is_err());
fs::remove_dir_all(temp_dir).unwrap();
}
#[test]
fn test_create_file_with_buffer() {
let temp_dir = testdir!();
println!("Test Directory: {}", temp_dir.display());
let file_path = temp_dir.join("test_file.txt");
let buffer = b"Hello, world!";
assert!(create_file_with_buffer(&file_path, buffer).is_ok());
let mut file = fs::File::open(&file_path).unwrap();
let mut file_contents = Vec::new();
file.read_to_end(&mut file_contents).unwrap();
assert_eq!(file_contents, buffer);
fs::remove_dir_all(temp_dir).unwrap();
}
#[test]
fn test_create_dir() {
let temp_dir = testdir!();
println!("Test Directory: {}", temp_dir.display());
let dir_path = temp_dir.join("test_dir").join("test_sub_dir");
assert!(create_dir(&dir_path).is_ok());
assert!(temp_dir.join("test_dir").is_dir());
assert!(temp_dir.join("test_dir").join("test_sub_dir").is_dir());
fs::remove_dir_all(temp_dir).unwrap();
}
#[test]
fn test_remove_file() {
let temp_dir = testdir!();
println!("Test Directory: {}", temp_dir.display());
let test_file_root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
.join("tests")
.join("test_repo")
.join("first.rs");
fs::copy(test_file_root, temp_dir.join("first.rs")).unwrap();
let result = remove_file(temp_dir.join("first.rs"));
assert!(result.is_ok());
let oepn_result = File::open(temp_dir.join("first.rs"));
assert!(oepn_result.is_err());
let result = remove_file(temp_dir.join("second.rs"));
assert!(result.is_err());
fs::remove_dir_all(temp_dir).unwrap();
}
#[test]
fn test_remove_dir_all() {
let temp_dir = testdir!();
println!("Test Directory: {}", temp_dir.display());
let test_file_root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
.join("tests")
.join("test_repo")
.join("first.rs");
let test_file2_root = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
.join("tests")
.join("test_repo")
.join("second.rs");
fs::copy(test_file_root, temp_dir.join("first.rs")).unwrap();
fs::copy(test_file2_root, temp_dir.join("second.rs")).unwrap();
let result = remove_dir_all(&temp_dir);
assert!(result.is_ok());
let oepn_result = File::open(temp_dir.join("first.rs"));
assert!(oepn_result.is_err());
let result = remove_file(temp_dir);
assert!(result.is_err());
}
#[test]
fn test_exists_repo() {
let temp_dir = testdir!();
println!("Test Directory: {}", temp_dir.display());
let nss_dir = temp_dir.join(".nss");
fs::create_dir(&nss_dir).unwrap();
let result = exists_repo(Some(temp_dir.clone()));
assert!(result.is_ok());
assert_eq!(result.unwrap(), temp_dir);
let result = exists_repo(Some(temp_dir.as_path()));
assert!(result.is_ok());
assert_eq!(result.unwrap(), temp_dir);
let result = exists_repo::<PathBuf>(None);
assert!(result.is_err());
fs::remove_dir_all(temp_dir).unwrap();
}
}