use crate::core::config::Config;
use crate::core::work_item::WorkItem;
use crate::utils::errors::CustomError;
use crate::utils::{git, PathBufExtensions, Return};
use serde::{Deserialize, Serialize};
use std::env;
use std::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;
self.review(&work_branch)
}
pub fn review(&self, work_branch: &str) -> Result<Return, CustomError> {
let work_dir = self.worktrees.join(&work_branch);
if work_dir.exists() && !git::is_valid_worktree(&work_dir) {
Err(CustomError::Custom(format!("Worktree directory exists, but is missing a .git directory at '{}'.", work_dir.display())))
} else {
if !work_dir.exists() {
git::checkout_new_or_existing_worktree(&work_dir, &work_branch)?;
}
Ok(Return::Cd { path: work_dir.to_path_buf() })
}
}
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 = 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 })
}
}