kjuulh 1ba6cf79c0
feat: fix minor bugs
Signed-off-by: kjuulh <contact@kjuulh.io>
2024-08-24 14:55:26 +02:00

112 lines
2.3 KiB
Rust

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(())
}
}