From 5fef5148010f384d0158361d64b8e17d357d4819 Mon Sep 17 00:00:00 2001 From: kjuulh Date: Mon, 30 Jan 2023 20:44:48 +0100 Subject: [PATCH] with objects --- Cargo.lock | 16 + crates/dagger-codegen/Cargo.toml | 1 + crates/dagger-codegen/src/codegen.rs | 24 +- .../src/handlers/enumeration.rs | 4 +- crates/dagger-codegen/src/handlers/fields.rs | 33 + crates/dagger-codegen/src/handlers/input.rs | 89 +-- .../src/handlers/input_field.rs | 22 + crates/dagger-codegen/src/handlers/mod.rs | 4 + crates/dagger-codegen/src/handlers/object.rs | 101 +++ .../dagger-codegen/src/handlers/type_ref.rs | 72 ++ crates/dagger-codegen/src/handlers/utility.rs | 15 +- crates/dagger-codegen/src/predicates.rs | 7 + crates/dagger-core/src/lib.rs | 6 + crates/dagger-sdk/src/gen.rs | 667 +++++++++++++++++- 14 files changed, 962 insertions(+), 99 deletions(-) create mode 100644 crates/dagger-codegen/src/handlers/fields.rs create mode 100644 crates/dagger-codegen/src/handlers/input_field.rs create mode 100644 crates/dagger-codegen/src/handlers/object.rs create mode 100644 crates/dagger-codegen/src/handlers/type_ref.rs diff --git a/Cargo.lock b/Cargo.lock index 28a656e..1dea011 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -119,6 +119,15 @@ dependencies = [ "unreachable", ] +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation" version = "0.9.3" @@ -177,6 +186,7 @@ dependencies = [ name = "dagger-codegen" version = "0.1.0" dependencies = [ + "convert_case", "dagger-core", "eyre", "genco", @@ -1360,6 +1370,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fdbf052a0783de01e944a6ce7a8cb939e295b1e7be835a1112c3b9a7f047a5a" + [[package]] name = "unreachable" version = "1.0.0" diff --git a/crates/dagger-codegen/Cargo.toml b/crates/dagger-codegen/Cargo.toml index 6f257b3..b5e0531 100644 --- a/crates/dagger-codegen/Cargo.toml +++ b/crates/dagger-codegen/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] +convert_case = "0.6.0" dagger-core = { path = "../dagger-core" } eyre = "0.6.8" diff --git a/crates/dagger-codegen/src/codegen.rs b/crates/dagger-codegen/src/codegen.rs index ad84843..4e1947a 100644 --- a/crates/dagger-codegen/src/codegen.rs +++ b/crates/dagger-codegen/src/codegen.rs @@ -8,9 +8,8 @@ use graphql_introspection_query::introspection_response::{ FullType, IntrospectionResponse, Schema, }; -use crate::{ - handlers::{enumeration::Enumeration, input::Input, scalar::Scalar, DynHandler, Handlers}, - predicates::is_custom_scalar_type, +use crate::handlers::{ + enumeration::Enumeration, input::Input, object::Object, scalar::Scalar, DynHandler, Handlers, }; #[allow(dead_code)] @@ -25,6 +24,7 @@ impl CodeGeneration { Arc::new(Scalar {}), Arc::new(Enumeration {}), Arc::new(Input {}), + Arc::new(Object {}), ], } } @@ -47,6 +47,10 @@ impl CodeGeneration { $(format!("// code generated by dagger. DO NOT EDIT.")) }); + output.push(); + output.append(render_base_types()); + output.push(); + let types = get_types(schema)?; //let remaining: Vec> = types.into_iter().map(type_name).collect(); // @@ -93,7 +97,8 @@ impl CodeGeneration { pub fn type_name(&self, t: &FullType) -> Option { let name = t.name.as_ref(); if let Some(name) = name { - if name.starts_with("_") || !is_custom_scalar_type(t) { + if name.starts_with("_") { + //|| !is_custom_scalar_type(t) { return None; } @@ -124,13 +129,22 @@ impl CodeGeneration { } } +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> { let types = schema .types .as_ref() .ok_or(eyre::anyhow!("types not found on schema"))?; - // 1. Get a list of all types and map it to handlers let types: Vec<&FullType> = types .iter() .map(|t| t.as_ref().map(|t| &t.full_type)) diff --git a/crates/dagger-codegen/src/handlers/enumeration.rs b/crates/dagger-codegen/src/handlers/enumeration.rs index 61c334c..deb777b 100644 --- a/crates/dagger-codegen/src/handlers/enumeration.rs +++ b/crates/dagger-codegen/src/handlers/enumeration.rs @@ -23,7 +23,9 @@ impl Handler for Enumeration { let out = quote! { $description - pub enum $name {} + pub enum $name { + // TODO: Add individual items + } }; Ok(out) diff --git a/crates/dagger-codegen/src/handlers/fields.rs b/crates/dagger-codegen/src/handlers/fields.rs new file mode 100644 index 0000000..42b3342 --- /dev/null +++ b/crates/dagger-codegen/src/handlers/fields.rs @@ -0,0 +1,33 @@ +use convert_case::{Case, Casing}; +use genco::{prelude::rust, quote}; +use graphql_introspection_query::introspection_response::FullTypeFields; + +use super::{ + type_ref, + utility::{render_description, render_description_from_field}, +}; + +pub fn render_fields(fields: &Vec) -> eyre::Result> { + let mut collected_fields: Vec = 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); + + collected_fields.push(quote! { + $(if description.is_some() => $description) + pub fn $name(&self) -> $output { + todo!() + } + }) + } + + Ok(Some(quote! { + $(for field in collected_fields => $field $['\n'] ) + })) +} + +pub fn render_field_output(field: &FullTypeFields) -> eyre::Result { + let inner = &field.type_.as_ref().unwrap(); + type_ref::render_type_ref(&inner.type_ref) +} diff --git a/crates/dagger-codegen/src/handlers/input.rs b/crates/dagger-codegen/src/handlers/input.rs index a7b59cd..07e7877 100644 --- a/crates/dagger-codegen/src/handlers/input.rs +++ b/crates/dagger-codegen/src/handlers/input.rs @@ -1,93 +1,12 @@ use genco::prelude::rust; use genco::prelude::*; -use graphql_introspection_query::introspection_response::{FullType, FullTypeInputFields, TypeRef}; +use graphql_introspection_query::introspection_response::FullType; -use crate::predicates::{ - is_custom_scalar_type_ref, is_input_object_type, is_list_type, is_required_type_ref, - is_scalar_type_ref, -}; +use crate::predicates::is_input_object_type; -use super::{utility::render_description, Handler}; +use super::{input_field::render_input_fields, utility::render_description, Handler}; pub struct Input; -impl Input { - fn render_input_fields( - &self, - input_fields: &Vec, - ) -> eyre::Result> { - let mut fields: Vec<(String, rust::Tokens)> = vec![]; - for field in input_fields.iter() { - fields.push(( - field.input_value.name.clone(), - self.render_input_field(field)?, - )); - } - - Ok(Some(quote! { - $(for (name, field) in fields => pub $name: $field $['\n'] ) - })) - } - - fn render_input_field(&self, field: &FullTypeInputFields) -> eyre::Result { - let inner = &field.input_value.type_; - self.render_type_ref(inner) - } - - fn render_type_ref(&self, inner: &TypeRef) -> eyre::Result { - let extract_of_type = |t: &TypeRef| -> Option { - return t.clone().of_type.map(|t| *t); - }; - - if !is_required_type_ref(inner) { - if let Some(inner_of_type) = extract_of_type(inner) { - let inner_field = self.render_type_ref(&inner_of_type)?; - return Ok(quote! { - Option<$inner_field> - }); - } - } - - if is_list_type(&inner) { - if let Some(inner_of_type) = extract_of_type(inner) { - let inner_field = self.render_type_ref(&inner_of_type)?; - 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 = self.render_type_ref(&inner_of_type)?; - 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"), - }; - - return Ok(quote! { - $name - }); - } - - eyre::bail!("could not determine type") - } -} impl Handler for Input { fn predicate(&self, t: &FullType) -> bool { @@ -104,7 +23,7 @@ impl Handler for Input { let input = rust::import("dagger_core", "Input"); let fields = match t.input_fields.as_ref() { - Some(i) => self.render_input_fields(i)?, + Some(i) => render_input_fields(i)?, None => None, }; diff --git a/crates/dagger-codegen/src/handlers/input_field.rs b/crates/dagger-codegen/src/handlers/input_field.rs new file mode 100644 index 0000000..d7b49e9 --- /dev/null +++ b/crates/dagger-codegen/src/handlers/input_field.rs @@ -0,0 +1,22 @@ +use genco::{prelude::rust, quote}; +use graphql_introspection_query::introspection_response::FullTypeInputFields; + +use super::type_ref; + +pub fn render_input_fields( + input_fields: &Vec, +) -> eyre::Result> { + 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 { + let inner = &field.input_value.type_; + type_ref::render_type_ref(inner) +} diff --git a/crates/dagger-codegen/src/handlers/mod.rs b/crates/dagger-codegen/src/handlers/mod.rs index 2692deb..8da7a02 100644 --- a/crates/dagger-codegen/src/handlers/mod.rs +++ b/crates/dagger-codegen/src/handlers/mod.rs @@ -1,6 +1,10 @@ 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; diff --git a/crates/dagger-codegen/src/handlers/object.rs b/crates/dagger-codegen/src/handlers/object.rs new file mode 100644 index 0000000..45b9379 --- /dev/null +++ b/crates/dagger-codegen/src/handlers/object.rs @@ -0,0 +1,101 @@ +use genco::{prelude::rust, quote}; +use graphql_introspection_query::introspection_response::FullType; + +use crate::predicates::is_object_type; + +use super::{fields, 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 { + 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.fields.as_ref() { + Some(i) => fields::render_fields(i)?, + None => None, + }; + + let out = quote! { + $(if description.is_some() => $description) + pub struct $name { + } + + impl $name { + $(if fields.is_some() => $fields) + } + + impl $input for $name {} + }; + + Ok(out) + } +} + +#[cfg(test)] +mod tests { + use graphql_introspection_query::introspection_response::{ + FullType, FullTypeFields, FullTypeFieldsType, 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#"use dagger_core::Input; + + +/// A directory whose contents persists across sessions +pub struct CacheVolume { + pub id: Option +} + +impl Input for CacheVolume {} +"#; + let handler = Object {}; + let obj = handler.render(&t).unwrap(); + let actual = obj.to_file_string().unwrap(); + + assert_eq!(actual, expected); + } +} diff --git a/crates/dagger-codegen/src/handlers/type_ref.rs b/crates/dagger-codegen/src/handlers/type_ref.rs new file mode 100644 index 0000000..92eb6fe --- /dev/null +++ b/crates/dagger-codegen/src/handlers/type_ref.rs @@ -0,0 +1,72 @@ +use genco::prelude::rust; +use genco::prelude::*; +use graphql_introspection_query::introspection_response::TypeRef; + +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 { + let extract_of_type = |t: &TypeRef| -> Option { + return t.clone().of_type.map(|t| *t); + }; + + if !is_required_type_ref(inner) { + if let Some(inner_of_type) = extract_of_type(inner) { + let inner_field = render_type_ref(&inner_of_type)?; + return Ok(quote! { + Option<$inner_field> + }); + } + } + + if is_list_type(&inner) { + if let Some(inner_of_type) = extract_of_type(inner) { + let inner_field = render_type_ref(&inner_of_type)?; + 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)?; + 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"), + }; + + return Ok(quote! { + $name + }); + } + + if let Some(inner_type) = inner.of_type.as_ref() { + return render_type_ref(&inner_type); + } + + if let Some(name) = inner.name.as_ref() { + return Ok(quote! { + $name + }); + } + + eyre::bail!("could not determine type") +} diff --git a/crates/dagger-codegen/src/handlers/utility.rs b/crates/dagger-codegen/src/handlers/utility.rs index 46dc15b..0d5798b 100644 --- a/crates/dagger-codegen/src/handlers/utility.rs +++ b/crates/dagger-codegen/src/handlers/utility.rs @@ -1,5 +1,5 @@ use genco::{prelude::*, quote}; -use graphql_introspection_query::introspection_response::FullType; +use graphql_introspection_query::introspection_response::{FullType, FullTypeFields}; pub fn render_description(t: &FullType) -> Option { if let Some(description) = t.description.as_ref() { @@ -13,3 +13,16 @@ pub fn render_description(t: &FullType) -> Option { None } + +pub fn render_description_from_field(t: &FullTypeFields) -> Option { + 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 +} diff --git a/crates/dagger-codegen/src/predicates.rs b/crates/dagger-codegen/src/predicates.rs index b6fea88..24747e6 100644 --- a/crates/dagger-codegen/src/predicates.rs +++ b/crates/dagger-codegen/src/predicates.rs @@ -55,6 +55,13 @@ pub fn is_list_type(t: &TypeRef) -> bool { false } +pub fn is_object_type(t: &FullType) -> bool { + if let Some(introspection_response::__TypeKind::OBJECT) = t.kind { + return true; + } + false +} + pub fn is_custom_scalar_type(t: &FullType) -> bool { if is_scalar_type(t) { // TODO: Insert scalar diff --git a/crates/dagger-core/src/lib.rs b/crates/dagger-core/src/lib.rs index d1e5bd8..5b4452c 100644 --- a/crates/dagger-core/src/lib.rs +++ b/crates/dagger-core/src/lib.rs @@ -1 +1,7 @@ pub struct Scalar(String); + +pub struct Boolean(bool); + +pub struct Int(isize); + +pub trait Input {} diff --git a/crates/dagger-sdk/src/gen.rs b/crates/dagger-sdk/src/gen.rs index 25a4ccb..2d8cbf3 100644 --- a/crates/dagger-sdk/src/gen.rs +++ b/crates/dagger-sdk/src/gen.rs @@ -1,19 +1,16 @@ -use dagger_core::Scalar; +use dagger_core::{Boolean, Input, Int, Scalar}; // code generated by dagger. DO NOT EDIT. -/// A global cache volume identifier. -pub struct CacheID(Scalar); - /// A content-addressed directory identifier. pub struct DirectoryID(Scalar); +/// A global cache volume identifier. +pub struct CacheID(Scalar); + /// A content-addressed socket identifier. pub struct SocketID(Scalar); -/// A unique container identifier. Null designates an empty container (scratch). -pub struct ContainerID(Scalar); - /// A file identifier. pub struct FileID(Scalar); @@ -21,5 +18,661 @@ pub struct FileID(Scalar); /// The format is [os]/[platform]/[version] (e.g. darwin/arm64/v7, windows/amd64, linux/arm64). pub struct Platform(Scalar); +/// A unique container identifier. Null designates an empty container (scratch). +pub struct ContainerID(Scalar); + /// A unique identifier for a secret. pub struct SecretID(Scalar); + +/// +pub struct BuildArg { + pub name: Option, + + pub value: Option, +} + +impl Input for BuildArg {} + +/// A file. +pub struct File {} + +impl File { + /// Retrieves the contents of the file. + pub fn contents(&self) -> Option { + todo!() + } + + /// Writes the file to a file path on the host. + pub fn export(&self) -> Option { + todo!() + } + + /// Retrieves the content-addressed identifier of the file. + pub fn id(&self) -> Option { + todo!() + } + + /// Retrieves a secret referencing the contents of this file. + pub fn secret(&self) -> Option { + todo!() + } + + /// Gets the size of the file, in bytes. + pub fn size(&self) -> Option { + 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) -> Option { + todo!() + } +} + +impl Input for File {} + +/// An OCI-compatible container, also known as a docker container. +pub struct Container {} + +impl Container { + /// Initializes this container from a Dockerfile build, using the context, a dockerfile file path and some additional buildArgs. + pub fn build(&self) -> Option { + todo!() + } + + /// Retrieves default arguments for future commands. + pub fn default_args(&self) -> Vec> { + todo!() + } + + /// Retrieves a directory at the given path. Mounts are included. + pub fn directory(&self) -> Option { + todo!() + } + + /// Retrieves entrypoint to be prepended to the arguments of all commands. + pub fn entrypoint(&self) -> Vec> { + todo!() + } + + /// Retrieves the value of the specified environment variable. + pub fn env_variable(&self) -> String { + todo!() + } + + /// Retrieves the list of environment variables passed to commands. + pub fn env_variables(&self) -> Option>> { + todo!() + } + + /// Retrieves this container after executing the specified command inside it. + pub fn exec(&self) -> Option { + todo!() + } + + /// Exit code of the last executed command. Zero means success. + /// Null if no command has been executed. + pub fn exit_code(&self) -> 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. + pub fn export(&self) -> Option { + todo!() + } + + /// Retrieves a file at the given path. Mounts are included. + pub fn file(&self) -> Option { + todo!() + } + + /// Initializes this container from the base image published at the given address. + pub fn from(&self) -> Option { + todo!() + } + + /// Retrieves this container's root filesystem. Mounts are not included. + pub fn fs(&self) -> Option { + todo!() + } + + /// A unique identifier for this container. + pub fn id(&self) -> Option { + todo!() + } + + /// Retrieves the value of the specified label. + pub fn label(&self) -> String { + todo!() + } + + /// Retrieves the list of labels passed to container. + pub fn labels(&self) -> Option>> { + todo!() + } + + /// Retrieves the list of paths where a directory is mounted. + pub fn mounts(&self) -> Option>> { + todo!() + } + + /// Creates a named sub-pipeline + pub fn pipeline(&self) -> Option { + todo!() + } + + /// The platform this container executes and publishes as. + pub fn platform(&self) -> Option { + todo!() + } + + /// Publishes this container as a new image to the specified address, for the platformVariants, returning a fully qualified ref. + pub fn publish(&self) -> Option { + todo!() + } + + /// Retrieves this container's root filesystem. Mounts are not included. + pub fn rootfs(&self) -> Option { + todo!() + } + + /// The error stream of the last executed command. + /// Null if no command has been executed. + pub fn stderr(&self) -> String { + todo!() + } + + /// The output stream of the last executed command. + /// Null if no command has been executed. + pub fn stdout(&self) -> String { + todo!() + } + + /// Retrieves the user to be set for all commands. + pub fn user(&self) -> String { + todo!() + } + + /// Configures default arguments for future commands. + pub fn with_default_args(&self) -> Option { + todo!() + } + + /// Retrieves this container plus a directory written at the given path. + pub fn with_directory(&self) -> Option { + todo!() + } + + /// Retrieves this container but with a different command entrypoint. + pub fn with_entrypoint(&self) -> Option { + todo!() + } + + /// Retrieves this container plus the given environment variable. + pub fn with_env_variable(&self) -> Option { + todo!() + } + + /// Retrieves this container after executing the specified command inside it. + pub fn with_exec(&self) -> Option { + todo!() + } + + /// Initializes this container from this DirectoryID. + pub fn with_fs(&self) -> Option { + todo!() + } + + /// Retrieves this container plus the contents of the given file copied to the given path. + pub fn with_file(&self) -> Option { + todo!() + } + + /// Retrieves this container plus the given label. + pub fn with_label(&self) -> Option { + todo!() + } + + /// Retrieves this container plus a cache volume mounted at the given path. + pub fn with_mounted_cache(&self) -> Option { + todo!() + } + + /// Retrieves this container plus a directory mounted at the given path. + pub fn with_mounted_directory(&self) -> Option { + todo!() + } + + /// Retrieves this container plus a file mounted at the given path. + pub fn with_mounted_file(&self) -> Option { + todo!() + } + + /// Retrieves this container plus a secret mounted into a file at the given path. + pub fn with_mounted_secret(&self) -> Option { + todo!() + } + + /// Retrieves this container plus a temporary directory mounted at the given path. + pub fn with_mounted_temp(&self) -> Option { + todo!() + } + + /// Retrieves this container plus a new file written at the given path. + pub fn with_new_file(&self) -> Option { + todo!() + } + + /// Initializes this container from this DirectoryID. + pub fn with_rootfs(&self) -> Option { + todo!() + } + + /// Retrieves this container plus an env variable containing the given secret. + pub fn with_secret_variable(&self) -> Option { + todo!() + } + + /// Retrieves this container plus a socket forwarded to the given Unix socket path. + pub fn with_unix_socket(&self) -> Option { + todo!() + } + + /// Retrieves this containers with a different command user. + pub fn with_user(&self) -> Option { + todo!() + } + + /// Retrieves this container with a different working directory. + pub fn with_workdir(&self) -> Option { + todo!() + } + + /// Retrieves this container minus the given environment variable. + pub fn without_env_variable(&self) -> Option { + todo!() + } + + /// Retrieves this container minus the given environment label. + pub fn without_label(&self) -> Option { + todo!() + } + + /// Retrieves this container after unmounting everything at the given path. + pub fn without_mount(&self) -> Option { + todo!() + } + + /// Retrieves this container with a previously added Unix socket removed. + pub fn without_unix_socket(&self) -> Option { + todo!() + } + + /// Retrieves the working directory for all commands. + pub fn workdir(&self) -> String { + todo!() + } +} + +impl Input for Container {} + +/// A directory whose contents persist across runs. +pub struct CacheVolume {} + +impl CacheVolume { + /// + pub fn id(&self) -> Option { + todo!() + } +} + +impl Input for CacheVolume {} + +/// 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) -> Option { + todo!() + } + + /// The filesystem tree at this ref. + pub fn tree(&self) -> Option { + todo!() + } +} + +impl Input for GitRef {} + +/// 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) -> Option { + todo!() + } + + /// The value of this secret. + pub fn plaintext(&self) -> Option { + todo!() + } +} + +impl Input for Secret {} + +/// An environment variable on the host environment. +pub struct HostVariable {} + +impl HostVariable { + /// A secret referencing the value of this variable. + pub fn secret(&self) -> Option { + todo!() + } + + /// The value of this variable. + pub fn value(&self) -> Option { + todo!() + } +} + +impl Input for HostVariable {} + +/// +pub struct Query {} + +impl Query { + /// Constructs a cache volume for a given cache key. + pub fn cache_volume(&self) -> Option { + 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) -> Option { + todo!() + } + + /// The default platform of the builder. + pub fn default_platform(&self) -> Option { + todo!() + } + + /// Load a directory by ID. No argument produces an empty directory. + pub fn directory(&self) -> Option { + todo!() + } + + /// Loads a file by ID. + pub fn file(&self) -> File { + todo!() + } + + /// Queries a git repository. + pub fn git(&self) -> Option { + todo!() + } + + /// Queries the host environment. + pub fn host(&self) -> Option { + todo!() + } + + /// Returns a file containing an http remote url content. + pub fn http(&self) -> Option { + todo!() + } + + /// Creates a named sub-pipeline + pub fn pipeline(&self) -> Option { + todo!() + } + + /// Look up a project by name + pub fn project(&self) -> Option { + todo!() + } + + /// Loads a secret from its ID. + pub fn secret(&self) -> Option { + todo!() + } + + /// Loads a socket by its ID. + pub fn socket(&self) -> Option { + todo!() + } +} + +impl Input for Query {} + +/// A directory. +pub struct Directory {} + +impl Directory { + /// Gets the difference between this directory and an another directory. + pub fn diff(&self) -> Option { + todo!() + } + + /// Retrieves a directory at the given path. + pub fn directory(&self) -> Option { + todo!() + } + + /// Builds a new Docker container from this directory. + pub fn docker_build(&self) -> Option { + todo!() + } + + /// Returns a list of files and directories at the given path. + pub fn entries(&self) -> Option>> { + todo!() + } + + /// Writes the contents of the directory to a path on the host. + pub fn export(&self) -> Option { + todo!() + } + + /// Retrieves a file at the given path. + pub fn file(&self) -> Option { + todo!() + } + + /// The content-addressed identifier of the directory. + pub fn id(&self) -> Option { + todo!() + } + + /// load a project's metadata + pub fn load_project(&self) -> Option { + todo!() + } + + /// Creates a named sub-pipeline. + pub fn pipeline(&self) -> Option { + todo!() + } + + /// Retrieves this directory plus a directory written at the given path. + pub fn with_directory(&self) -> Option { + todo!() + } + + /// Retrieves this directory plus the contents of the given file copied to the given path. + pub fn with_file(&self) -> Option { + todo!() + } + + /// Retrieves this directory plus a new directory created at the given path. + pub fn with_new_directory(&self) -> Option { + todo!() + } + + /// Retrieves this directory plus a new file written at the given path. + pub fn with_new_file(&self) -> Option { + 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) -> Option { + todo!() + } + + /// Retrieves this directory with the directory at the given path removed. + pub fn without_directory(&self) -> Option { + todo!() + } + + /// Retrieves this directory with the file at the given path removed. + pub fn without_file(&self) -> Option { + todo!() + } +} + +impl Input for Directory {} + +/// A set of scripts and/or extensions +pub struct Project {} + +impl Project { + /// extensions in this project + pub fn extensions(&self) -> Vec> { + todo!() + } + + /// Code files generated by the SDKs in the project + pub fn generated_code(&self) -> Option { + todo!() + } + + /// install the project's schema + pub fn install(&self) -> Option { + todo!() + } + + /// name of the project + pub fn name(&self) -> Option { + todo!() + } + + /// schema provided by the project + pub fn schema(&self) -> String { + todo!() + } + + /// sdk used to generate code for and/or execute this project + pub fn sdk(&self) -> String { + todo!() + } +} + +impl Input for Project {} + +/// +pub struct Socket {} + +impl Socket { + /// The content-addressed identifier of the socket. + pub fn id(&self) -> Option { + todo!() + } +} + +impl Input for Socket {} + +/// A simple key value object that represents a label. +pub struct Label {} + +impl Label { + /// The label name. + pub fn name(&self) -> Option { + todo!() + } + + /// The label value. + pub fn value(&self) -> Option { + todo!() + } +} + +impl Input for Label {} + +/// A git repository. +pub struct GitRepository {} + +impl GitRepository { + /// Returns details on one branch. + pub fn branch(&self) -> Option { + todo!() + } + + /// Lists of branches on the repository. + pub fn branches(&self) -> Option>> { + todo!() + } + + /// Returns details on one commit. + pub fn commit(&self) -> Option { + todo!() + } + + /// Returns details on one tag. + pub fn tag(&self) -> Option { + todo!() + } + + /// Lists of tags on the repository. + pub fn tags(&self) -> Option>> { + todo!() + } +} + +impl Input for GitRepository {} + +/// A simple key value object that represents an environment variable. +pub struct EnvVariable {} + +impl EnvVariable { + /// The environment variable name. + pub fn name(&self) -> Option { + todo!() + } + + /// The environment variable value. + pub fn value(&self) -> Option { + todo!() + } +} + +impl Input for EnvVariable {} + +/// Information about the host execution environment. +pub struct Host {} + +impl Host { + /// Accesses a directory on the host. + pub fn directory(&self) -> Option { + todo!() + } + + /// Accesses an environment variable on the host. + pub fn env_variable(&self) -> HostVariable { + todo!() + } + + /// Accesses a Unix socket on the host. + pub fn unix_socket(&self) -> Option { + todo!() + } + + /// Retrieves the current working directory on the host. + pub fn workdir(&self) -> Option { + todo!() + } +} + +impl Input for Host {}