2024-08-24 00:45:16 +02:00
|
|
|
use std::{env::current_dir, path::PathBuf};
|
2024-08-23 23:22:35 +02:00
|
|
|
|
|
|
|
use serde::Deserialize;
|
|
|
|
|
|
|
|
const CUDDLE_FILE_NAME: &str = "cuddle.toml";
|
|
|
|
|
2024-08-24 00:45:16 +02:00
|
|
|
pub struct ProjectPlan {
|
2024-08-23 23:22:35 +02:00
|
|
|
config: Config,
|
2024-08-24 00:45:16 +02:00
|
|
|
pub root: PathBuf,
|
2024-08-23 23:22:35 +02:00
|
|
|
}
|
|
|
|
|
2024-08-24 00:45:16 +02:00
|
|
|
impl ProjectPlan {
|
|
|
|
pub fn new(config: Config, root: PathBuf) -> Self {
|
|
|
|
Self { config, root }
|
2024-08-23 23:22:35 +02:00
|
|
|
}
|
|
|
|
|
2024-08-24 00:45:16 +02:00
|
|
|
pub fn from_file(content: &str, root: PathBuf) -> anyhow::Result<Self> {
|
2024-08-23 23:22:35 +02:00
|
|
|
let config: Config = toml::from_str(&content)?;
|
|
|
|
|
2024-08-24 00:45:16 +02:00
|
|
|
Ok(Self::new(config, root))
|
2024-08-23 23:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
pub async fn from_current_path() -> anyhow::Result<Option<Self>> {
|
|
|
|
let cur_dir = current_dir()?;
|
|
|
|
let cuddle_file = cur_dir.join(CUDDLE_FILE_NAME);
|
|
|
|
|
2024-08-24 00:45:16 +02:00
|
|
|
tracing::trace!(
|
|
|
|
path = cuddle_file.display().to_string(),
|
|
|
|
"searching for cuddle.toml project file"
|
|
|
|
);
|
|
|
|
|
2024-08-23 23:22:35 +02:00
|
|
|
if !cuddle_file.exists() {
|
2024-08-24 00:45:16 +02:00
|
|
|
tracing::debug!("no cuddle.toml project file found");
|
2024-08-23 23:22:35 +02:00
|
|
|
// 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?;
|
|
|
|
|
2024-08-24 00:45:16 +02:00
|
|
|
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,
|
|
|
|
}
|
2024-08-23 23:22:35 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-08-24 00:45:16 +02:00
|
|
|
pub enum Plan {
|
|
|
|
None,
|
|
|
|
Git(String),
|
|
|
|
Folder(PathBuf),
|
|
|
|
}
|
|
|
|
|
2024-08-23 23:22:35 +02:00
|
|
|
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
|
|
|
pub struct Config {
|
2024-08-24 00:45:16 +02:00
|
|
|
plan: Option<PlanConfig>,
|
2024-08-23 23:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
2024-08-24 00:45:16 +02:00
|
|
|
#[serde(untagged)]
|
|
|
|
pub enum PlanConfig {
|
|
|
|
Bare(String),
|
|
|
|
Git { git: String },
|
|
|
|
Folder { path: PathBuf },
|
2024-08-23 23:22:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_can_parse_simple_file() -> anyhow::Result<()> {
|
2024-08-24 00:45:16 +02:00
|
|
|
let project = ProjectPlan::from_file(
|
2024-08-23 23:22:35 +02:00
|
|
|
r##"
|
2024-08-24 00:45:16 +02:00
|
|
|
[plan]
|
|
|
|
git = "https://github.com/kjuulh/some-cuddle-project"
|
2024-08-23 23:22:35 +02:00
|
|
|
"##,
|
2024-08-24 00:45:16 +02:00
|
|
|
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(),
|
2024-08-23 23:22:35 +02:00
|
|
|
)?;
|
|
|
|
|
|
|
|
assert_eq!(
|
|
|
|
Config {
|
2024-08-24 00:45:16 +02:00
|
|
|
plan: Some(PlanConfig::Bare(
|
|
|
|
"https://github.com/kjuulh/some-cuddle-project".into()
|
|
|
|
))
|
2024-08-23 23:22:35 +02:00
|
|
|
},
|
|
|
|
project.config
|
|
|
|
);
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
2024-08-24 00:45:16 +02:00
|
|
|
|
|
|
|
#[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(())
|
|
|
|
}
|
2024-08-23 23:22:35 +02:00
|
|
|
}
|