mirror of
https://github.com/kjuulh/dagger-rs.git
synced 2025-12-28 18:51:02 +01:00
Compare commits
6 Commits
99bab8e1b0
...
2eb027754b
| Author | SHA1 | Date | |
|---|---|---|---|
|
2eb027754b
|
|||
|
19b46b6cf0
|
|||
|
c4edd29f50
|
|||
|
04526c052b
|
|||
|
52a0db3e31
|
|||
|
3b5b59ba1c
|
@@ -15,15 +15,16 @@ Work in progress. This is not ready for usage yet
|
|||||||
- [x] Enums
|
- [x] Enums
|
||||||
- [x] Input
|
- [x] Input
|
||||||
- [x] Objects
|
- [x] Objects
|
||||||
- [ ] Implement context and querier
|
- [x] Implement context and querier
|
||||||
- [x] Marshaller
|
- [x] Marshaller
|
||||||
- [x] Querier
|
- [x] Querier
|
||||||
- [x] Context
|
- [x] Context
|
||||||
- [ ] Deserializer for nested response (bind)
|
- [x] Deserializer for nested response (bind)
|
||||||
- [ ] Add codegen to hook into querier
|
- [ ] Add codegen to hook into querier
|
||||||
- [ ] fix build / release cycle
|
- [ ] fix build / release cycle
|
||||||
- [ ] general api stabilisation
|
- [ ] general api stabilisation
|
||||||
- [ ] document usage
|
- [ ] document usage
|
||||||
|
- [ ] make async variant
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
|
|||||||
@@ -19,27 +19,31 @@ pub fn render_fields(fields: &Vec<FullTypeFields>) -> eyre::Result<Option<rust::
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut tkns = rust::Tokens::new();
|
let mut tkns = rust::Tokens::new();
|
||||||
if let Some(desc) = &description {
|
|
||||||
tkns.append(desc);
|
|
||||||
tkns.push()
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(args) = args.as_ref() {
|
if let Some(args) = args.as_ref() {
|
||||||
if let Some(desc) = args.description.as_ref() {
|
tkns.append(quote! {
|
||||||
tkns.append("/// # Arguments");
|
$description
|
||||||
tkns.push();
|
pub struct $(&name)Args {
|
||||||
tkns.append("///");
|
$(&args.args)
|
||||||
tkns.push();
|
}
|
||||||
tkns.append(desc);
|
});
|
||||||
tkns.push();
|
tkns.push();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tkns.append(quote! {
|
tkns.append(quote! {
|
||||||
pub fn $name(
|
pub fn $(&name)(
|
||||||
&self,
|
&self,
|
||||||
$(if let Some(args) = args.as_ref() => $(&args.args))
|
$(if let Some(_) = args.as_ref() => args: $(&name)Args)
|
||||||
) -> $output {
|
) -> $(&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!()
|
todo!()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ impl Handler for Input {
|
|||||||
.ok_or(eyre::anyhow!("could not find name"))?;
|
.ok_or(eyre::anyhow!("could not find name"))?;
|
||||||
let description = render_description(t);
|
let description = render_description(t);
|
||||||
|
|
||||||
let input = rust::import("dagger_core", "Input");
|
//let input = rust::import("dagger_core", "Input");
|
||||||
|
|
||||||
let fields = match t.input_fields.as_ref() {
|
let fields = match t.input_fields.as_ref() {
|
||||||
Some(i) => render_input_fields(i)?,
|
Some(i) => render_input_fields(i)?,
|
||||||
@@ -32,8 +32,6 @@ impl Handler for Input {
|
|||||||
pub struct $name {
|
pub struct $name {
|
||||||
$(if fields.is_some() => $fields)
|
$(if fields.is_some() => $fields)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $input for $name {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(out)
|
Ok(out)
|
||||||
@@ -98,15 +96,11 @@ mod tests {
|
|||||||
fields: None,
|
fields: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let expected = r#"use dagger_core::Input;
|
let expected = r#"pub struct BuildArg {
|
||||||
|
pub name: String,
|
||||||
|
|
||||||
pub struct BuildArg {
|
pub value: String,
|
||||||
pub name: Option<String>,
|
|
||||||
|
|
||||||
pub value: Option<String>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Input for BuildArg {}
|
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
let output = input.render(&t).unwrap();
|
let output = input.render(&t).unwrap();
|
||||||
|
|||||||
@@ -19,8 +19,6 @@ impl Handler for Object {
|
|||||||
.ok_or(eyre::anyhow!("could not find name"))?;
|
.ok_or(eyre::anyhow!("could not find name"))?;
|
||||||
let description = render_description(t);
|
let description = render_description(t);
|
||||||
|
|
||||||
let input = rust::import("dagger_core", "Input");
|
|
||||||
|
|
||||||
let fields = match t.fields.as_ref() {
|
let fields = match t.fields.as_ref() {
|
||||||
Some(i) => fields::render_fields(i)?,
|
Some(i) => fields::render_fields(i)?,
|
||||||
None => None,
|
None => None,
|
||||||
@@ -40,8 +38,6 @@ impl Handler for Object {
|
|||||||
impl $name {
|
impl $name {
|
||||||
$(if fields.is_some() => $fields)
|
$(if fields.is_some() => $fields)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl $input for $name {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(out)
|
Ok(out)
|
||||||
@@ -51,7 +47,8 @@ impl Handler for Object {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use dagger_core::introspection::{
|
use dagger_core::introspection::{
|
||||||
FullType, FullTypeFields, FullTypeFieldsType, TypeRef, __TypeKind,
|
FullType, FullTypeFields, FullTypeFieldsArgs, FullTypeFieldsType, InputValue, TypeRef,
|
||||||
|
__TypeKind,
|
||||||
};
|
};
|
||||||
use pretty_assertions::assert_eq;
|
use pretty_assertions::assert_eq;
|
||||||
|
|
||||||
@@ -88,21 +85,78 @@ mod tests {
|
|||||||
enum_values: None,
|
enum_values: None,
|
||||||
possible_types: None,
|
possible_types: None,
|
||||||
};
|
};
|
||||||
let expected = r#"use dagger_core::Input;
|
let expected = r#"
|
||||||
|
|
||||||
|
|
||||||
/// A directory whose contents persists across sessions
|
/// A directory whose contents persists across sessions
|
||||||
pub struct CacheVolume {}
|
pub struct CacheVolume {}
|
||||||
|
|
||||||
impl CacheVolume {
|
impl CacheVolume {
|
||||||
pub fn id(
|
pub fn id(
|
||||||
&self,
|
&self,
|
||||||
) -> Option<CacheID> {
|
) -> CacheID {
|
||||||
|
let query = self.selection.select("id");
|
||||||
|
|
||||||
|
CacheID {
|
||||||
|
conn: self.conn.clone(),
|
||||||
|
proc: self.proc.clone(),
|
||||||
|
selection: query,
|
||||||
|
}
|
||||||
|
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
"#;
|
||||||
|
let handler = Object {};
|
||||||
|
let obj = handler.render(&t).unwrap();
|
||||||
|
let actual = obj.to_file_string().unwrap();
|
||||||
|
|
||||||
impl Input for CacheVolume {}
|
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 handler = Object {};
|
||||||
let obj = handler.render(&t).unwrap();
|
let obj = handler.render(&t).unwrap();
|
||||||
|
|||||||
@@ -6,14 +6,6 @@ use crate::predicates::{
|
|||||||
is_custom_scalar_type_ref, is_list_type, is_required_type_ref, is_scalar_type_ref,
|
is_custom_scalar_type_ref, is_list_type, is_required_type_ref, is_scalar_type_ref,
|
||||||
};
|
};
|
||||||
|
|
||||||
//fn optional(t: rust::Tokens) -> impl FormatInto<Rust> {
|
|
||||||
// quote_fn! {"Option<$[const](t)>"}
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//fn required(t: rust::Tokens) -> impl FormatInto<Rust> {
|
|
||||||
// quote_fn! {"$[const](t)"}
|
|
||||||
//}
|
|
||||||
|
|
||||||
pub fn render_type_ref(inner: &TypeRef) -> eyre::Result<rust::Tokens> {
|
pub fn render_type_ref(inner: &TypeRef) -> eyre::Result<rust::Tokens> {
|
||||||
let extract_of_type = |t: &TypeRef| -> Option<TypeRef> {
|
let extract_of_type = |t: &TypeRef| -> Option<TypeRef> {
|
||||||
return t.clone().of_type.map(|t| *t);
|
return t.clone().of_type.map(|t| *t);
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
fs::canonicalize,
|
fs::canonicalize,
|
||||||
io::{BufRead, BufReader},
|
io::{BufRead, BufReader},
|
||||||
@@ -101,7 +100,7 @@ impl InnerCliSession {
|
|||||||
let stderr_bufr = BufReader::new(stderr);
|
let stderr_bufr = BufReader::new(stderr);
|
||||||
for line in stderr_bufr.lines() {
|
for line in stderr_bufr.lines() {
|
||||||
let out = line.unwrap();
|
let out = line.unwrap();
|
||||||
panic!("could not start dagger session: {}", out)
|
//panic!("could not start dagger session: {}", out)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use std::{collections::HashMap, ops::Add, sync::Arc};
|
use std::{collections::HashMap, ops::Add, sync::Arc};
|
||||||
|
|
||||||
|
use eyre::Context;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::task::block_in_place;
|
|
||||||
|
|
||||||
pub fn query() -> Selection {
|
pub fn query() -> Selection {
|
||||||
Selection::default()
|
Selection::default()
|
||||||
@@ -106,11 +106,13 @@ impl Selection {
|
|||||||
|
|
||||||
dbg!(&query);
|
dbg!(&query);
|
||||||
|
|
||||||
let resp: Option<D> = match basic.block_on(gql_client.query(&query)) {
|
let resp: Option<serde_json::Value> = match basic.block_on(gql_client.query(&query)) {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(e) => eyre::bail!(e),
|
Err(e) => eyre::bail!(e),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let resp: Option<D> = self.unpack_resp(resp)?;
|
||||||
|
|
||||||
Ok(resp)
|
Ok(resp)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,6 +131,33 @@ impl Selection {
|
|||||||
selections.reverse();
|
selections.reverse();
|
||||||
selections
|
selections
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn unpack_resp<D>(&self, resp: Option<serde_json::Value>) -> eyre::Result<Option<D>>
|
||||||
|
where
|
||||||
|
D: for<'de> Deserialize<'de>,
|
||||||
|
{
|
||||||
|
match resp {
|
||||||
|
Some(r) => self.unpack_resp_value::<D>(r).map(|v| Some(v)),
|
||||||
|
None => Ok(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unpack_resp_value<D>(&self, r: serde_json::Value) -> eyre::Result<D>
|
||||||
|
where
|
||||||
|
D: for<'de> Deserialize<'de>,
|
||||||
|
{
|
||||||
|
if let Some(o) = r.as_object() {
|
||||||
|
let keys = o.keys();
|
||||||
|
if keys.len() != 1 {
|
||||||
|
eyre::bail!("too many nested objects inside graphql response")
|
||||||
|
}
|
||||||
|
|
||||||
|
let first = keys.into_iter().next().unwrap();
|
||||||
|
return self.unpack_resp_value(o.get(first).unwrap().clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
serde_json::from_value::<D>(r).context("could not deserialize response")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -16,5 +16,5 @@ fn test_example_container() {
|
|||||||
)
|
)
|
||||||
.stdout();
|
.stdout();
|
||||||
|
|
||||||
assert_eq!(out, Some("3.16.2".to_string()))
|
assert_eq!(out, Some("3.16.2\n".to_string()))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user