cuddle-v2/crates/cuddle/src/project.rs
kjuulh 531ea225f3
feat: add basic plan and project clone
Signed-off-by: kjuulh <contact@kjuulh.io>
2024-08-24 00:45:16 +02:00

131 lines
3.1 KiB
Rust

use std::{env::current_dir, path::PathBuf};
use serde::Deserialize;
const CUDDLE_FILE_NAME: &str = "cuddle.toml";
pub struct ProjectPlan {
config: Config,
pub root: PathBuf,
}
impl ProjectPlan {
pub fn new(config: Config, root: PathBuf) -> Self {
Self { config, root }
}
pub fn from_file(content: &str, root: PathBuf) -> anyhow::Result<Self> {
let config: Config = toml::from_str(&content)?;
Ok(Self::new(config, root))
}
pub async fn from_current_path() -> anyhow::Result<Option<Self>> {
let cur_dir = current_dir()?;
let cuddle_file = cur_dir.join(CUDDLE_FILE_NAME);
tracing::trace!(
path = cuddle_file.display().to_string(),
"searching for cuddle.toml project file"
);
if !cuddle_file.exists() {
tracing::debug!("no cuddle.toml project file found");
// We may want to recursively search for the file (towards root)
return Ok(None);
}
let cuddle_project_file = tokio::fs::read_to_string(cuddle_file).await?;
Ok(Some(Self::from_file(&cuddle_project_file, cur_dir)?))
}
pub fn has_plan(&self) -> bool {
self.config.plan.is_some()
}
pub fn get_plan(&self) -> Plan {
match &self.config.plan {
Some(PlanConfig::Bare(git)) | Some(PlanConfig::Git { git }) => Plan::Git(git.clone()),
Some(PlanConfig::Folder { path }) => Plan::Folder(path.clone()),
None => Plan::None,
}
}
}
pub enum Plan {
None,
Git(String),
Folder(PathBuf),
}
#[derive(Debug, Clone, Deserialize, PartialEq)]
pub struct Config {
plan: Option<PlanConfig>,
}
#[derive(Debug, Clone, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum PlanConfig {
Bare(String),
Git { git: String },
Folder { path: PathBuf },
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_can_parse_simple_file() -> anyhow::Result<()> {
let project = ProjectPlan::from_file(
r##"
[plan]
git = "https://github.com/kjuulh/some-cuddle-project"
"##,
PathBuf::new(),
)?;
assert_eq!(
Config {
plan: Some(PlanConfig::Git {
git: "https://github.com/kjuulh/some-cuddle-project".into()
})
},
project.config
);
Ok(())
}
#[test]
fn test_can_parse_simple_file_bare() -> anyhow::Result<()> {
let project = ProjectPlan::from_file(
r##"
plan = "https://github.com/kjuulh/some-cuddle-project"
"##,
PathBuf::new(),
)?;
assert_eq!(
Config {
plan: Some(PlanConfig::Bare(
"https://github.com/kjuulh/some-cuddle-project".into()
))
},
project.config
);
Ok(())
}
#[test]
fn test_can_parse_simple_file_none() -> anyhow::Result<()> {
let project = ProjectPlan::from_file(r##""##, PathBuf::new())?;
assert_eq!(Config { plan: None }, project.config);
Ok(())
}
}