feat: expose the plan model from the reconciler

This commit is contained in:
Kasper Juul Hermansen 2025-02-13 23:14:17 +01:00
parent b629bcf924
commit c1bbf6a69e
Signed by: kjuulh
SSH Key Fingerprint: SHA256:RjXh0p7U6opxnfd3ga/Y9TCo18FYlHFdSpRIV72S/QM
3 changed files with 54 additions and 9 deletions

View File

@ -4,7 +4,11 @@ use clap::{Parser, Subcommand};
use kdl::KdlDocument; use kdl::KdlDocument;
use rusty_s3::{Bucket, Credentials, S3Action}; use rusty_s3::{Bucket, Credentials, S3Action};
use crate::{model::Project, plan_reconciler::PlanReconciler, state::SharedState}; use crate::{
model::{Plan, Project},
plan_reconciler::PlanReconciler,
state::SharedState,
};
#[derive(Parser)] #[derive(Parser)]
#[command(author, version, about, long_about = None, subcommand_required = true)] #[command(author, version, about, long_about = None, subcommand_required = true)]
@ -64,11 +68,18 @@ pub async fn execute() -> anyhow::Result<()> {
let project_doc: KdlDocument = project_file.parse()?; let project_doc: KdlDocument = project_file.parse()?;
let project: Project = project_doc.try_into()?; let project: Project = project_doc.try_into()?;
tracing::trace!("found a project name: {}, {:?}", project.name, project); tracing::trace!("found a project name: {}", project.name);
PlanReconciler::new() if let Some(plan_file_path) = PlanReconciler::new()
.reconcile(&project, &project_path) .reconcile(&project, &project_path)
.await?; .await?
{
let plan_file = tokio::fs::read_to_string(&plan_file_path).await?;
let plan_doc: KdlDocument = plan_file.parse()?;
let project: Plan = plan_doc.try_into()?;
tracing::trace!("found a plan name: {}", project.name);
}
} }
Commands::Serve { Commands::Serve {

View File

@ -2,6 +2,36 @@ use std::path::PathBuf;
use kdl::{KdlDocument, KdlNode, KdlValue}; use kdl::{KdlDocument, KdlNode, KdlValue};
#[derive(Debug, Clone)]
pub struct Plan {
pub name: String,
}
impl TryFrom<KdlDocument> for Plan {
type Error = anyhow::Error;
fn try_from(value: KdlDocument) -> Result<Self, Self::Error> {
let plan_section = value.get("plan").ok_or(anyhow::anyhow!(
"forest.kdl plan file must have a plan object"
))?;
let plan_children = plan_section
.children()
.ok_or(anyhow::anyhow!("a forest plan must have children"))?;
Ok(Self {
name: plan_children
.get_arg("name")
.and_then(|n| match n {
KdlValue::String(s) => Some(s),
_ => None,
})
.cloned()
.ok_or(anyhow::anyhow!("a forest kuddle plan must have a name"))?,
})
}
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum ProjectPlan { pub enum ProjectPlan {
Local { path: PathBuf }, Local { path: PathBuf },

View File

@ -1,4 +1,4 @@
use std::path::Path; use std::path::{Path, PathBuf};
use anyhow::Context; use anyhow::Context;
@ -14,11 +14,15 @@ impl PlanReconciler {
Self {} Self {}
} }
pub async fn reconcile(&self, project: &Project, destination: &Path) -> anyhow::Result<()> { pub async fn reconcile(
&self,
project: &Project,
destination: &Path,
) -> anyhow::Result<Option<PathBuf>> {
tracing::info!("reconciling project"); tracing::info!("reconciling project");
if project.plan.is_none() { if project.plan.is_none() {
tracing::debug!("no plan, returning"); tracing::debug!("no plan, returning");
return Ok(()); return Ok(None);
} }
// prepare the plan dir // prepare the plan dir
@ -41,12 +45,12 @@ impl PlanReconciler {
} }
crate::model::ProjectPlan::NoPlan => { crate::model::ProjectPlan::NoPlan => {
tracing::debug!("no plan, returning"); tracing::debug!("no plan, returning");
return Ok(()); return Ok(None);
} }
} }
tracing::info!("recociled project"); tracing::info!("recociled project");
Ok(()) Ok(Some(plan_dir.join("forest.kdl")))
} }
} }