use std::env;
use crate::core::config::Config;
use crate::utils::errors::CustomError;
use crate::utils::{git, PathBufExtensions, Return};
use crate::core::work_item::WorkItem;
use serde::{Deserialize, Serialize};
use std::path::{Path, PathBuf};
#[derive(Serialize)]
#[derive(Deserialize)]
#[derive(Clone)]
pub struct Project {
pub repository: PathBuf,
pub worktrees: PathBuf,
}
impl Project {
pub fn work_on(&self, config: Config, work_type: &str, work_name: &str) -> Result<Return, CustomError> {
let work_branch = config.work_type_from_name(work_type)?.prefix.to_string() + &work_name;
let work_dir = &self.worktrees.join(&work_branch);
if !Path::exists(&work_dir) {
if git::branch_exists(work_branch.clone())? {
git::checkout_worktree(work_dir, &work_branch)?;
} else {
git::new_worktree(work_dir, work_branch)?;
}
}
Ok(Return::Cd { path: work_dir.to_path_buf() })
}
pub fn review(&self, branch: &str) -> Result<Return, CustomError> {
let directory = self.worktrees.join(&branch);
match Path::exists(&directory) {
true => Ok(Return::Cd { path: directory }),
false => {
git::checkout_worktree(&directory, branch)?;
Ok(Return::Cd { path: directory })
}
}
}
pub fn current_work_item(&self) -> Result<WorkItem, CustomError> {
if env::current_dir()? == self.repository {
return Err(CustomError::Custom("Current directory is the main working tree".to_string()));
}
let current_dir = std::env::current_dir().map_err(|error| CustomError::IoError(error))?;
let worktrees_dir_len = self.worktrees.to_str_result()?.len() + 1;
let name = ¤t_dir.to_str_result()?[worktrees_dir_len..];
Ok(WorkItem { name: name.to_string(), path: current_dir })
}
}