Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
vkleen committed May 24, 2023
1 parent aae6d37 commit 5ad3fbb
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 43 deletions.
42 changes: 27 additions & 15 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions tf-ncl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ serde = { version = "1.0", features = ["derive"] }
nickel-lang = "0.3.1"
pretty = "0.11"
codespan = "0.11.1"
thiserror = "1.0.40"

[dev-dependencies]
pretty_assertions = "1.3"
57 changes: 47 additions & 10 deletions tf-ncl/src/intermediate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,17 @@ pub struct SplitSchema {
pub core_schema: GoSchema,
}

#[derive(Debug)]
#[derive(thiserror::Error, Debug)]
pub enum SplittingError {
#[error("leftover top-level computed fields found")]
LeftoverComputedFields,
#[error("Missing top-level block {field}")]
MissingBlock { field: &'static str },
#[error("expected {field} to be an object")]
ExpectedObject { field: &'static str },
#[error("expected {field} to be a list of objects")]
ExpectedListOfObjects { field: String },
#[error("missing provider {provider}")]
MissingProvider { provider: String },
}

Expand Down Expand Up @@ -199,17 +204,23 @@ impl GoSchema {
return Err(SplittingError::LeftoverComputedFields);
}

let resource = self
.schema
.remove("resource")
.ok_or(SplittingError::MissingBlock { field: "resource" })?;

let data = self
.schema
.remove("data")
.ok_or(SplittingError::MissingBlock { field: "data" })?;

Ok(SplitSchema {
resources: self
.schema
.remove("resource")
.ok_or(SplittingError::MissingBlock { field: "resource" })?
resources: resource
.clone()
.into_object_content()
.ok_or(SplittingError::ExpectedObject { field: "resource" })?,
data_sources: self
.schema
.remove("data")
.ok_or(SplittingError::MissingBlock { field: "data" })?
data_sources: data
.clone()
.into_object_content()
.ok_or(SplittingError::ExpectedObject { field: "data" })?,
provider_schema: self
Expand All @@ -226,7 +237,33 @@ impl GoSchema {
.ok_or(SplittingError::ExpectedListOfObjects {
field: format!("provider.{}", provider.as_ref()),
})?,
core_schema: self,
core_schema: {
self.schema.insert(
String::from("resource"),
Attribute {
description: resource.description,
optional: true,
computed: false,
type_: Type::Object {
open: true,
content: HashMap::new(),
},
},
);
self.schema.insert(
String::from("data"),
Attribute {
description: data.description,
optional: true,
computed: false,
type_: Type::Object {
open: true,
content: HashMap::new(),
},
},
);
self
},
})
}
}
25 changes: 13 additions & 12 deletions tf-ncl/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,21 +89,22 @@ impl<'a, 'b> fmt::Display for Display<'a, 'b> {
fn main() -> anyhow::Result<()> {
let opts = Args::parse();

// let providers = get_providers(&opts)?;
let go_schema = get_schema(&opts)?.push_down_computed_fields();

let split_schema = dbg!(go_schema.split_for_provider("github"));
let split_schema = dbg!(go_schema.split_for_provider("github")?);

Ok(())
let mut schema_terms = HashMap::from([(
PathBuf::from("core.nix"),
split_schema.core_schema.as_nickel_term(),
)]);
split_schema.as_nickel(&mut schema_terms);

// let doc: RenderableSchema = go_schema.with_providers(providers).into();
let doc = RenderableSchema {
schemas: schema_terms
.into_iter()
.map(|(k, v)| (k, v.pretty(&BoxAllocator).into_doc()))
.collect(),
};

// let doc = RenderableSchema {
// schemas: schema_docs
// .into_iter()
// .map(|(k, v)| (k, v.pretty(&BoxAllocator).into_doc()))
// .collect(),
// };

// doc.render(&opts.output_directory)
doc.render(&opts.output_directory)
}
46 changes: 40 additions & 6 deletions tf-ncl/src/nickel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::collections::HashMap;
use std::path::PathBuf;
use std::rc::Rc;

use crate::intermediate::{self, FieldDescriptor, GoSchema, Providers, WithProviders};
use crate::intermediate::{self, FieldDescriptor, GoSchema, Providers, SplitSchema, WithProviders};
use crate::nickel_builder::{self as builder, Types};
use crate::terraform::{TFProviderSchema, TFSchema};
use nickel_lang::term::array::{Array, ArrayAttrs};
Expand Down Expand Up @@ -37,16 +37,50 @@ impl AsNickel for TFProviderSchema {
}
}

impl AsNickel for SplitSchema {
fn as_nickel(&self, schemas: &mut HashMap<PathBuf, RichTerm>) {
schemas.extend(self.resources.iter().map(|(resource, schema)| {
match &schema.type_ {
intermediate::Type::Dictionary {
inner,
prefix: _,
computed_fields: _,
} => match inner.as_ref() {
intermediate::Type::Object { open, content } => (
PathBuf::new()
.join("resource")
.join(resource)
.with_extension("ncl"),
as_nickel_record(content).set_open(*open).build(),
),
_ => unimplemented!(),
},
_ => unimplemented!(),
}
}));

schemas.extend(self.data_sources.iter().map(|(data_source, schema)| {
(
PathBuf::new()
.join("data")
.join(data_source)
.with_extension("ncl"),
schema
.as_nickel_field(builder::Field::name(data_source))
.with_record(builder::Record::new())
.build(),
)
}));
}
}

pub trait AsNickelTerm {
fn as_nickel_term(&self) -> RichTerm;
}

impl AsNickelTerm for WithProviders<GoSchema> {
impl AsNickelTerm for GoSchema {
fn as_nickel_term(&self) -> RichTerm {
as_nickel_record(&self.data.schema)
.path(["terraform", "required_providers"])
.value(self.providers.as_nickel_term())
.build()
as_nickel_record(&self.schema).build()
}
}

Expand Down

0 comments on commit 5ad3fbb

Please sign in to comment.