Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
parent
c2b7e44ea3
commit
1ba6cf79c0
@ -0,0 +1 @@
|
|||||||
|
[plan]
|
@ -1,2 +1,5 @@
|
|||||||
[plan]
|
[plan]
|
||||||
path = "../plan"
|
path = "../plan"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "basic"
|
||||||
|
2
crates/cuddle/examples/schema/plan/cuddle.plan.toml
Normal file
2
crates/cuddle/examples/schema/plan/cuddle.plan.toml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
[plan]
|
||||||
|
schema = { nickel = "schema.ncl" }
|
0
crates/cuddle/examples/schema/plan/cuddle.toml
Normal file
0
crates/cuddle/examples/schema/plan/cuddle.toml
Normal file
5
crates/cuddle/examples/schema/plan/schema.ncl
Normal file
5
crates/cuddle/examples/schema/plan/schema.ncl
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
ProjectSchema = {
|
||||||
|
name | String
|
||||||
|
}
|
||||||
|
}
|
4
crates/cuddle/src/lib.rs
Normal file
4
crates/cuddle/src/lib.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
mod plan;
|
||||||
|
mod project;
|
||||||
|
mod schema_validator;
|
||||||
|
mod state;
|
@ -1,8 +1,11 @@
|
|||||||
use plan::Plan;
|
use plan::{ClonedPlan, Plan};
|
||||||
use project::ProjectPlan;
|
use project::ProjectPlan;
|
||||||
|
use state::ValidatedState;
|
||||||
|
|
||||||
mod plan;
|
mod plan;
|
||||||
mod project;
|
mod project;
|
||||||
|
mod schema_validator;
|
||||||
|
mod state;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
@ -13,6 +16,8 @@ async fn main() -> anyhow::Result<()> {
|
|||||||
.prepare_project()
|
.prepare_project()
|
||||||
.await?
|
.await?
|
||||||
.prepare_plan()
|
.prepare_plan()
|
||||||
|
.await?
|
||||||
|
.build_state()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -25,7 +30,7 @@ struct PrepareProject {
|
|||||||
|
|
||||||
struct PreparePlan {
|
struct PreparePlan {
|
||||||
project: Option<ProjectPlan>,
|
project: Option<ProjectPlan>,
|
||||||
plan: Option<Plan>,
|
plan: Option<ClonedPlan>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Cuddle<S = Start> {
|
struct Cuddle<S = Start> {
|
||||||
@ -54,13 +59,32 @@ impl Cuddle<Start> {
|
|||||||
|
|
||||||
impl Cuddle<PrepareProject> {
|
impl Cuddle<PrepareProject> {
|
||||||
pub async fn prepare_plan(&self) -> anyhow::Result<Cuddle<PreparePlan>> {
|
pub async fn prepare_plan(&self) -> anyhow::Result<Cuddle<PreparePlan>> {
|
||||||
if let Some(project) = &self.state.project {
|
let plan = if let Some(project) = &self.state.project {
|
||||||
match Plan::new().clone_from_project(project).await? {
|
Plan::new().clone_from_project(project).await?
|
||||||
Some(plan) => todo!(),
|
} else {
|
||||||
None => todo!(),
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Cuddle {
|
||||||
|
state: PreparePlan {
|
||||||
|
project: self.state.project.clone(),
|
||||||
|
plan,
|
||||||
|
},
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
todo!()
|
impl Cuddle<PreparePlan> {
|
||||||
|
pub async fn build_state(&self) -> anyhow::Result<Cuddle<ValidatedState>> {
|
||||||
|
let state = if let Some(project) = &self.state.project {
|
||||||
|
let state = state::State::new();
|
||||||
|
let raw_state = state.build_state(project, &self.state.plan).await?;
|
||||||
|
|
||||||
|
state.validate_state(&raw_state).await?
|
||||||
|
} else {
|
||||||
|
ValidatedState {}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Cuddle { state })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
use fs_extra::dir::CopyOptions;
|
use fs_extra::dir::CopyOptions;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::project::{self, ProjectPlan};
|
use crate::project::{self, ProjectPlan};
|
||||||
|
|
||||||
pub const CUDDLE_PLAN_FOLDER: &str = "plan";
|
pub const CUDDLE_PLAN_FOLDER: &str = "plan";
|
||||||
pub const CUDDLE_PROJECT_WORKSPACE: &str = ".cuddle";
|
pub const CUDDLE_PROJECT_WORKSPACE: &str = ".cuddle";
|
||||||
|
pub const CUDDLE_PLAN_FILE: &str = "cuddle.plan.toml";
|
||||||
|
|
||||||
pub trait PlanPathExt {
|
pub trait PlanPathExt {
|
||||||
fn plan_path(&self) -> PathBuf;
|
fn plan_path(&self) -> PathBuf;
|
||||||
@ -19,8 +21,60 @@ impl PlanPathExt for project::ProjectPlan {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Plan {}
|
pub struct RawPlan {
|
||||||
|
pub config: RawPlanConfig,
|
||||||
|
pub root: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RawPlan {
|
||||||
|
pub fn new(config: RawPlanConfig, root: &Path) -> Self {
|
||||||
|
Self {
|
||||||
|
config,
|
||||||
|
root: root.to_path_buf(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_file(content: &str, root: &Path) -> anyhow::Result<Self> {
|
||||||
|
let config: RawPlanConfig = toml::from_str(content)?;
|
||||||
|
|
||||||
|
Ok(Self::new(config, root))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn from_path(path: &Path) -> anyhow::Result<Self> {
|
||||||
|
let cuddle_file = path.join(CUDDLE_PLAN_FILE);
|
||||||
|
|
||||||
|
tracing::trace!(
|
||||||
|
path = cuddle_file.display().to_string(),
|
||||||
|
"searching for cuddle.toml project file"
|
||||||
|
);
|
||||||
|
|
||||||
|
if !cuddle_file.exists() {
|
||||||
|
anyhow::bail!("no cuddle.toml project file found");
|
||||||
|
}
|
||||||
|
|
||||||
|
let cuddle_plan_file = tokio::fs::read_to_string(cuddle_file).await?;
|
||||||
|
|
||||||
|
Self::from_file(&cuddle_plan_file, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
||||||
|
pub struct RawPlanConfig {
|
||||||
|
pub plan: RawPlanConfigSection,
|
||||||
|
}
|
||||||
|
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
||||||
|
pub struct RawPlanConfigSection {
|
||||||
|
pub schema: Option<RawPlanSchema>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
||||||
|
#[serde(untagged)]
|
||||||
|
pub enum RawPlanSchema {
|
||||||
|
Nickel { nickel: PathBuf },
|
||||||
|
JsonSchema { jsonschema: String },
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Plan {}
|
||||||
impl Plan {
|
impl Plan {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {}
|
Self {}
|
||||||
@ -113,8 +167,61 @@ impl Plan {
|
|||||||
.copy_inside(false),
|
.copy_inside(false),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
todo!()
|
Ok(ClonedPlan {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ClonedPlan {}
|
pub struct ClonedPlan {}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_can_parse_schema_plan() -> anyhow::Result<()> {
|
||||||
|
let plan = RawPlan::from_file(
|
||||||
|
r##"
|
||||||
|
[plan]
|
||||||
|
schema = {nickel = "contract.ncl"}
|
||||||
|
"##,
|
||||||
|
&PathBuf::new(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
RawPlanConfig {
|
||||||
|
plan: RawPlanConfigSection {
|
||||||
|
schema: Some(RawPlanSchema::Nickel {
|
||||||
|
nickel: "contract.ncl".into()
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plan.config,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_can_parse_json_schema() -> anyhow::Result<()> {
|
||||||
|
let plan = RawPlan::from_file(
|
||||||
|
r##"
|
||||||
|
[plan]
|
||||||
|
schema = {jsonschema = "schema.json"}
|
||||||
|
"##,
|
||||||
|
&PathBuf::new(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
RawPlanConfig {
|
||||||
|
plan: RawPlanConfigSection {
|
||||||
|
schema: Some(RawPlanSchema::JsonSchema {
|
||||||
|
jsonschema: "schema.json".into()
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plan.config,
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,28 +1,70 @@
|
|||||||
use std::{env::current_dir, path::PathBuf};
|
use std::{
|
||||||
|
env::current_dir,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
const CUDDLE_FILE_NAME: &str = "cuddle.toml";
|
pub const CUDDLE_PROJECT_FILE: &str = "cuddle.toml";
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct RawProject {
|
||||||
|
config: RawConfig,
|
||||||
|
pub root: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RawProject {
|
||||||
|
pub fn new(config: RawConfig, root: &Path) -> Self {
|
||||||
|
Self {
|
||||||
|
config,
|
||||||
|
root: root.to_path_buf(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_file(content: &str, root: &Path) -> anyhow::Result<Self> {
|
||||||
|
let config: RawConfig = toml::from_str(content)?;
|
||||||
|
|
||||||
|
Ok(Self::new(config, root))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn from_path(path: &Path) -> anyhow::Result<Self> {
|
||||||
|
let cuddle_file = path.join(CUDDLE_PROJECT_FILE);
|
||||||
|
|
||||||
|
tracing::trace!(
|
||||||
|
path = cuddle_file.display().to_string(),
|
||||||
|
"searching for cuddle.toml project file"
|
||||||
|
);
|
||||||
|
|
||||||
|
if !cuddle_file.exists() {
|
||||||
|
anyhow::bail!("no cuddle.toml project file found");
|
||||||
|
}
|
||||||
|
|
||||||
|
let cuddle_project_file = tokio::fs::read_to_string(cuddle_file).await?;
|
||||||
|
|
||||||
|
Self::from_file(&cuddle_project_file, path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct ProjectPlan {
|
pub struct ProjectPlan {
|
||||||
config: Config,
|
config: ProjectPlanConfig,
|
||||||
pub root: PathBuf,
|
pub root: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProjectPlan {
|
impl ProjectPlan {
|
||||||
pub fn new(config: Config, root: PathBuf) -> Self {
|
pub fn new(config: ProjectPlanConfig, root: PathBuf) -> Self {
|
||||||
Self { config, root }
|
Self { config, root }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_file(content: &str, root: PathBuf) -> anyhow::Result<Self> {
|
pub fn from_file(content: &str, root: PathBuf) -> anyhow::Result<Self> {
|
||||||
let config: Config = toml::from_str(&content)?;
|
let config: ProjectPlanConfig = toml::from_str(content)?;
|
||||||
|
|
||||||
Ok(Self::new(config, root))
|
Ok(Self::new(config, root))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn from_current_path() -> anyhow::Result<Option<Self>> {
|
pub async fn from_current_path() -> anyhow::Result<Option<Self>> {
|
||||||
let cur_dir = current_dir()?;
|
let cur_dir = current_dir()?;
|
||||||
let cuddle_file = cur_dir.join(CUDDLE_FILE_NAME);
|
let cuddle_file = cur_dir.join(CUDDLE_PROJECT_FILE);
|
||||||
|
|
||||||
tracing::trace!(
|
tracing::trace!(
|
||||||
path = cuddle_file.display().to_string(),
|
path = cuddle_file.display().to_string(),
|
||||||
@ -60,7 +102,17 @@ pub enum Plan {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
||||||
pub struct Config {
|
pub struct RawConfig {
|
||||||
|
project: ProjectConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
||||||
|
pub struct ProjectConfig {
|
||||||
|
name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize, PartialEq)]
|
||||||
|
pub struct ProjectPlanConfig {
|
||||||
plan: Option<PlanConfig>,
|
plan: Option<PlanConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +139,7 @@ git = "https://github.com/kjuulh/some-cuddle-project"
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Config {
|
ProjectPlanConfig {
|
||||||
plan: Some(PlanConfig::Git {
|
plan: Some(PlanConfig::Git {
|
||||||
git: "https://github.com/kjuulh/some-cuddle-project".into()
|
git: "https://github.com/kjuulh/some-cuddle-project".into()
|
||||||
})
|
})
|
||||||
@ -108,7 +160,7 @@ plan = "https://github.com/kjuulh/some-cuddle-project"
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
Config {
|
ProjectPlanConfig {
|
||||||
plan: Some(PlanConfig::Bare(
|
plan: Some(PlanConfig::Bare(
|
||||||
"https://github.com/kjuulh/some-cuddle-project".into()
|
"https://github.com/kjuulh/some-cuddle-project".into()
|
||||||
))
|
))
|
||||||
@ -123,7 +175,7 @@ plan = "https://github.com/kjuulh/some-cuddle-project"
|
|||||||
fn test_can_parse_simple_file_none() -> anyhow::Result<()> {
|
fn test_can_parse_simple_file_none() -> anyhow::Result<()> {
|
||||||
let project = ProjectPlan::from_file(r##""##, PathBuf::new())?;
|
let project = ProjectPlan::from_file(r##""##, PathBuf::new())?;
|
||||||
|
|
||||||
assert_eq!(Config { plan: None }, project.config);
|
assert_eq!(ProjectPlanConfig { plan: None }, project.config);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
30
crates/cuddle/src/schema_validator.rs
Normal file
30
crates/cuddle/src/schema_validator.rs
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
use nickel::NickelSchemaValidator;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
plan::{RawPlan, RawPlanSchema},
|
||||||
|
project::RawProject,
|
||||||
|
};
|
||||||
|
|
||||||
|
mod nickel;
|
||||||
|
|
||||||
|
pub struct SchemaValidator {}
|
||||||
|
|
||||||
|
impl SchemaValidator {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn validate(&self, plan: &RawPlan, project: &RawProject) -> anyhow::Result<Option<()>> {
|
||||||
|
let schema = match &plan.config.plan.schema {
|
||||||
|
Some(schema) => schema,
|
||||||
|
None => return Ok(None),
|
||||||
|
};
|
||||||
|
|
||||||
|
match schema {
|
||||||
|
RawPlanSchema::Nickel { nickel } => Ok(Some(NickelSchemaValidator::validate(
|
||||||
|
plan, project, nickel,
|
||||||
|
)?)),
|
||||||
|
RawPlanSchema::JsonSchema { jsonschema } => todo!("jsonschema not implemented yet"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
111
crates/cuddle/src/schema_validator/nickel.rs
Normal file
111
crates/cuddle/src/schema_validator/nickel.rs
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
use std::{
|
||||||
|
env::temp_dir,
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
plan::RawPlan,
|
||||||
|
project::{RawProject, CUDDLE_PROJECT_FILE},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub trait NickelPlanExt {
|
||||||
|
fn schema_path(&self, schema: &Path) -> PathBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NickelPlanExt for RawPlan {
|
||||||
|
fn schema_path(&self, schema: &Path) -> PathBuf {
|
||||||
|
self.root.join(schema)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait NickelProjectExt {
|
||||||
|
fn project_path(&self) -> PathBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NickelProjectExt for RawProject {
|
||||||
|
fn project_path(&self) -> PathBuf {
|
||||||
|
self.root.join(CUDDLE_PROJECT_FILE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unique_contract_file() -> anyhow::Result<TempDirGuard> {
|
||||||
|
let p = temp_dir()
|
||||||
|
.join("cuddle")
|
||||||
|
.join("nickel-contracts")
|
||||||
|
.join(Uuid::new_v4().to_string());
|
||||||
|
|
||||||
|
std::fs::create_dir_all(&p)?;
|
||||||
|
|
||||||
|
let file = p.join("contract.ncl");
|
||||||
|
|
||||||
|
Ok(TempDirGuard { dir: p, file })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct TempDirGuard {
|
||||||
|
dir: PathBuf,
|
||||||
|
file: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for TempDirGuard {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if let Err(e) = std::fs::remove_dir_all(&self.dir) {
|
||||||
|
panic!("failed to remove tempdir: {}", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::ops::Deref for TempDirGuard {
|
||||||
|
type Target = PathBuf;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.file
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct NickelSchemaValidator {}
|
||||||
|
impl NickelSchemaValidator {
|
||||||
|
pub fn validate(plan: &RawPlan, project: &RawProject, nickel: &Path) -> anyhow::Result<()> {
|
||||||
|
let nickel_file = plan.schema_path(nickel);
|
||||||
|
let cuddle_file = project.project_path();
|
||||||
|
|
||||||
|
let nickel_file = format!(
|
||||||
|
r##"
|
||||||
|
let {{ProjectSchema, ..}} = import "{}" in
|
||||||
|
|
||||||
|
let Schema = {{
|
||||||
|
project | ProjectSchema, ..
|
||||||
|
}} in
|
||||||
|
|
||||||
|
{{
|
||||||
|
|
||||||
|
config | Schema = import "{}"
|
||||||
|
}}
|
||||||
|
|
||||||
|
"##,
|
||||||
|
nickel_file.display(),
|
||||||
|
cuddle_file.display()
|
||||||
|
);
|
||||||
|
|
||||||
|
let contract_file = unique_contract_file()?;
|
||||||
|
|
||||||
|
std::fs::write(contract_file.as_path(), nickel_file)?;
|
||||||
|
|
||||||
|
let mut cmd = std::process::Command::new("nickel");
|
||||||
|
|
||||||
|
cmd.args(["export", &contract_file.display().to_string()]);
|
||||||
|
|
||||||
|
let output = cmd.output()?;
|
||||||
|
|
||||||
|
if !output.status.success() {
|
||||||
|
anyhow::bail!(
|
||||||
|
"failed to run nickel command: output: {} {}",
|
||||||
|
std::str::from_utf8(&output.stdout)?,
|
||||||
|
std::str::from_utf8(&output.stderr)?
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
45
crates/cuddle/src/state.rs
Normal file
45
crates/cuddle/src/state.rs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
use crate::{
|
||||||
|
plan::{self, ClonedPlan, PlanPathExt},
|
||||||
|
project::{self, ProjectPlan},
|
||||||
|
schema_validator::SchemaValidator,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct State {}
|
||||||
|
impl State {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn build_state(
|
||||||
|
&self,
|
||||||
|
project_plan: &ProjectPlan,
|
||||||
|
cloned_plan: &Option<ClonedPlan>,
|
||||||
|
) -> anyhow::Result<RawState> {
|
||||||
|
let project = project::RawProject::from_path(&project_plan.root).await?;
|
||||||
|
let plan = if let Some(_cloned_plan) = cloned_plan {
|
||||||
|
Some(plan::RawPlan::from_path(&project_plan.plan_path()).await?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(RawState { project, plan })
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn validate_state(&self, state: &RawState) -> anyhow::Result<ValidatedState> {
|
||||||
|
// 2. Prepare context for actions and components
|
||||||
|
|
||||||
|
if let Some(plan) = &state.plan {
|
||||||
|
SchemaValidator::new().validate(plan, &state.project)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Match against schema from plan
|
||||||
|
|
||||||
|
Ok(ValidatedState {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RawState {
|
||||||
|
project: project::RawProject,
|
||||||
|
plan: Option<plan::RawPlan>,
|
||||||
|
}
|
||||||
|
pub struct ValidatedState {}
|
Loading…
Reference in New Issue
Block a user