use std::{
fs::create_dir_all,
path::{Path, PathBuf},
};
use git2::Repository;
use crate::errors::DiaryError;
pub struct InitOptions {
pub path: PathBuf,
pub prefix: Option<String>,
pub git_repo: bool,
}
enum InitStatus {
UseConfig(PathBuf),
UseOpt(PathBuf),
}
fn establish_path(opts: &InitOptions, potential_path: &Path) -> Result<InitStatus, DiaryError> {
if potential_path == PathBuf::from("") {
let diary_path = opts.path.join("diary");
if diary_path.exists() {
return Err(DiaryError::ExistsHere);
}
Ok(InitStatus::UseOpt(diary_path))
} else if potential_path.exists() {
Err(DiaryError::ExistsElsewhere)
} else {
Ok(InitStatus::UseConfig(potential_path.to_path_buf()))
}
}
pub fn init(opts: &InitOptions, potential_path: &Path) -> Result<PathBuf, DiaryError> {
let init_status = establish_path(opts, potential_path);
let path = match init_status? {
InitStatus::UseConfig(path) => {
print!("It appears the config file already has a diary path set. ");
println!("Creating a diary folder here: {:?}", path);
path
}
InitStatus::UseOpt(path) => {
println!("Creating a diary folder.");
path
}
};
let path = match create_dir_all(&path) {
Ok(_) => path,
Err(e) => return Err(DiaryError::from(e)), };
if opts.git_repo {
match Repository::init(&path) {
Ok(_) => (),
Err(e) => return Err(DiaryError::from(e)), };
};
Ok(path)
}
#[cfg(test)]
mod tests {
use std::fs::create_dir_all;
use super::{init, InitOptions};
use crate::{config::Config, ops::testing};
#[test]
fn blank_config_valid_path() {
let dir = testing::temp_path();
let diary_dir = dir.join("diary");
let opts = InitOptions {
path: dir,
prefix: None,
git_repo: false,
};
let config = Config::default();
init(&opts, config.diary_path()).unwrap();
assert!(diary_dir.exists());
}
#[test]
fn blank_config_invalid_path() {
let dir = testing::temp_path();
let diary_dir = dir.join("diary");
let opts = InitOptions {
path: dir,
prefix: None,
git_repo: false,
};
let config = Config::default();
create_dir_all(diary_dir).unwrap();
init(&opts, config.diary_path()).expect_err("No error produced.");
}
#[test]
fn filled_config_non_existing_path() {
let dir = testing::temp_path();
let diary_dir = dir.join("diary");
let config = Config::builder().diary_path(diary_dir.clone()).build();
let opts = InitOptions {
path: testing::temp_path(),
prefix: None,
git_repo: false,
};
init(&opts, config.diary_path()).unwrap();
assert!(diary_dir.exists());
}
#[test]
fn filled_config_existing_path() {
let dir = testing::temp_path();
let diary_dir = dir.join("diary");
let config = Config::builder().diary_path(diary_dir.clone()).build();
let opts = InitOptions {
path: testing::temp_path(),
prefix: None,
git_repo: false,
};
create_dir_all(diary_dir).unwrap();
init(&opts, config.diary_path()).expect_err("No error produced.");
}
#[test]
fn blank_config_valid_path_git_repo() {
let dir = testing::temp_path();
let mut diary_dir = dir.join("diary");
let opts = InitOptions {
path: dir,
prefix: None,
git_repo: true,
};
let config = Config::default();
init(&opts, config.diary_path()).unwrap();
diary_dir.push(".git");
assert!(diary_dir.exists());
}
#[test]
fn filled_config_non_existing_path_git_repo() {
let dir = testing::temp_path();
let mut diary_dir = dir.join("diary");
let config = Config::builder().diary_path(diary_dir.clone()).build();
let opts = InitOptions {
path: testing::temp_path(),
prefix: None,
git_repo: true,
};
init(&opts, config.diary_path()).unwrap();
diary_dir.push(".git");
assert!(diary_dir.exists());
}
#[test]
fn filled_config_existing_path_git_repo() {
let dir = testing::temp_path();
let diary_dir = dir.join("diary");
let config = Config::builder().diary_path(diary_dir.clone()).build();
let opts = InitOptions {
path: testing::temp_path(),
prefix: None,
git_repo: true,
};
create_dir_all(diary_dir).unwrap();
init(&opts, config.diary_path()).expect_err("No error produced.");
}
}