mirror of
https://github.com/kjuulh/dagger-rs.git
synced 2025-12-28 18:51:02 +01:00
Compare commits
7 Commits
v0.2.8
...
46f0b4d841
| Author | SHA1 | Date | |
|---|---|---|---|
|
46f0b4d841
|
|||
|
af0464e45e
|
|||
|
12507188ca
|
|||
|
f41103a9fa
|
|||
|
58de5386e2
|
|||
|
3453e8cac6
|
|||
|
d0483b0434
|
@@ -1,155 +0,0 @@
|
|||||||
use std::{
|
|
||||||
io::{BufWriter, Write},
|
|
||||||
sync::Arc,
|
|
||||||
};
|
|
||||||
|
|
||||||
use dagger_core::introspection::{FullType, IntrospectionResponse, Schema};
|
|
||||||
use genco::{fmt, prelude::rust, prelude::*, quote};
|
|
||||||
|
|
||||||
use crate::handlers::{
|
|
||||||
enumeration::Enumeration, input::Input, object::Object, scalar::Scalar, DynHandler, Handlers,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[allow(dead_code)]
|
|
||||||
pub struct CodeGeneration {
|
|
||||||
handlers: Handlers,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CodeGeneration {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
handlers: vec![
|
|
||||||
Arc::new(Scalar {}),
|
|
||||||
Arc::new(Enumeration {}),
|
|
||||||
Arc::new(Input {}),
|
|
||||||
Arc::new(Object {}),
|
|
||||||
],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate(&self, schema: &IntrospectionResponse) -> eyre::Result<String> {
|
|
||||||
let code = self.generate_from_schema(
|
|
||||||
schema
|
|
||||||
.as_schema()
|
|
||||||
.schema
|
|
||||||
.as_ref()
|
|
||||||
.ok_or(eyre::anyhow!("could not get schema to generate code from"))?,
|
|
||||||
)?;
|
|
||||||
Ok(code)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn generate_from_schema(&self, schema: &Schema) -> eyre::Result<String> {
|
|
||||||
let mut output = rust::Tokens::new();
|
|
||||||
output.push();
|
|
||||||
output.append(quote! {
|
|
||||||
$(format!("// code generated by dagger. DO NOT EDIT."))
|
|
||||||
});
|
|
||||||
|
|
||||||
output.push();
|
|
||||||
output.append(render_base_types());
|
|
||||||
output.push();
|
|
||||||
|
|
||||||
let mut types = get_types(schema)?;
|
|
||||||
//let remaining: Vec<Option<String>> = types.into_iter().map(type_name).collect();
|
|
||||||
|
|
||||||
types.sort_by_key(|a| a.name.as_ref());
|
|
||||||
|
|
||||||
for (handler, types) in self.group_by_handlers(&types) {
|
|
||||||
for t in types {
|
|
||||||
if let Some(_) = self.type_name(&t) {
|
|
||||||
let rendered = handler.render(&t)?;
|
|
||||||
output.push();
|
|
||||||
output.append(rendered);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut buffer = BufWriter::new(Vec::new());
|
|
||||||
let mut w = fmt::IoWriter::new(buffer.by_ref());
|
|
||||||
let fmt = fmt::Config::from_lang::<Rust>().with_indentation(fmt::Indentation::Space(4));
|
|
||||||
let config = rust::Config::default();
|
|
||||||
// Prettier imports and use.
|
|
||||||
//.with_default_import(rust::ImportMode::Qualified);
|
|
||||||
|
|
||||||
output.format_file(&mut w.as_formatter(&fmt), &config)?;
|
|
||||||
|
|
||||||
let out = String::from_utf8(buffer.into_inner()?)?;
|
|
||||||
Ok(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn group_by_handlers(&self, types: &Vec<&FullType>) -> Vec<(DynHandler, Vec<FullType>)> {
|
|
||||||
let mut group = vec![];
|
|
||||||
|
|
||||||
for handler in self.handlers.iter() {
|
|
||||||
let mut group_types: Vec<FullType> = vec![];
|
|
||||||
for t in types.iter() {
|
|
||||||
if handler.predicate(*t) {
|
|
||||||
group_types.push(t.clone().clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
group.push((handler.clone(), group_types))
|
|
||||||
}
|
|
||||||
|
|
||||||
group
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn type_name(&self, t: &FullType) -> Option<String> {
|
|
||||||
let name = t.name.as_ref();
|
|
||||||
if let Some(name) = name {
|
|
||||||
if name.starts_with("_") {
|
|
||||||
//|| !is_custom_scalar_type(t) {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Some(name.replace("Query", "Client"));
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn group_key(&self, t: &FullType) -> Option<DynHandler> {
|
|
||||||
for handler in self.handlers.iter() {
|
|
||||||
if handler.predicate(&t) {
|
|
||||||
return Some(handler.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
fn sort_key(&self, t: &FullType) -> (isize, String) {
|
|
||||||
for (i, handler) in self.handlers.iter().enumerate() {
|
|
||||||
if handler.predicate(t) {
|
|
||||||
return (i as isize, t.name.as_ref().unwrap().clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (-1, t.name.as_ref().unwrap().clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_base_types() -> rust::Tokens {
|
|
||||||
let i = rust::import("dagger_core", "Int");
|
|
||||||
let b = rust::import("dagger_core", "Boolean");
|
|
||||||
|
|
||||||
quote! {
|
|
||||||
$(register(i))
|
|
||||||
$(register(b))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_types(schema: &Schema) -> eyre::Result<Vec<&FullType>> {
|
|
||||||
let types = schema
|
|
||||||
.types
|
|
||||||
.as_ref()
|
|
||||||
.ok_or(eyre::anyhow!("types not found on schema"))?;
|
|
||||||
|
|
||||||
let types: Vec<&FullType> = types
|
|
||||||
.iter()
|
|
||||||
.map(|t| t.as_ref().map(|t| &t.full_type))
|
|
||||||
.flatten()
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
Ok(types)
|
|
||||||
}
|
|
||||||
126
crates/dagger-codegen/src/functions.rs
Normal file
126
crates/dagger-codegen/src/functions.rs
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use dagger_core::introspection::{TypeRef, __TypeKind};
|
||||||
|
|
||||||
|
pub trait FormatTypeFuncs {
|
||||||
|
fn format_kind_list(&self, representation: &str) -> String;
|
||||||
|
fn format_kind_scalar_string(&self, representation: &str) -> String;
|
||||||
|
fn format_kind_scalar_int(&self, representation: &str) -> String;
|
||||||
|
fn format_kind_scalar_float(&self, representation: &str) -> String;
|
||||||
|
fn format_kind_scalar_boolean(&self, representation: &str) -> String;
|
||||||
|
fn format_kind_scalar_default(
|
||||||
|
&self,
|
||||||
|
representation: &str,
|
||||||
|
ref_name: &str,
|
||||||
|
input: bool,
|
||||||
|
) -> String;
|
||||||
|
fn format_kind_object(&self, representation: &str, ref_name: &str) -> String;
|
||||||
|
fn format_kind_input_object(&self, representation: &str, ref_name: &str) -> String;
|
||||||
|
fn format_kind_enum(&self, representation: &str, ref_name: &str) -> String;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type DynFormatTypeFuncs = Arc<dyn FormatTypeFuncs + Send + Sync>;
|
||||||
|
|
||||||
|
pub struct CommonFunctions {
|
||||||
|
format_type_funcs: DynFormatTypeFuncs,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CommonFunctions {
|
||||||
|
pub fn new(funcs: DynFormatTypeFuncs) -> Self {
|
||||||
|
Self {
|
||||||
|
format_type_funcs: funcs,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_input_type(&self, t: &TypeRef) -> String {
|
||||||
|
self.format_type(t, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format_output_type(&self, t: &TypeRef) -> String {
|
||||||
|
self.format_type(t, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_type(&self, t: &TypeRef, input: bool) -> String {
|
||||||
|
let mut representation = String::new();
|
||||||
|
let mut r = Some(t.clone());
|
||||||
|
while r.is_some() {
|
||||||
|
match r.as_ref() {
|
||||||
|
Some(rf) => match rf.kind.as_ref() {
|
||||||
|
Some(k) => match k {
|
||||||
|
__TypeKind::SCALAR => match Scalar::from(rf) {
|
||||||
|
Scalar::Int => {
|
||||||
|
self.format_type_funcs
|
||||||
|
.format_kind_scalar_int(&mut representation);
|
||||||
|
}
|
||||||
|
Scalar::Float => {
|
||||||
|
self.format_type_funcs
|
||||||
|
.format_kind_scalar_float(&mut representation);
|
||||||
|
}
|
||||||
|
Scalar::String => {
|
||||||
|
self.format_type_funcs
|
||||||
|
.format_kind_scalar_string(&mut representation);
|
||||||
|
}
|
||||||
|
Scalar::Boolean => {
|
||||||
|
self.format_type_funcs
|
||||||
|
.format_kind_scalar_boolean(&mut representation);
|
||||||
|
}
|
||||||
|
Scalar::Default => {
|
||||||
|
self.format_type_funcs.format_kind_scalar_default(
|
||||||
|
&mut representation,
|
||||||
|
rf.name.as_ref().unwrap(),
|
||||||
|
input,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
__TypeKind::OBJECT => {
|
||||||
|
self.format_type_funcs
|
||||||
|
.format_kind_object(&mut representation, rf.name.as_ref().unwrap());
|
||||||
|
}
|
||||||
|
__TypeKind::ENUM => {
|
||||||
|
self.format_type_funcs
|
||||||
|
.format_kind_enum(&mut representation, rf.name.as_ref().unwrap());
|
||||||
|
}
|
||||||
|
__TypeKind::INPUT_OBJECT => {
|
||||||
|
self.format_type_funcs.format_kind_input_object(
|
||||||
|
&mut representation,
|
||||||
|
&rf.name.as_ref().unwrap(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
__TypeKind::LIST => {
|
||||||
|
self.format_type_funcs.format_kind_list(&mut representation);
|
||||||
|
}
|
||||||
|
__TypeKind::Other(_) => {
|
||||||
|
r = rf.of_type.as_ref().map(|t| t.clone()).map(|t| *t)
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
},
|
||||||
|
None => break,
|
||||||
|
},
|
||||||
|
None => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
representation
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Scalar {
|
||||||
|
Int,
|
||||||
|
Float,
|
||||||
|
String,
|
||||||
|
Boolean,
|
||||||
|
Default,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&TypeRef> for Scalar {
|
||||||
|
fn from(value: &TypeRef) -> Self {
|
||||||
|
match value.name.as_ref().map(|n| n.as_str()) {
|
||||||
|
Some("Int") => Scalar::Int,
|
||||||
|
Some("Float") => Scalar::Float,
|
||||||
|
Some("String") => Scalar::String,
|
||||||
|
Some("Boolean") => Scalar::Boolean,
|
||||||
|
Some(_) => Scalar::Default,
|
||||||
|
None => Scalar::Default,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
crates/dagger-codegen/src/generator.rs
Normal file
21
crates/dagger-codegen/src/generator.rs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use dagger_core::introspection::Schema;
|
||||||
|
|
||||||
|
pub trait Generator {
|
||||||
|
fn generate(&self, schema: Schema) -> eyre::Result<String>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type DynGenerator = Arc<dyn Generator + Send + Sync>;
|
||||||
|
|
||||||
|
pub trait FormatTypeRefs {
|
||||||
|
fn format_kind_list(representation: &str) -> String;
|
||||||
|
fn format_kind_scalar_string(representation: &str) -> String;
|
||||||
|
fn format_kind_scalar_int(representation: &str) -> String;
|
||||||
|
fn format_kind_scalar_float(representation: &str) -> String;
|
||||||
|
fn format_kind_scalar_boolean(representation: &str) -> String;
|
||||||
|
fn format_kind_scalar_default(representation: &str, ref_name: &str, input: bool) -> String;
|
||||||
|
fn format_kind_object(representation: &str, ref_name: &str) -> String;
|
||||||
|
fn format_kind_input_object(representation: &str, ref_name: &str) -> String;
|
||||||
|
fn format_kind_enum(representation: &str, ref_name: &str) -> String;
|
||||||
|
}
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
use dagger_core::introspection::FullType;
|
|
||||||
use genco::{prelude::rust, quote};
|
|
||||||
|
|
||||||
use crate::predicates::is_enum_type;
|
|
||||||
|
|
||||||
use super::{utility::render_description, Handler};
|
|
||||||
|
|
||||||
pub struct Enumeration;
|
|
||||||
|
|
||||||
impl Handler for Enumeration {
|
|
||||||
fn predicate(&self, t: &FullType) -> bool {
|
|
||||||
is_enum_type(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&self, t: &FullType) -> eyre::Result<rust::Tokens> {
|
|
||||||
let name = t
|
|
||||||
.name
|
|
||||||
.as_ref()
|
|
||||||
.ok_or(eyre::anyhow!("could not get name from type"))?;
|
|
||||||
|
|
||||||
let description =
|
|
||||||
render_description(t).ok_or(eyre::anyhow!("could not find description"))?;
|
|
||||||
|
|
||||||
let out = quote! {
|
|
||||||
$description
|
|
||||||
pub enum $name {
|
|
||||||
// TODO: Add individual items
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
use convert_case::{Case, Casing};
|
|
||||||
use dagger_core::introspection::{FullTypeFields, FullTypeFieldsArgs};
|
|
||||||
use genco::{prelude::rust, quote};
|
|
||||||
|
|
||||||
use super::{
|
|
||||||
type_ref::{self, render_type_ref},
|
|
||||||
utility::{render_description_from_field, render_description_from_input_value},
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn render_fields(fields: &Vec<FullTypeFields>) -> eyre::Result<Option<rust::Tokens>> {
|
|
||||||
let mut collected_fields: Vec<rust::Tokens> = vec![];
|
|
||||||
for field in fields.iter() {
|
|
||||||
let name = field.name.as_ref().map(|n| n.to_case(Case::Snake)).unwrap();
|
|
||||||
let output = render_field_output(field)?;
|
|
||||||
let description = render_description_from_field(field);
|
|
||||||
let args = match field.args.as_ref() {
|
|
||||||
Some(a) => render_args(a),
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut tkns = rust::Tokens::new();
|
|
||||||
|
|
||||||
if let Some(args) = args.as_ref() {
|
|
||||||
tkns.append(quote! {
|
|
||||||
$description
|
|
||||||
pub struct $(&name)Args {
|
|
||||||
$(&args.args)
|
|
||||||
}
|
|
||||||
});
|
|
||||||
tkns.push();
|
|
||||||
}
|
|
||||||
|
|
||||||
tkns.append(quote! {
|
|
||||||
pub fn $(&name)(
|
|
||||||
&self,
|
|
||||||
$(if let Some(_) = args.as_ref() => args: $(&name)Args)
|
|
||||||
) -> $(&output) {
|
|
||||||
let query = self.selection.select($(field.name.as_ref().map(|n| format!("\"{}\"", n))));
|
|
||||||
$(if let Some(_) = args.as_ref() => query.args(args);)
|
|
||||||
|
|
||||||
$output {
|
|
||||||
conn: self.conn.clone(),
|
|
||||||
proc: self.proc.clone(),
|
|
||||||
selection: query,
|
|
||||||
}
|
|
||||||
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
collected_fields.push(tkns);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Some(quote! {
|
|
||||||
$(for field in collected_fields => $field $['\n'] )
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Arg {
|
|
||||||
name: String,
|
|
||||||
description: Option<rust::Tokens>,
|
|
||||||
type_: rust::Tokens,
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CollectedArgs {
|
|
||||||
description: Option<rust::Tokens>,
|
|
||||||
args: rust::Tokens,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_args(args: &[Option<FullTypeFieldsArgs>]) -> Option<CollectedArgs> {
|
|
||||||
let mut collected_args: Vec<Arg> = vec![];
|
|
||||||
|
|
||||||
for arg in args {
|
|
||||||
if let Some(arg) = arg.as_ref().map(|a| &a.input_value) {
|
|
||||||
let name = arg.name.clone();
|
|
||||||
let description = render_description_from_input_value(&arg, &name);
|
|
||||||
let t = render_type_ref(&arg.type_).unwrap();
|
|
||||||
|
|
||||||
collected_args.push(Arg {
|
|
||||||
name,
|
|
||||||
description,
|
|
||||||
type_: t,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if collected_args.len() > 0 {
|
|
||||||
let mut collected_arg = CollectedArgs {
|
|
||||||
description: Some(rust::Tokens::new()),
|
|
||||||
args: rust::Tokens::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
for arg in collected_args {
|
|
||||||
if let Some(desc) = arg.description {
|
|
||||||
if let Some(inner_desc) = collected_arg.description.as_mut() {
|
|
||||||
inner_desc.append(desc);
|
|
||||||
inner_desc.push();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
collected_arg.args.append(quote! {
|
|
||||||
$(arg.name.to_case(Case::Snake)): $(arg.type_),
|
|
||||||
});
|
|
||||||
collected_arg.args.push();
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(desc) = collected_arg.description.as_ref() {
|
|
||||||
if desc.is_empty() {
|
|
||||||
collected_arg.description = None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Some(collected_arg)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render_field_output(field: &FullTypeFields) -> eyre::Result<rust::Tokens> {
|
|
||||||
let inner = &field.type_.as_ref().unwrap();
|
|
||||||
type_ref::render_type_ref(&inner.type_ref)
|
|
||||||
}
|
|
||||||
@@ -1,110 +0,0 @@
|
|||||||
use dagger_core::introspection::FullType;
|
|
||||||
use genco::prelude::rust;
|
|
||||||
use genco::prelude::*;
|
|
||||||
|
|
||||||
use crate::predicates::is_input_object_type;
|
|
||||||
|
|
||||||
use super::{input_field::render_input_fields, utility::render_description, Handler};
|
|
||||||
|
|
||||||
pub struct Input;
|
|
||||||
|
|
||||||
impl Handler for Input {
|
|
||||||
fn predicate(&self, t: &FullType) -> bool {
|
|
||||||
is_input_object_type(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&self, t: &FullType) -> eyre::Result<rust::Tokens> {
|
|
||||||
let name = t
|
|
||||||
.name
|
|
||||||
.as_ref()
|
|
||||||
.ok_or(eyre::anyhow!("could not find name"))?;
|
|
||||||
let description = render_description(t);
|
|
||||||
|
|
||||||
//let input = rust::import("dagger_core", "Input");
|
|
||||||
|
|
||||||
let fields = match t.input_fields.as_ref() {
|
|
||||||
Some(i) => render_input_fields(i)?,
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let out = quote! {
|
|
||||||
$(if description.is_some() => $description)
|
|
||||||
pub struct $name {
|
|
||||||
$(if fields.is_some() => $fields)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use dagger_core::introspection::{
|
|
||||||
FullType, FullTypeInputFields, InputValue, TypeRef, __TypeKind,
|
|
||||||
};
|
|
||||||
use pretty_assertions::assert_eq;
|
|
||||||
|
|
||||||
use crate::handlers::Handler;
|
|
||||||
|
|
||||||
use super::Input;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_gen_input() {
|
|
||||||
let input = Input {};
|
|
||||||
let t = FullType {
|
|
||||||
kind: Some(__TypeKind::INPUT_OBJECT),
|
|
||||||
name: Some("BuildArg".into()),
|
|
||||||
description: None,
|
|
||||||
input_fields: Some(vec![
|
|
||||||
FullTypeInputFields {
|
|
||||||
input_value: InputValue {
|
|
||||||
name: "name".into(),
|
|
||||||
description: None,
|
|
||||||
type_: TypeRef {
|
|
||||||
name: None,
|
|
||||||
kind: Some(__TypeKind::NON_NULL),
|
|
||||||
of_type: Some(Box::new(TypeRef {
|
|
||||||
kind: Some(__TypeKind::SCALAR),
|
|
||||||
name: Some("String".into()),
|
|
||||||
of_type: None,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
default_value: None,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
FullTypeInputFields {
|
|
||||||
input_value: InputValue {
|
|
||||||
name: "value".into(),
|
|
||||||
description: None,
|
|
||||||
type_: TypeRef {
|
|
||||||
name: None,
|
|
||||||
kind: Some(__TypeKind::NON_NULL),
|
|
||||||
of_type: Some(Box::new(TypeRef {
|
|
||||||
kind: Some(__TypeKind::SCALAR),
|
|
||||||
name: Some("String".into()),
|
|
||||||
of_type: None,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
default_value: None,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
interfaces: None,
|
|
||||||
enum_values: None,
|
|
||||||
possible_types: None,
|
|
||||||
fields: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let expected = r#"pub struct BuildArg {
|
|
||||||
pub name: String,
|
|
||||||
|
|
||||||
pub value: String,
|
|
||||||
}
|
|
||||||
"#;
|
|
||||||
|
|
||||||
let output = input.render(&t).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(output.to_file_string().unwrap(), expected);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
use dagger_core::introspection::FullTypeInputFields;
|
|
||||||
use genco::{prelude::rust, quote};
|
|
||||||
|
|
||||||
use super::type_ref;
|
|
||||||
|
|
||||||
pub fn render_input_fields(
|
|
||||||
input_fields: &Vec<FullTypeInputFields>,
|
|
||||||
) -> eyre::Result<Option<rust::Tokens>> {
|
|
||||||
let mut fields: Vec<(String, rust::Tokens)> = vec![];
|
|
||||||
for field in input_fields.iter() {
|
|
||||||
fields.push((field.input_value.name.clone(), render_input_field(field)?));
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(Some(quote! {
|
|
||||||
$(for (name, field) in fields => pub $name: $field, $['\n'] )
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render_input_field(field: &FullTypeInputFields) -> eyre::Result<rust::Tokens> {
|
|
||||||
let inner = &field.input_value.type_;
|
|
||||||
type_ref::render_type_ref(inner)
|
|
||||||
}
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
pub mod enumeration;
|
|
||||||
mod fields;
|
|
||||||
pub mod input;
|
|
||||||
mod input_field;
|
|
||||||
pub mod object;
|
|
||||||
pub mod scalar;
|
|
||||||
mod type_ref;
|
|
||||||
mod utility;
|
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
use dagger_core::introspection::FullType;
|
|
||||||
use genco::prelude::rust::Tokens;
|
|
||||||
use genco::prelude::*;
|
|
||||||
|
|
||||||
pub trait Handler {
|
|
||||||
fn predicate(&self, _t: &FullType) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&self, t: &FullType) -> eyre::Result<rust::Tokens> {
|
|
||||||
let tstruct = self.render_struct(t)?;
|
|
||||||
let timpl = self.render_impl(t)?;
|
|
||||||
let mut out = rust::Tokens::new();
|
|
||||||
out.append(tstruct);
|
|
||||||
out.push();
|
|
||||||
out.append(timpl);
|
|
||||||
out.push();
|
|
||||||
Ok(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_struct(&self, t: &FullType) -> eyre::Result<Tokens> {
|
|
||||||
let name = t.name.as_ref().ok_or(eyre::anyhow!("name not found"))?;
|
|
||||||
|
|
||||||
Ok(quote! {
|
|
||||||
pub struct $name {} {
|
|
||||||
// TODO: Add fields
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_impl(&self, t: &FullType) -> eyre::Result<Tokens> {
|
|
||||||
let name = t.name.as_ref().ok_or(eyre::anyhow!("name not found"))?;
|
|
||||||
|
|
||||||
Ok(quote! {
|
|
||||||
impl $name {} {
|
|
||||||
// TODO: Add fields
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type DynHandler = Arc<dyn Handler + Send + Sync>;
|
|
||||||
pub type Handlers = Vec<DynHandler>;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use dagger_core::introspection::FullType;
|
|
||||||
use pretty_assertions::assert_eq;
|
|
||||||
|
|
||||||
use super::Handler;
|
|
||||||
|
|
||||||
struct DefaultHandler;
|
|
||||||
impl Handler for DefaultHandler {}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn render_returns_expected() {
|
|
||||||
let handler = DefaultHandler {};
|
|
||||||
let t = FullType {
|
|
||||||
kind: None,
|
|
||||||
name: Some("SomeName".into()),
|
|
||||||
description: None,
|
|
||||||
fields: None,
|
|
||||||
input_fields: None,
|
|
||||||
interfaces: None,
|
|
||||||
enum_values: None,
|
|
||||||
possible_types: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let res = handler.render(&t).unwrap();
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
res.to_string().unwrap(),
|
|
||||||
"pub struct SomeName {} {
|
|
||||||
|
|
||||||
}
|
|
||||||
impl SomeName {} {
|
|
||||||
|
|
||||||
}"
|
|
||||||
.to_string()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,167 +0,0 @@
|
|||||||
use dagger_core::introspection::FullType;
|
|
||||||
use genco::{prelude::rust, quote};
|
|
||||||
|
|
||||||
use crate::predicates::is_object_type;
|
|
||||||
|
|
||||||
use super::{fields, input_field, utility::render_description, Handler};
|
|
||||||
|
|
||||||
pub struct Object;
|
|
||||||
|
|
||||||
impl Handler for Object {
|
|
||||||
fn predicate(&self, t: &FullType) -> bool {
|
|
||||||
is_object_type(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&self, t: &FullType) -> eyre::Result<rust::Tokens> {
|
|
||||||
let name = t
|
|
||||||
.name
|
|
||||||
.as_ref()
|
|
||||||
.ok_or(eyre::anyhow!("could not find name"))?;
|
|
||||||
let description = render_description(t);
|
|
||||||
|
|
||||||
let fields = match t.fields.as_ref() {
|
|
||||||
Some(i) => fields::render_fields(i)?,
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let input_fields = match t.input_fields.as_ref() {
|
|
||||||
Some(i) => input_field::render_input_fields(i)?,
|
|
||||||
None => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
let out = quote! {
|
|
||||||
$(if description.is_some() => $description)
|
|
||||||
pub struct $name {
|
|
||||||
$(if input_fields.is_some() => $input_fields)
|
|
||||||
}
|
|
||||||
|
|
||||||
impl $name {
|
|
||||||
$(if fields.is_some() => $fields)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(out)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use dagger_core::introspection::{
|
|
||||||
FullType, FullTypeFields, FullTypeFieldsArgs, FullTypeFieldsType, InputValue, TypeRef,
|
|
||||||
__TypeKind,
|
|
||||||
};
|
|
||||||
use pretty_assertions::assert_eq;
|
|
||||||
|
|
||||||
use crate::handlers::Handler;
|
|
||||||
|
|
||||||
use super::Object;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_render_object() {
|
|
||||||
let t: FullType = FullType {
|
|
||||||
kind: Some(__TypeKind::OBJECT),
|
|
||||||
name: Some("CacheVolume".into()),
|
|
||||||
description: Some("A directory whose contents persists across sessions".into()),
|
|
||||||
fields: Some(vec![FullTypeFields {
|
|
||||||
name: Some("id".into()),
|
|
||||||
description: None,
|
|
||||||
args: None,
|
|
||||||
type_: Some(FullTypeFieldsType {
|
|
||||||
type_ref: TypeRef {
|
|
||||||
kind: Some(__TypeKind::NON_NULL),
|
|
||||||
name: None,
|
|
||||||
of_type: Some(Box::new(TypeRef {
|
|
||||||
kind: Some(__TypeKind::SCALAR),
|
|
||||||
name: Some("CacheID".into()),
|
|
||||||
of_type: None,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
is_deprecated: Some(false),
|
|
||||||
deprecation_reason: None,
|
|
||||||
}]),
|
|
||||||
input_fields: None,
|
|
||||||
interfaces: None,
|
|
||||||
enum_values: None,
|
|
||||||
possible_types: None,
|
|
||||||
};
|
|
||||||
let expected = r#"
|
|
||||||
/// A directory whose contents persists across sessions
|
|
||||||
pub struct CacheVolume {}
|
|
||||||
|
|
||||||
impl CacheVolume {
|
|
||||||
pub fn id(
|
|
||||||
&self,
|
|
||||||
) -> CacheID {
|
|
||||||
let query = self.selection.select("id");
|
|
||||||
|
|
||||||
CacheID {
|
|
||||||
conn: self.conn.clone(),
|
|
||||||
proc: self.proc.clone(),
|
|
||||||
selection: query,
|
|
||||||
}
|
|
||||||
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"#;
|
|
||||||
let handler = Object {};
|
|
||||||
let obj = handler.render(&t).unwrap();
|
|
||||||
let actual = obj.to_file_string().unwrap();
|
|
||||||
|
|
||||||
assert_eq!(actual, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_render_query_container() {
|
|
||||||
let t: FullType = FullType {
|
|
||||||
kind: Some(__TypeKind::OBJECT),
|
|
||||||
name: Some("Query".into()),
|
|
||||||
description: None,
|
|
||||||
fields: Some(vec![FullTypeFields {
|
|
||||||
name: Some("container".into()),
|
|
||||||
description: Some("Loads a container from ID.\nNull ID returns an empty container (scratch).\nOptional platform argument initializes new containers to execute and publish as that platform. Platform defaults to that of the builder's host.".into()),
|
|
||||||
args: Some(
|
|
||||||
vec![
|
|
||||||
Some(
|
|
||||||
FullTypeFieldsArgs
|
|
||||||
{
|
|
||||||
input_value: InputValue { name: "id".into(), description: None, type_: TypeRef { kind: Some(__TypeKind::SCALAR), name: Some("ContainerID".into()), of_type: None }, default_value: None }
|
|
||||||
}
|
|
||||||
),
|
|
||||||
Some(
|
|
||||||
FullTypeFieldsArgs {
|
|
||||||
input_value: InputValue {
|
|
||||||
name: "platform".into(), description: None, type_: TypeRef { kind: Some(__TypeKind::SCALAR), name: Some("Platform".into()), of_type: None },
|
|
||||||
default_value: None }
|
|
||||||
})
|
|
||||||
]),
|
|
||||||
type_: Some(FullTypeFieldsType {
|
|
||||||
type_ref: TypeRef {
|
|
||||||
kind: Some(__TypeKind::NON_NULL),
|
|
||||||
name: None,
|
|
||||||
of_type: Some(Box::new(TypeRef {
|
|
||||||
kind: Some(__TypeKind::SCALAR),
|
|
||||||
name: Some("CacheID".into()),
|
|
||||||
of_type: None,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
is_deprecated: Some(false),
|
|
||||||
deprecation_reason: None,
|
|
||||||
}
|
|
||||||
]),
|
|
||||||
input_fields: None,
|
|
||||||
interfaces: None,
|
|
||||||
enum_values: None,
|
|
||||||
possible_types: None,
|
|
||||||
};
|
|
||||||
let expected = r#"
|
|
||||||
"#;
|
|
||||||
let handler = Object {};
|
|
||||||
let obj = handler.render(&t).unwrap();
|
|
||||||
let actual = obj.to_file_string().unwrap();
|
|
||||||
|
|
||||||
assert_eq!(actual, expected);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
use dagger_core::introspection::FullType;
|
|
||||||
use genco::{prelude::rust, quote};
|
|
||||||
|
|
||||||
use crate::predicates::is_custom_scalar_type;
|
|
||||||
|
|
||||||
use super::{utility::render_description, Handler};
|
|
||||||
|
|
||||||
pub struct Scalar;
|
|
||||||
|
|
||||||
impl Handler for Scalar {
|
|
||||||
fn predicate(&self, t: &FullType) -> bool {
|
|
||||||
is_custom_scalar_type(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render(&self, t: &FullType) -> eyre::Result<rust::Tokens> {
|
|
||||||
let mut out = rust::Tokens::new();
|
|
||||||
|
|
||||||
let description =
|
|
||||||
render_description(t).ok_or(eyre::anyhow!("could not find description"))?;
|
|
||||||
let tstruct = self.render_struct(t)?;
|
|
||||||
|
|
||||||
out.append(description);
|
|
||||||
out.push();
|
|
||||||
out.append(tstruct);
|
|
||||||
|
|
||||||
Ok(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_struct(&self, t: &FullType) -> eyre::Result<genco::prelude::rust::Tokens> {
|
|
||||||
let name = t.name.as_ref().ok_or(eyre::anyhow!("name not found"))?;
|
|
||||||
|
|
||||||
let scalar = rust::import("dagger_core", "Scalar");
|
|
||||||
|
|
||||||
Ok(quote! {
|
|
||||||
pub struct $name($scalar);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_impl(&self, _t: &FullType) -> eyre::Result<genco::prelude::rust::Tokens> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
use dagger_core::introspection::TypeRef;
|
|
||||||
use genco::prelude::rust;
|
|
||||||
use genco::prelude::*;
|
|
||||||
|
|
||||||
use crate::predicates::{
|
|
||||||
is_custom_scalar_type_ref, is_list_type, is_required_type_ref, is_scalar_type_ref,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn render_type_ref(inner: &TypeRef) -> eyre::Result<rust::Tokens> {
|
|
||||||
let extract_of_type = |t: &TypeRef| -> Option<TypeRef> {
|
|
||||||
return t.clone().of_type.map(|t| *t);
|
|
||||||
};
|
|
||||||
|
|
||||||
let (optional, inner) = if !is_required_type_ref(inner) {
|
|
||||||
(true, inner.clone())
|
|
||||||
} else {
|
|
||||||
(false, extract_of_type(inner).unwrap())
|
|
||||||
};
|
|
||||||
|
|
||||||
if is_list_type(&inner) {
|
|
||||||
if let Some(inner_of_type) = extract_of_type(&inner) {
|
|
||||||
let inner_field = render_type_ref(&inner_of_type)?;
|
|
||||||
if optional {
|
|
||||||
return Ok(quote! {
|
|
||||||
Option<Vec<$inner_field>>
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Ok(quote! {
|
|
||||||
Vec<$inner_field>
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if is_custom_scalar_type_ref(&inner) {
|
|
||||||
if let Some(inner_of_type) = extract_of_type(&inner) {
|
|
||||||
let inner_field = render_type_ref(&inner_of_type)?;
|
|
||||||
if optional {
|
|
||||||
return Ok(quote! {
|
|
||||||
Option<$inner_field>
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Ok(quote! {
|
|
||||||
$inner_field
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if is_scalar_type_ref(&inner) {
|
|
||||||
let name = match inner.name.as_ref().map(|s| s.as_str()) {
|
|
||||||
Some("ID") => "ID",
|
|
||||||
Some("Int") => "Int",
|
|
||||||
Some("String") => "String",
|
|
||||||
Some("Float") => "Float",
|
|
||||||
Some("Boolean") => "Boolean",
|
|
||||||
Some("Date") => "Date",
|
|
||||||
Some("DateTime") => "DateTime",
|
|
||||||
Some("Time") => "Time",
|
|
||||||
Some("Decimal") => "Decimal",
|
|
||||||
Some(n) => n,
|
|
||||||
_ => eyre::bail!("missing type in the end of chain"),
|
|
||||||
};
|
|
||||||
|
|
||||||
if optional {
|
|
||||||
return Ok(quote! {
|
|
||||||
Option<$name>
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(quote! {
|
|
||||||
$name
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(inner_type) = inner.of_type.as_ref() {
|
|
||||||
let inner_field = render_type_ref(&inner_type)?;
|
|
||||||
if optional {
|
|
||||||
return Ok(quote! {
|
|
||||||
Option<$inner_field>
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return Ok(inner_field);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(name) = inner.name.as_ref() {
|
|
||||||
if optional {
|
|
||||||
return Ok(quote! {
|
|
||||||
Option<$name>
|
|
||||||
});
|
|
||||||
}
|
|
||||||
return Ok(quote! {
|
|
||||||
$name
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
eyre::bail!("could not determine type")
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
use dagger_core::introspection::{FullType, FullTypeFields, InputValue};
|
|
||||||
use genco::{prelude::*, quote};
|
|
||||||
|
|
||||||
pub fn render_description(t: &FullType) -> Option<rust::Tokens> {
|
|
||||||
if let Some(description) = t.description.as_ref() {
|
|
||||||
let lines = description.split('\n');
|
|
||||||
let output: rust::Tokens = quote! {
|
|
||||||
$(for line in lines => $(format!("\n/// {line}")))
|
|
||||||
};
|
|
||||||
|
|
||||||
return Some(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render_description_from_field(t: &FullTypeFields) -> Option<rust::Tokens> {
|
|
||||||
if let Some(description) = t.description.as_ref() {
|
|
||||||
let lines = description.split('\n');
|
|
||||||
let output: rust::Tokens = quote! {
|
|
||||||
$(for line in lines => $(format!("\n/// {line}")))
|
|
||||||
};
|
|
||||||
|
|
||||||
return Some(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn render_description_from_input_value(t: &InputValue, name: &String) -> Option<rust::Tokens> {
|
|
||||||
if let Some(description) = t.description.as_ref() {
|
|
||||||
if description == "" {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
let lines = description.split('\n').collect::<Vec<&str>>();
|
|
||||||
let mut output = rust::Tokens::new();
|
|
||||||
|
|
||||||
if let Some(line) = lines.first() {
|
|
||||||
output.append(quote! {
|
|
||||||
$(format!("/// * `{name}` - {line}"))
|
|
||||||
});
|
|
||||||
output.push();
|
|
||||||
}
|
|
||||||
|
|
||||||
for line in lines.iter().skip(1) {
|
|
||||||
output.append(quote! {
|
|
||||||
$(format!("/// {line}"))
|
|
||||||
});
|
|
||||||
output.push();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Some(output);
|
|
||||||
}
|
|
||||||
|
|
||||||
None
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,12 @@
|
|||||||
pub mod codegen;
|
mod functions;
|
||||||
mod handlers;
|
mod generator;
|
||||||
mod models;
|
pub mod rust;
|
||||||
mod predicates;
|
mod visitor;
|
||||||
|
|
||||||
|
use dagger_core::introspection::Schema;
|
||||||
|
|
||||||
|
use self::generator::DynGenerator;
|
||||||
|
|
||||||
|
pub fn generate(schema: Schema, generator: DynGenerator) -> eyre::Result<String> {
|
||||||
|
generator.generate(schema)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
pub enum Scalars {
|
|
||||||
ID(String),
|
|
||||||
Int(usize),
|
|
||||||
String(String),
|
|
||||||
Float(f64),
|
|
||||||
Boolean(bool),
|
|
||||||
Date(String),
|
|
||||||
DateTime(String),
|
|
||||||
Time(String),
|
|
||||||
Decimal(f64),
|
|
||||||
}
|
|
||||||
@@ -1,101 +0,0 @@
|
|||||||
use dagger_core::introspection::{FullType, FullTypeInputFields, TypeRef, __TypeKind};
|
|
||||||
|
|
||||||
use crate::models::Scalars;
|
|
||||||
|
|
||||||
pub fn is_scalar_type(t: &FullType) -> bool {
|
|
||||||
if let Some(__TypeKind::SCALAR) = t.kind {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_scalar_type_ref(t: &TypeRef) -> bool {
|
|
||||||
if let Some(__TypeKind::SCALAR) = t.kind {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_enum_type(t: &FullType) -> bool {
|
|
||||||
if let Some(__TypeKind::ENUM) = t.kind {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_input_object_type(t: &FullType) -> bool {
|
|
||||||
if let Some(__TypeKind::INPUT_OBJECT) = t.kind {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_required_type(t: &FullTypeInputFields) -> bool {
|
|
||||||
match t.input_value.type_.kind {
|
|
||||||
Some(__TypeKind::NON_NULL) => return true,
|
|
||||||
Some(_) => return false,
|
|
||||||
_ => return false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_required_type_ref(t: &TypeRef) -> bool {
|
|
||||||
match t.kind {
|
|
||||||
Some(__TypeKind::NON_NULL) => return true,
|
|
||||||
Some(_) => return false,
|
|
||||||
_ => return false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_list_type(t: &TypeRef) -> bool {
|
|
||||||
if let Some(__TypeKind::LIST) = t.kind {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_object_type(t: &FullType) -> bool {
|
|
||||||
if let Some(__TypeKind::OBJECT) = t.kind {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_custom_scalar_type(t: &FullType) -> bool {
|
|
||||||
if is_scalar_type(t) {
|
|
||||||
// TODO: Insert scalar
|
|
||||||
let _ = match t.name.as_ref().map(|s| s.as_str()) {
|
|
||||||
Some("ID") => Scalars::ID("ID".into()),
|
|
||||||
Some("Int") => Scalars::Int(0),
|
|
||||||
Some("String") => Scalars::String("ID".into()),
|
|
||||||
Some("Float") => Scalars::Float(0.0),
|
|
||||||
Some("Boolean") => Scalars::Boolean(false),
|
|
||||||
Some("Date") => Scalars::Date("ID".into()),
|
|
||||||
Some("DateTime") => Scalars::DateTime("ID".into()),
|
|
||||||
Some("Time") => Scalars::Time("ID".into()),
|
|
||||||
Some("Decimal") => Scalars::Decimal(0.0),
|
|
||||||
Some(_) => return true,
|
|
||||||
None => return false,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is_custom_scalar_type_ref(t: &TypeRef) -> bool {
|
|
||||||
if is_scalar_type_ref(t) {
|
|
||||||
// TODO: Insert scalar
|
|
||||||
let _ = match t.name.as_ref().map(|s| s.as_str()) {
|
|
||||||
Some("ID") => Scalars::ID("ID".into()),
|
|
||||||
Some("Int") => Scalars::Int(0),
|
|
||||||
Some("String") => Scalars::String("ID".into()),
|
|
||||||
Some("Float") => Scalars::Float(0.0),
|
|
||||||
Some("Boolean") => Scalars::Boolean(false),
|
|
||||||
Some("Date") => Scalars::Date("ID".into()),
|
|
||||||
Some("DateTime") => Scalars::DateTime("ID".into()),
|
|
||||||
Some("Time") => Scalars::Time("ID".into()),
|
|
||||||
Some("Decimal") => Scalars::Decimal(0.0),
|
|
||||||
Some(_) => return true,
|
|
||||||
None => return false,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
|
||||||
64
crates/dagger-codegen/src/rust/format.rs
Normal file
64
crates/dagger-codegen/src/rust/format.rs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
use crate::functions::FormatTypeFuncs;
|
||||||
|
|
||||||
|
use super::functions::format_name;
|
||||||
|
|
||||||
|
pub struct FormatTypeFunc;
|
||||||
|
|
||||||
|
impl FormatTypeFuncs for FormatTypeFunc {
|
||||||
|
fn format_kind_list(&self, representation: &str) -> String {
|
||||||
|
format!("Vec<{}>", representation)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_kind_scalar_string(&self, representation: &str) -> String {
|
||||||
|
let mut rep = representation.to_string();
|
||||||
|
rep.push_str("String");
|
||||||
|
rep
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_kind_scalar_int(&self, representation: &str) -> String {
|
||||||
|
let mut rep = representation.to_string();
|
||||||
|
rep.push_str("isize");
|
||||||
|
rep
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_kind_scalar_float(&self, representation: &str) -> String {
|
||||||
|
let mut rep = representation.to_string();
|
||||||
|
rep.push_str("float");
|
||||||
|
rep
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_kind_scalar_boolean(&self, representation: &str) -> String {
|
||||||
|
let mut rep = representation.to_string();
|
||||||
|
rep.push_str("bool");
|
||||||
|
rep
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_kind_scalar_default(
|
||||||
|
&self,
|
||||||
|
representation: &str,
|
||||||
|
ref_name: &str,
|
||||||
|
input: bool,
|
||||||
|
) -> String {
|
||||||
|
let mut rep = representation.to_string();
|
||||||
|
rep.push_str(ref_name);
|
||||||
|
rep
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_kind_object(&self, representation: &str, ref_name: &str) -> String {
|
||||||
|
let mut rep = representation.to_string();
|
||||||
|
rep.push_str(&format_name(ref_name));
|
||||||
|
rep
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_kind_input_object(&self, representation: &str, ref_name: &str) -> String {
|
||||||
|
let mut rep = representation.to_string();
|
||||||
|
rep.push_str(&format_name(ref_name));
|
||||||
|
rep
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_kind_enum(&self, representation: &str, ref_name: &str) -> String {
|
||||||
|
let mut rep = representation.to_string();
|
||||||
|
rep.push_str(ref_name);
|
||||||
|
rep
|
||||||
|
}
|
||||||
|
}
|
||||||
5
crates/dagger-codegen/src/rust/functions.rs
Normal file
5
crates/dagger-codegen/src/rust/functions.rs
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
use convert_case::{Case, Casing};
|
||||||
|
|
||||||
|
pub fn format_name(s: &str) -> String {
|
||||||
|
s.to_case(Case::Pascal)
|
||||||
|
}
|
||||||
94
crates/dagger-codegen/src/rust/mod.rs
Normal file
94
crates/dagger-codegen/src/rust/mod.rs
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
pub mod format;
|
||||||
|
mod functions;
|
||||||
|
pub mod templates;
|
||||||
|
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use dagger_core::introspection::Schema;
|
||||||
|
use eyre::Context;
|
||||||
|
use genco::prelude::rust;
|
||||||
|
|
||||||
|
use crate::generator::Generator;
|
||||||
|
use crate::visitor::{VisitHandlers, Visitor};
|
||||||
|
|
||||||
|
use self::templates::enum_tmpl::render_enum;
|
||||||
|
use self::templates::input_tmpl::render_input;
|
||||||
|
use self::templates::object_tmpl::render_object;
|
||||||
|
use self::templates::scalar_tmpl::render_scalar;
|
||||||
|
|
||||||
|
pub struct RustGenerator {}
|
||||||
|
|
||||||
|
impl Generator for RustGenerator {
|
||||||
|
fn generate(&self, schema: Schema) -> eyre::Result<String> {
|
||||||
|
let render = Arc::new(Mutex::new(rust::Tokens::new()));
|
||||||
|
|
||||||
|
let visitor = Visitor {
|
||||||
|
schema,
|
||||||
|
handlers: VisitHandlers {
|
||||||
|
visit_scalar: Arc::new({
|
||||||
|
let render = render.clone();
|
||||||
|
move |t| {
|
||||||
|
let rendered_scalar = render_scalar(t)?;
|
||||||
|
|
||||||
|
let mut render = render.lock().unwrap();
|
||||||
|
|
||||||
|
render.append(rendered_scalar);
|
||||||
|
render.push();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
visit_object: Arc::new({
|
||||||
|
let render = render.clone();
|
||||||
|
|
||||||
|
move |t| {
|
||||||
|
let rendered_scalar = render_object(t)?;
|
||||||
|
|
||||||
|
let mut render = render.lock().unwrap();
|
||||||
|
|
||||||
|
render.append(rendered_scalar);
|
||||||
|
render.push();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
visit_input: Arc::new({
|
||||||
|
let render = render.clone();
|
||||||
|
|
||||||
|
move |t| {
|
||||||
|
let rendered_scalar = render_input(t)?;
|
||||||
|
|
||||||
|
let mut render = render.lock().unwrap();
|
||||||
|
|
||||||
|
render.append(rendered_scalar);
|
||||||
|
render.push();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
visit_enum: Arc::new({
|
||||||
|
let render = render.clone();
|
||||||
|
|
||||||
|
move |t| {
|
||||||
|
let rendered_scalar = render_enum(t)?;
|
||||||
|
|
||||||
|
let mut render = render.lock().unwrap();
|
||||||
|
|
||||||
|
render.append(rendered_scalar);
|
||||||
|
render.push();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
visitor.run()?;
|
||||||
|
|
||||||
|
let rendered = render.lock().unwrap();
|
||||||
|
|
||||||
|
rendered
|
||||||
|
.to_file_string()
|
||||||
|
.context("could not render to file string")
|
||||||
|
}
|
||||||
|
}
|
||||||
33
crates/dagger-codegen/src/rust/templates/enum_tmpl.rs
Normal file
33
crates/dagger-codegen/src/rust/templates/enum_tmpl.rs
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
use dagger_core::introspection::FullType;
|
||||||
|
use genco::prelude::rust;
|
||||||
|
use genco::quote;
|
||||||
|
|
||||||
|
fn render_enum_values(values: &FullType) -> Option<rust::Tokens> {
|
||||||
|
let values = values
|
||||||
|
.enum_values
|
||||||
|
.as_ref()
|
||||||
|
.into_iter()
|
||||||
|
.map(|values| {
|
||||||
|
values
|
||||||
|
.into_iter()
|
||||||
|
.map(|val| quote! { $(val.name.as_ref()) })
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let mut tokens = rust::Tokens::new();
|
||||||
|
for val in values {
|
||||||
|
tokens.append(val);
|
||||||
|
tokens.push();
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(tokens)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn render_enum(t: &FullType) -> eyre::Result<rust::Tokens> {
|
||||||
|
Ok(quote! {
|
||||||
|
pub enum $(t.name.as_ref()) {
|
||||||
|
$(render_enum_values(t))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
13
crates/dagger-codegen/src/rust/templates/input_tmpl.rs
Normal file
13
crates/dagger-codegen/src/rust/templates/input_tmpl.rs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
use dagger_core::introspection::FullType;
|
||||||
|
use genco::prelude::rust;
|
||||||
|
use genco::quote;
|
||||||
|
|
||||||
|
use crate::rust::functions::format_name;
|
||||||
|
|
||||||
|
pub fn render_input(t: &FullType) -> eyre::Result<rust::Tokens> {
|
||||||
|
Ok(quote! {
|
||||||
|
pub struct $(format_name(t.name.as_ref().unwrap())) {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
4
crates/dagger-codegen/src/rust/templates/mod.rs
Normal file
4
crates/dagger-codegen/src/rust/templates/mod.rs
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
pub mod enum_tmpl;
|
||||||
|
pub mod input_tmpl;
|
||||||
|
pub mod object_tmpl;
|
||||||
|
pub mod scalar_tmpl;
|
||||||
12
crates/dagger-codegen/src/rust/templates/object_tmpl.rs
Normal file
12
crates/dagger-codegen/src/rust/templates/object_tmpl.rs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
use dagger_core::introspection::FullType;
|
||||||
|
use genco::prelude::rust;
|
||||||
|
use genco::quote;
|
||||||
|
|
||||||
|
use crate::rust::functions::format_name;
|
||||||
|
|
||||||
|
pub fn render_object(t: &FullType) -> eyre::Result<rust::Tokens> {
|
||||||
|
Ok(quote! {
|
||||||
|
pub struct $(format_name(t.name.as_ref().unwrap())) {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
11
crates/dagger-codegen/src/rust/templates/scalar_tmpl.rs
Normal file
11
crates/dagger-codegen/src/rust/templates/scalar_tmpl.rs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
use dagger_core::introspection::FullType;
|
||||||
|
use genco::prelude::rust;
|
||||||
|
use genco::quote;
|
||||||
|
|
||||||
|
use crate::rust::functions::format_name;
|
||||||
|
|
||||||
|
pub fn render_scalar(t: &FullType) -> eyre::Result<rust::Tokens> {
|
||||||
|
Ok(quote! {
|
||||||
|
pub struct $(format_name(&t.name.as_ref().unwrap()))(String);
|
||||||
|
})
|
||||||
|
}
|
||||||
106
crates/dagger-codegen/src/visitor.rs
Normal file
106
crates/dagger-codegen/src/visitor.rs
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use dagger_core::introspection::{FullType, Schema, __TypeKind};
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
pub struct Visitor {
|
||||||
|
pub schema: Schema,
|
||||||
|
pub handlers: VisitHandlers,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type VisitFunc = Arc<dyn Fn(&FullType) -> eyre::Result<()>>;
|
||||||
|
|
||||||
|
pub struct VisitHandlers {
|
||||||
|
pub visit_scalar: VisitFunc,
|
||||||
|
pub visit_object: VisitFunc,
|
||||||
|
pub visit_input: VisitFunc,
|
||||||
|
pub visit_enum: VisitFunc,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SequenceItem {
|
||||||
|
kind: __TypeKind,
|
||||||
|
handler: VisitFunc,
|
||||||
|
ignore: Option<Vec<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Visitor {
|
||||||
|
pub fn run(&self) -> eyre::Result<()> {
|
||||||
|
let sequence = vec![
|
||||||
|
SequenceItem {
|
||||||
|
kind: __TypeKind::SCALAR,
|
||||||
|
handler: self.handlers.visit_scalar.clone(),
|
||||||
|
ignore: Some(vec![
|
||||||
|
"String".into(),
|
||||||
|
"Float".into(),
|
||||||
|
"Int".into(),
|
||||||
|
"Boolean".into(),
|
||||||
|
"DateTime".into(),
|
||||||
|
"ID".into(),
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
SequenceItem {
|
||||||
|
kind: __TypeKind::INPUT_OBJECT,
|
||||||
|
handler: self.handlers.visit_input.clone(),
|
||||||
|
ignore: None,
|
||||||
|
},
|
||||||
|
SequenceItem {
|
||||||
|
kind: __TypeKind::OBJECT,
|
||||||
|
handler: self.handlers.visit_object.clone(),
|
||||||
|
ignore: None,
|
||||||
|
},
|
||||||
|
SequenceItem {
|
||||||
|
kind: __TypeKind::ENUM,
|
||||||
|
handler: self.handlers.visit_enum.clone(),
|
||||||
|
ignore: None,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
for item in sequence {
|
||||||
|
self.visit(&item)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit(&self, item: &SequenceItem) -> eyre::Result<()> {
|
||||||
|
self.schema
|
||||||
|
.types
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.into_iter()
|
||||||
|
.map(|t| t.as_ref().unwrap())
|
||||||
|
.filter(|t| match t.full_type.kind.as_ref().unwrap() == &item.kind {
|
||||||
|
true => match (item.ignore.as_ref(), t.full_type.name.as_ref()) {
|
||||||
|
(Some(ignore), Some(name)) => {
|
||||||
|
if name.starts_with("__") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ignore.contains(name) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
(None, Some(name)) => {
|
||||||
|
if name.starts_with("__") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
|
},
|
||||||
|
false => false,
|
||||||
|
})
|
||||||
|
.sorted_by(|a, b| {
|
||||||
|
a.full_type
|
||||||
|
.name
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.cmp(&b.full_type.name.as_ref().unwrap())
|
||||||
|
})
|
||||||
|
.map(|t| (*item.handler)(&t.full_type))
|
||||||
|
.collect::<eyre::Result<Vec<_>>>()?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,852 +1,38 @@
|
|||||||
use std::process::Child;
|
pub struct CacheId(String);
|
||||||
use std::sync::Arc;
|
pub struct ContainerId(String);
|
||||||
|
pub struct DirectoryId(String);
|
||||||
use dagger_core::connect_params::ConnectParams;
|
pub struct FileId(String);
|
||||||
use dagger_core::{Boolean, Input, Int, Scalar};
|
pub struct Platform(String);
|
||||||
|
pub struct SecretId(String);
|
||||||
use crate::client::graphql_client;
|
pub struct SocketId(String);
|
||||||
use crate::querybuilder::Selection;
|
|
||||||
|
|
||||||
// code generated by dagger. DO NOT EDIT.
|
|
||||||
|
|
||||||
/// A global cache volume identifier.
|
|
||||||
pub struct CacheID(Scalar);
|
|
||||||
|
|
||||||
/// A unique container identifier. Null designates an empty container (scratch).
|
|
||||||
pub struct ContainerID(Scalar);
|
|
||||||
|
|
||||||
/// A content-addressed directory identifier.
|
|
||||||
pub struct DirectoryID(Scalar);
|
|
||||||
|
|
||||||
/// A file identifier.
|
|
||||||
pub struct FileID(Scalar);
|
|
||||||
|
|
||||||
/// The platform config OS and architecture in a Container.
|
|
||||||
/// The format is [os]/[platform]/[version] (e.g. darwin/arm64/v7, windows/amd64, linux/arm64).
|
|
||||||
pub struct Platform(Scalar);
|
|
||||||
|
|
||||||
/// A unique identifier for a secret.
|
|
||||||
pub struct SecretID(Scalar);
|
|
||||||
|
|
||||||
/// A content-addressed socket identifier.
|
|
||||||
pub struct SocketID(Scalar);
|
|
||||||
|
|
||||||
///
|
|
||||||
pub struct BuildArg {
|
pub struct BuildArg {
|
||||||
pub name: String,
|
|
||||||
|
|
||||||
pub value: String,
|
|
||||||
}
|
}
|
||||||
|
pub struct CacheVolume {
|
||||||
impl Input for BuildArg {}
|
|
||||||
|
|
||||||
/// A directory whose contents persist across runs.
|
|
||||||
pub struct CacheVolume {}
|
|
||||||
|
|
||||||
impl CacheVolume {
|
|
||||||
///
|
|
||||||
pub fn id(&self) -> CacheID {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Input for CacheVolume {}
|
|
||||||
|
|
||||||
/// An OCI-compatible container, also known as a docker container.
|
|
||||||
pub struct Container {
|
pub struct Container {
|
||||||
pub conn: ConnectParams,
|
|
||||||
pub proc: Arc<Child>,
|
|
||||||
pub selection: Selection,
|
|
||||||
}
|
}
|
||||||
|
pub struct Directory {
|
||||||
impl Container {
|
|
||||||
/// Initializes this container from a Dockerfile build, using the context, a dockerfile file path and some additional buildArgs.
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `context` - Directory context used by the Dockerfile.
|
|
||||||
/// * `dockerfile` - Path to the Dockerfile to use.
|
|
||||||
/// Defaults to './Dockerfile'.
|
|
||||||
/// * `buildArgs` - Additional build arguments.
|
|
||||||
/// * `target` - Target build stage to build.
|
|
||||||
pub fn build(
|
|
||||||
&self,
|
|
||||||
_context: DirectoryID,
|
|
||||||
_dockerfile: Option<String>,
|
|
||||||
_build_args: Option<Vec<BuildArg>>,
|
|
||||||
_target: Option<String>,
|
|
||||||
) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves default arguments for future commands.
|
|
||||||
pub fn default_args(&self) -> Option<Vec<String>> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves a directory at the given path. Mounts are included.
|
|
||||||
pub fn directory(&self, _path: String) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves entrypoint to be prepended to the arguments of all commands.
|
|
||||||
pub fn entrypoint(&self) -> Option<Vec<String>> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the value of the specified environment variable.
|
|
||||||
pub fn env_variable(&self, _name: String) -> Option<String> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the list of environment variables passed to commands.
|
|
||||||
pub fn env_variables(&self) -> Vec<EnvVariable> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container after executing the specified command inside it.
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `args` - Command to run instead of the container's default command.
|
|
||||||
/// * `stdin` - Content to write to the command's standard input before closing.
|
|
||||||
/// * `redirectStdout` - Redirect the command's standard output to a file in the container.
|
|
||||||
/// * `redirectStderr` - Redirect the command's standard error to a file in the container.
|
|
||||||
/// * `experimentalPrivilegedNesting` - Provide dagger access to the executed command.
|
|
||||||
/// Do not use this option unless you trust the command being executed.
|
|
||||||
/// The command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM.
|
|
||||||
pub fn exec(
|
|
||||||
&self,
|
|
||||||
args: Option<Vec<String>>,
|
|
||||||
_stdin: Option<String>,
|
|
||||||
_redirect_stdout: Option<String>,
|
|
||||||
_redirect_stderr: Option<String>,
|
|
||||||
_experimental_privileged_nesting: Option<Boolean>,
|
|
||||||
) -> Container {
|
|
||||||
let query = self.selection.select("exec");
|
|
||||||
let query = query.arg("args", args).unwrap();
|
|
||||||
|
|
||||||
Container {
|
|
||||||
conn: self.conn.clone(),
|
|
||||||
proc: self.proc.clone(),
|
|
||||||
selection: query,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Exit code of the last executed command. Zero means success.
|
|
||||||
/// Null if no command has been executed.
|
|
||||||
pub fn exit_code(&self) -> Option<Int> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes the container as an OCI tarball to the destination file path on the host for the specified platformVariants.
|
|
||||||
/// Return true on success.
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `path` - Host's destination path.
|
|
||||||
/// Path can be relative to the engine's workdir or absolute.
|
|
||||||
/// * `platformVariants` - Identifiers for other platform specific containers.
|
|
||||||
/// Used for multi-platform image.
|
|
||||||
pub fn export(&self, _path: String, _platform_variants: Option<Vec<ContainerID>>) -> Boolean {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves a file at the given path. Mounts are included.
|
|
||||||
pub fn file(&self, _path: String) -> File {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initializes this container from the base image published at the given address.
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `address` - Image's address from its registry.
|
|
||||||
/// Formatted as [host]/[user]/[repo]:[tag] (e.g. docker.io/dagger/dagger:main).
|
|
||||||
pub fn from(&self, address: String) -> Container {
|
|
||||||
let query = self.selection.select("from");
|
|
||||||
let query = query.arg("address", address).unwrap();
|
|
||||||
|
|
||||||
Container {
|
|
||||||
conn: self.conn.clone(),
|
|
||||||
proc: self.proc.clone(),
|
|
||||||
selection: query,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container's root filesystem. Mounts are not included.
|
|
||||||
pub fn fs(&self) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A unique identifier for this container.
|
|
||||||
pub fn id(&self) -> ContainerID {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the value of the specified label.
|
|
||||||
pub fn label(&self, _name: String) -> Option<String> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the list of labels passed to container.
|
|
||||||
pub fn labels(&self) -> Vec<Label> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the list of paths where a directory is mounted.
|
|
||||||
pub fn mounts(&self) -> Vec<String> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a named sub-pipeline
|
|
||||||
pub fn pipeline(&self, _name: String, _description: Option<String>) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The platform this container executes and publishes as.
|
|
||||||
pub fn platform(&self) -> Platform {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Publishes this container as a new image to the specified address, for the platformVariants, returning a fully qualified ref.
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `address` - Registry's address to publish the image to.
|
|
||||||
/// Formatted as [host]/[user]/[repo]:[tag] (e.g. docker.io/dagger/dagger:main).
|
|
||||||
/// * `platformVariants` - Identifiers for other platform specific containers.
|
|
||||||
/// Used for multi-platform image.
|
|
||||||
pub fn publish(
|
|
||||||
&self,
|
|
||||||
_address: String,
|
|
||||||
_platform_variants: Option<Vec<ContainerID>>,
|
|
||||||
) -> String {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container's root filesystem. Mounts are not included.
|
|
||||||
pub fn rootfs(&self) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The error stream of the last executed command.
|
|
||||||
/// Null if no command has been executed.
|
|
||||||
pub fn stderr(&self) -> Option<String> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The output stream of the last executed command.
|
|
||||||
/// Null if no command has been executed.
|
|
||||||
pub fn stdout(&self) -> Option<String> {
|
|
||||||
let query = self.selection.select("stdout");
|
|
||||||
|
|
||||||
query.execute(&graphql_client(&self.conn)).unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the user to be set for all commands.
|
|
||||||
pub fn user(&self) -> Option<String> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configures default arguments for future commands.
|
|
||||||
pub fn with_default_args(&self, _args: Option<Vec<String>>) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container plus a directory written at the given path.
|
|
||||||
pub fn with_directory(
|
|
||||||
&self,
|
|
||||||
_path: String,
|
|
||||||
_directory: DirectoryID,
|
|
||||||
_exclude: Option<Vec<String>>,
|
|
||||||
_include: Option<Vec<String>>,
|
|
||||||
) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container but with a different command entrypoint.
|
|
||||||
pub fn with_entrypoint(&self, _args: Vec<String>) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container plus the given environment variable.
|
|
||||||
pub fn with_env_variable(&self, _name: String, _value: String) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container after executing the specified command inside it.
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `args` - Command to run instead of the container's default command.
|
|
||||||
/// * `stdin` - Content to write to the command's standard input before closing.
|
|
||||||
/// * `redirectStdout` - Redirect the command's standard output to a file in the container.
|
|
||||||
/// * `redirectStderr` - Redirect the command's standard error to a file in the container.
|
|
||||||
/// * `experimentalPrivilegedNesting` - Provide dagger access to the executed command.
|
|
||||||
/// Do not use this option unless you trust the command being executed.
|
|
||||||
/// The command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM.
|
|
||||||
pub fn with_exec(
|
|
||||||
&self,
|
|
||||||
args: Vec<String>,
|
|
||||||
_stdin: Option<String>,
|
|
||||||
_redirect_stdout: Option<String>,
|
|
||||||
_redirect_stderr: Option<String>,
|
|
||||||
_experimental_privileged_nesting: Option<Boolean>,
|
|
||||||
) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initializes this container from this DirectoryID.
|
|
||||||
pub fn with_fs(&self, _id: DirectoryID) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container plus the contents of the given file copied to the given path.
|
|
||||||
pub fn with_file(
|
|
||||||
&self,
|
|
||||||
_path: String,
|
|
||||||
_source: FileID,
|
|
||||||
_permissions: Option<Int>,
|
|
||||||
) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container plus the given label.
|
|
||||||
pub fn with_label(&self, _name: String, _value: String) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container plus a cache volume mounted at the given path.
|
|
||||||
pub fn with_mounted_cache(
|
|
||||||
&self,
|
|
||||||
_path: String,
|
|
||||||
_cache: CacheID,
|
|
||||||
_source: Option<DirectoryID>,
|
|
||||||
) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container plus a directory mounted at the given path.
|
|
||||||
pub fn with_mounted_directory(&self, _path: String, _source: DirectoryID) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container plus a file mounted at the given path.
|
|
||||||
pub fn with_mounted_file(&self, _path: String, _source: FileID) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container plus a secret mounted into a file at the given path.
|
|
||||||
pub fn with_mounted_secret(&self, _path: String, _source: SecretID) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container plus a temporary directory mounted at the given path.
|
|
||||||
pub fn with_mounted_temp(&self, _path: String) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container plus a new file written at the given path.
|
|
||||||
pub fn with_new_file(
|
|
||||||
&self,
|
|
||||||
_path: String,
|
|
||||||
_contents: Option<String>,
|
|
||||||
_permissions: Option<Int>,
|
|
||||||
) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Initializes this container from this DirectoryID.
|
|
||||||
pub fn with_rootfs(&self, _id: DirectoryID) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container plus an env variable containing the given secret.
|
|
||||||
pub fn with_secret_variable(&self, _name: String, _secret: SecretID) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container plus a socket forwarded to the given Unix socket path.
|
|
||||||
pub fn with_unix_socket(&self, _path: String, _source: SocketID) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this containers with a different command user.
|
|
||||||
pub fn with_user(&self, _name: String) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container with a different working directory.
|
|
||||||
pub fn with_workdir(&self, _path: String) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container minus the given environment variable.
|
|
||||||
pub fn without_env_variable(&self, _name: String) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container minus the given environment label.
|
|
||||||
pub fn without_label(&self, _name: String) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container after unmounting everything at the given path.
|
|
||||||
pub fn without_mount(&self, _path: String) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this container with a previously added Unix socket removed.
|
|
||||||
pub fn without_unix_socket(&self, _path: String) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the working directory for all commands.
|
|
||||||
pub fn workdir(&self) -> Option<String> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
pub struct EnvVariable {
|
||||||
impl Input for Container {}
|
|
||||||
|
|
||||||
/// A directory.
|
|
||||||
pub struct Directory {}
|
|
||||||
|
|
||||||
impl Directory {
|
|
||||||
/// Gets the difference between this directory and an another directory.
|
|
||||||
pub fn diff(&self, _other: DirectoryID) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves a directory at the given path.
|
|
||||||
pub fn directory(&self, _path: String) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Builds a new Docker container from this directory.
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `dockerfile` - Path to the Dockerfile to use.
|
|
||||||
/// Defaults to './Dockerfile'.
|
|
||||||
/// * `platform` - The platform to build.
|
|
||||||
/// * `buildArgs` - Additional build arguments.
|
|
||||||
/// * `target` - Target build stage to build.
|
|
||||||
pub fn docker_build(
|
|
||||||
&self,
|
|
||||||
_dockerfile: Option<String>,
|
|
||||||
_platform: Option<Platform>,
|
|
||||||
_build_args: Option<Vec<BuildArg>>,
|
|
||||||
_target: Option<String>,
|
|
||||||
) -> Container {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a list of files and directories at the given path.
|
|
||||||
pub fn entries(&self, _path: Option<String>) -> Vec<String> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes the contents of the directory to a path on the host.
|
|
||||||
pub fn export(&self, _path: String) -> Boolean {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves a file at the given path.
|
|
||||||
pub fn file(&self, _path: String) -> File {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The content-addressed identifier of the directory.
|
|
||||||
pub fn id(&self) -> DirectoryID {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// load a project's metadata
|
|
||||||
pub fn load_project(&self, _config_path: String) -> Project {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a named sub-pipeline.
|
|
||||||
pub fn pipeline(&self, _name: String, _description: Option<String>) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this directory plus a directory written at the given path.
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `exclude` - Exclude artifacts that match the given pattern.
|
|
||||||
/// (e.g. ["node_modules/", ".git*"]).
|
|
||||||
/// * `include` - Include only artifacts that match the given pattern.
|
|
||||||
/// (e.g. ["app/", "package.*"]).
|
|
||||||
pub fn with_directory(
|
|
||||||
&self,
|
|
||||||
_path: String,
|
|
||||||
_directory: DirectoryID,
|
|
||||||
_exclude: Option<Vec<String>>,
|
|
||||||
_include: Option<Vec<String>>,
|
|
||||||
) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this directory plus the contents of the given file copied to the given path.
|
|
||||||
pub fn with_file(
|
|
||||||
&self,
|
|
||||||
_path: String,
|
|
||||||
_source: FileID,
|
|
||||||
_permissions: Option<Int>,
|
|
||||||
) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this directory plus a new directory created at the given path.
|
|
||||||
pub fn with_new_directory(&self, _path: String, _permissions: Option<Int>) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this directory plus a new file written at the given path.
|
|
||||||
pub fn with_new_file(
|
|
||||||
&self,
|
|
||||||
_path: String,
|
|
||||||
_contents: String,
|
|
||||||
_permissions: Option<Int>,
|
|
||||||
) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this directory with all file/dir timestamps set to the given time, in seconds from the Unix epoch.
|
|
||||||
pub fn with_timestamps(&self, _timestamp: Int) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this directory with the directory at the given path removed.
|
|
||||||
pub fn without_directory(&self, _path: String) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this directory with the file at the given path removed.
|
|
||||||
pub fn without_file(&self, _path: String) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
pub struct File {
|
||||||
impl Input for Directory {}
|
|
||||||
|
|
||||||
/// A simple key value object that represents an environment variable.
|
|
||||||
pub struct EnvVariable {}
|
|
||||||
|
|
||||||
impl EnvVariable {
|
|
||||||
/// The environment variable name.
|
|
||||||
pub fn name(&self) -> String {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The environment variable value.
|
|
||||||
pub fn value(&self) -> String {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
pub struct GitRef {
|
||||||
impl Input for EnvVariable {}
|
|
||||||
|
|
||||||
/// A file.
|
|
||||||
pub struct File {}
|
|
||||||
|
|
||||||
impl File {
|
|
||||||
/// Retrieves the contents of the file.
|
|
||||||
pub fn contents(&self) -> String {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Writes the file to a file path on the host.
|
|
||||||
pub fn export(&self, _path: String) -> Boolean {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the content-addressed identifier of the file.
|
|
||||||
pub fn id(&self) -> FileID {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves a secret referencing the contents of this file.
|
|
||||||
pub fn secret(&self) -> Secret {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the size of the file, in bytes.
|
|
||||||
pub fn size(&self) -> Int {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves this file with its created/modified timestamps set to the given time, in seconds from the Unix epoch.
|
|
||||||
pub fn with_timestamps(&self, _timestamp: Int) -> File {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
pub struct GitRepository {
|
||||||
impl Input for File {}
|
|
||||||
|
|
||||||
/// A git ref (tag, branch or commit).
|
|
||||||
pub struct GitRef {}
|
|
||||||
|
|
||||||
impl GitRef {
|
|
||||||
/// The digest of the current value of this ref.
|
|
||||||
pub fn digest(&self) -> String {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The filesystem tree at this ref.
|
|
||||||
pub fn tree(
|
|
||||||
&self,
|
|
||||||
_ssh_known_hosts: Option<String>,
|
|
||||||
_ssh_auth_socket: Option<SocketID>,
|
|
||||||
) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
pub struct Host {
|
||||||
impl Input for GitRef {}
|
|
||||||
|
|
||||||
/// A git repository.
|
|
||||||
pub struct GitRepository {}
|
|
||||||
|
|
||||||
impl GitRepository {
|
|
||||||
/// Returns details on one branch.
|
|
||||||
pub fn branch(&self, _name: String) -> GitRef {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Lists of branches on the repository.
|
|
||||||
pub fn branches(&self) -> Vec<String> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns details on one commit.
|
|
||||||
pub fn commit(&self, _id: String) -> GitRef {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns details on one tag.
|
|
||||||
pub fn tag(&self, _name: String) -> GitRef {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Lists of tags on the repository.
|
|
||||||
pub fn tags(&self) -> Vec<String> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
pub struct HostVariable {
|
||||||
impl Input for GitRepository {}
|
|
||||||
|
|
||||||
/// Information about the host execution environment.
|
|
||||||
pub struct Host {}
|
|
||||||
|
|
||||||
impl Host {
|
|
||||||
/// Accesses a directory on the host.
|
|
||||||
pub fn directory(
|
|
||||||
&self,
|
|
||||||
_path: String,
|
|
||||||
_exclude: Option<Vec<String>>,
|
|
||||||
_include: Option<Vec<String>>,
|
|
||||||
) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Accesses an environment variable on the host.
|
|
||||||
pub fn env_variable(&self, _name: String) -> Option<HostVariable> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Accesses a Unix socket on the host.
|
|
||||||
pub fn unix_socket(&self, _path: String) -> Socket {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Retrieves the current working directory on the host.
|
|
||||||
pub fn workdir(
|
|
||||||
&self,
|
|
||||||
_exclude: Option<Vec<String>>,
|
|
||||||
_include: Option<Vec<String>>,
|
|
||||||
) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
pub struct Label {
|
||||||
impl Input for Host {}
|
|
||||||
|
|
||||||
/// An environment variable on the host environment.
|
|
||||||
pub struct HostVariable {}
|
|
||||||
|
|
||||||
impl HostVariable {
|
|
||||||
/// A secret referencing the value of this variable.
|
|
||||||
pub fn secret(&self) -> Secret {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The value of this variable.
|
|
||||||
pub fn value(&self) -> String {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
pub struct Project {
|
||||||
impl Input for HostVariable {}
|
|
||||||
|
|
||||||
/// A simple key value object that represents a label.
|
|
||||||
pub struct Label {}
|
|
||||||
|
|
||||||
impl Label {
|
|
||||||
/// The label name.
|
|
||||||
pub fn name(&self) -> String {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The label value.
|
|
||||||
pub fn value(&self) -> String {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Input for Label {}
|
|
||||||
|
|
||||||
/// A set of scripts and/or extensions
|
|
||||||
pub struct Project {}
|
|
||||||
|
|
||||||
impl Project {
|
|
||||||
/// extensions in this project
|
|
||||||
pub fn extensions(&self) -> Option<Vec<Project>> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Code files generated by the SDKs in the project
|
|
||||||
pub fn generated_code(&self) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// install the project's schema
|
|
||||||
pub fn install(&self) -> Boolean {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// name of the project
|
|
||||||
pub fn name(&self) -> String {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// schema provided by the project
|
|
||||||
pub fn schema(&self) -> Option<String> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// sdk used to generate code for and/or execute this project
|
|
||||||
pub fn sdk(&self) -> Option<String> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Input for Project {}
|
|
||||||
|
|
||||||
///
|
|
||||||
pub struct Query {
|
pub struct Query {
|
||||||
pub conn: ConnectParams,
|
|
||||||
pub proc: Arc<Child>,
|
|
||||||
pub selection: Selection,
|
|
||||||
}
|
}
|
||||||
|
pub struct Secret {
|
||||||
impl Query {
|
|
||||||
/// Constructs a cache volume for a given cache key.
|
|
||||||
/// # Arguments
|
|
||||||
///
|
|
||||||
/// * `key` - A string identifier to target this cache volume (e.g. "myapp-cache").
|
|
||||||
pub fn cache_volume(&self, _key: String) -> CacheVolume {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Loads a container from ID.
|
|
||||||
/// Null ID returns an empty container (scratch).
|
|
||||||
/// Optional platform argument initializes new containers to execute and publish as that platform. Platform defaults to that of the builder's host.
|
|
||||||
pub fn container(&self, _id: Option<ContainerID>, _platform: Option<Platform>) -> Container {
|
|
||||||
let query = self.selection.select("container");
|
|
||||||
|
|
||||||
return Container {
|
|
||||||
conn: self.conn.clone(),
|
|
||||||
proc: self.proc.clone(),
|
|
||||||
selection: query,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The default platform of the builder.
|
|
||||||
pub fn default_platform(&self) -> Platform {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Load a directory by ID. No argument produces an empty directory.
|
|
||||||
pub fn directory(&self, _id: Option<DirectoryID>) -> Directory {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Loads a file by ID.
|
|
||||||
pub fn file(&self, _id: FileID) -> Option<File> {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Queries a git repository.
|
|
||||||
pub fn git(&self, _url: String, _keep_git_dir: Option<Boolean>) -> GitRepository {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Queries the host environment.
|
|
||||||
pub fn host(&self) -> Host {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a file containing an http remote url content.
|
|
||||||
pub fn http(&self, _url: String) -> File {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Creates a named sub-pipeline
|
|
||||||
pub fn pipeline(&self, _name: String, _description: Option<String>) -> Query {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Look up a project by name
|
|
||||||
pub fn project(&self, _name: String) -> Project {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Loads a secret from its ID.
|
|
||||||
pub fn secret(&self, _id: SecretID) -> Secret {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Loads a socket by its ID.
|
|
||||||
pub fn socket(&self, _id: Option<SocketID>) -> Socket {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
pub struct Socket {
|
||||||
impl Input for Query {}
|
|
||||||
|
|
||||||
/// A reference to a secret value, which can be handled more safely than the value itself.
|
|
||||||
pub struct Secret {}
|
|
||||||
|
|
||||||
impl Secret {
|
|
||||||
/// The identifier for this secret.
|
|
||||||
pub fn id(&self) -> SecretID {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The value of this secret.
|
|
||||||
pub fn plaintext(&self) -> String {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Input for Secret {}
|
|
||||||
|
|
||||||
///
|
|
||||||
pub struct Socket {}
|
|
||||||
|
|
||||||
impl Socket {
|
|
||||||
/// The content-addressed identifier of the socket.
|
|
||||||
pub fn id(&self) -> SocketID {
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Input for Socket {}
|
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use clap::{Arg, ArgMatches};
|
use clap::{Arg, ArgMatches};
|
||||||
use dagger_codegen::codegen::CodeGeneration;
|
use dagger_codegen::generate;
|
||||||
|
use dagger_codegen::rust::RustGenerator;
|
||||||
use dagger_core::config::Config;
|
use dagger_core::config::Config;
|
||||||
use dagger_core::engine::Engine;
|
use dagger_core::engine::Engine;
|
||||||
use dagger_core::session::Session;
|
use dagger_core::session::Session;
|
||||||
@@ -21,7 +23,10 @@ impl GenerateCommand {
|
|||||||
let session = Session::new();
|
let session = Session::new();
|
||||||
let req = session.start(&cfg, &conn)?;
|
let req = session.start(&cfg, &conn)?;
|
||||||
let schema = session.schema(req)?;
|
let schema = session.schema(req)?;
|
||||||
let code = CodeGeneration::new().generate(&schema)?;
|
let code = generate(
|
||||||
|
schema.into_schema().schema.unwrap(),
|
||||||
|
Arc::new(RustGenerator {}),
|
||||||
|
)?;
|
||||||
|
|
||||||
if let Some(output) = arg_matches.get_one::<String>("output") {
|
if let Some(output) = arg_matches.get_one::<String>("output") {
|
||||||
let mut file = std::fs::File::create(output)?;
|
let mut file = std::fs::File::create(output)?;
|
||||||
|
|||||||
Reference in New Issue
Block a user