Compare commits

..

2 Commits

Author SHA1 Message Date
040f97dfb8 Merge branch 'main' into feat/lint-pr 2023-02-19 12:52:49 +01:00
8c66f3a076 feat(ci): lint pr 2023-02-19 12:52:32 +01:00
76 changed files with 1395 additions and 34741 deletions

View File

@@ -8,7 +8,6 @@ env:
CARGO_TERM_COLOR: always CARGO_TERM_COLOR: always
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
_EXPERIMENTAL_DAGGER_CACHE_CONFIG: type=gha;mode=max
jobs: jobs:
deploy: deploy:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@@ -1,12 +0,0 @@
# Architecture
- `.` Root project mainly used for generating the CLI, which in turn is used to
bootstrap the code generation from `dagger`
- `crates/dagger-core` Contains all base types used during actual usage. This is
where the primary logic lives in which the user interacts (\*disclaimer: most
stuff haven't moved in here yet.)
- `crates/dagger-sdk` Contains the actual sdk in which the user interacts,
`dagger-core` is reexported through this API as well.
- `crates/dagger-codegen` This is the bulk of the work, it takes the input
graphql and spits out the API in which the user interacts, this is heavily
inspired by other `dagger-sdk's`. It primarily turns graphql into rust code.

View File

@@ -5,57 +5,6 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## v0.2.10 (2023-02-20)
### Bug Fixes
- <csr-id-75bc17e57db222492c6ffd2dfe80208d2bda75c9/> Fix async panic on blocking #19
Replaced internal threads with tokio spawn functions
### Commit Statistics
<csr-read-only-do-not-edit/>
- 1 commit contributed to the release.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Fix async panic on blocking #19 ([`75bc17e`](https://github.com/kjuulh/dagger-rs/commit/75bc17e57db222492c6ffd2dfe80208d2bda75c9))
</details>
## v0.2.9 (2023-02-19)
### New Features
- <csr-id-19ed6c267f779b72430422c463ceed553f6fc618/> re-export through lib.rs
this means that you can now use dagger_sdk::connect() instead of
dagger_sdk::client::connect();
### Commit Statistics
<csr-read-only-do-not-edit/>
- 1 commit contributed to the release.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- re-export through lib.rs ([`19ed6c2`](https://github.com/kjuulh/dagger-rs/commit/19ed6c267f779b72430422c463ceed553f6fc618))
</details>
## v0.2.8 (2023-02-19) ## v0.2.8 (2023-02-19)
### New Features ### New Features

View File

@@ -1,11 +0,0 @@
# Contributing
The sdk is still quite young, so feel free to either:
- Refactor
- Document
- Improve the code
Feel free to ping me on discord @Hermansen#4325, or just create an issue if
there is a missing feature, or you'd like some mentorship in getting into the
code

579
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,25 +1,44 @@
[package]
name = "dagger-rs"
version = "0.2.8"
edition = "2021"
readme = "README.md"
license-file = "LICENSE.MIT"
description = "A dagger sdk for rust, written in rust"
repository = "https://github.com/kjuulh/dagger-rs"
publish = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[workspace] [workspace]
members = [ members = [
"crates/dagger-codegen", "crates/dagger-codegen",
"crates/dagger-sdk", "crates/dagger-sdk",
"crates/dagger-core", "crates/dagger-core",
"crates/dagger-bootstrap",
"ci", "ci",
] ]
[workspace.dependencies] [dependencies]
dagger-codegen = { path = "crates/dagger-codegen", version = "^0.2.5" } dagger-codegen = { path = "crates/dagger-codegen", version = "^0.2.2" }
dagger-core = { path = "crates/dagger-core", version = "^0.2.8" } dagger-core = { path = "crates/dagger-core", version = "^0.2.2" }
dagger-bootstrap = { path = "crates/dagger-bootstrap", version = "^0.2.10" }
dagger-sdk = { path = "crates/dagger-sdk", version = "^0.2.19" }
clap = "4.1.6"
dirs = "4.0.0"
eyre = "0.6.8" eyre = "0.6.8"
color-eyre = "0.6.2" flate2 = { version = "1.0.25", features = ["zlib"] }
genco = "0.17.3"
graphql-introspection-query = "0.2.0"
graphql_client = { version = "0.12.0", features = [
"reqwest",
"reqwest-blocking",
] }
hex = "0.4.3"
hex-literal = "0.3.4"
platform-info = "1.0.2"
reqwest = { version = "0.11.14", features = ["stream", "blocking", "deflate"] }
serde = { version = "1.0.152", features = ["derive"] } serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.93" serde_json = "1.0.93"
tokio = { version = "1.25.0", features = ["full"] } sha2 = "0.10.6"
tracing = { version = "0.1.37", features = ["log"] } tar = "0.4.38"
tracing-subscriber = { version = "0.3.16", features = [ tempfile = "3.3.0"
"tracing-log", color-eyre = "0.6.2"
"tracing",
] }

View File

@@ -1,60 +0,0 @@
[tasks.codegen]
command = "cargo"
args = ["run", "-p", "ci", "--", "codegen"]
workspace = false
[tasks.local_codegen]
command = "cargo"
args = [
"run",
"-p",
"dagger-bootstrap",
"--",
"generate",
"--output",
"crates/dagger-sdk/src/gen.rs",
]
workspace = false
[tasks.build]
command = "cargo"
args = ["run", "-p", "ci", "--", "ci"]
dependencies = ["codegen"]
workspace = false
[tasks.fmt]
command = "cargo"
args = ["fmt", "--all"]
workspace = false
[tasks.fix]
command = "cargo"
args = ["fix", "--workspace", "--allow-dirty"]
dependencies = ["fmt"]
workspace = false
[tasks.gen]
dependencies = ["local_codegen", "fmt", "fix"]
workspace = false
[tasks.release_crate]
command = "cargo"
args = [
"smart-release",
"--allow-fully-generated-changelogs",
"--update-crates-index",
"dagger-sdk",
]
dependencies = ["codegen", "fix"]
workspace = false
[tasks.release_crate_commit]
command = "cargo"
args = [
"smart-release",
"-e",
"--allow-fully-generated-changelogs",
"--update-crates-index",
"dagger-sdk",
]
workspace = false

View File

@@ -1,55 +1,40 @@
# dagger-sdk # dagger-rs
A dagger sdk written in rust for rust. A dagger sdk written in rust for rust.
## Examples # Usage
See [examples](./crates/dagger-sdk/examples/) See [dagger-sdk](./crates/dagger-sdk/README.md)
Run them like so ### Status
```bash - [x] dagger cli downloader
cargo run --example first-pipeline - [x] dagger network session
``` - [x] graphql rust codegen (User API)
- [x] Scalars
- [x] Enums
- [x] Input
- [x] Objects
- [x] Implement context and querier
- [x] Marshaller
- [x] Querier
- [x] Context
- [x] Deserializer for nested response (bind)
- [x] Add codegen to hook into querier
- [ ] fix build / release cycle
- [ ] general api stabilisation
- [x] document usage
- [ ] make async variant
The examples match the folder name in each directory in examples ## Architecture
## Install - `.` Root project mainly used for generating the CLI, which in turn is used to
bootstrap the code generation from `dagger`
Simply install like: - `crates/dagger-core` Contains all base types used during actual usage. This is
where the primary logic lives in which the user interacts (\*disclaimer: most
```bash stuff haven't moved in here yet.)
cargo add dagger-sdk - `crates/dagger-sdk` Contains the actual sdk in which the user interacts,
``` `dagger-core` is reexported through this API as well.
- `crates/dagger-codegen` This is the bulk of the work, it takes the input
### Usage graphql and spits out the API in which the user interacts, this is heavily
inspired by other `dagger-sdk's`. It primarily turns graphql into rust code.
```rust
#[tokio::main]
async fn main() -> eyre::Result<()> {
let client = dagger_sdk::connect().await?;
let version = client
.container()
.from("golang:1.19")
.with_exec(vec!["go", "version"])
.stdout()
.await?;
println!("Hello from Dagger and {}", version.trim());
Ok(())
}
```
And run it like a normal application:
```bash
cargo run
```
### Contributing
See [CONTRIBUTING](./CONTRIBUTING.md)
or just cargo make codegen

View File

@@ -1,73 +0,0 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## v0.1.0 (2023-02-20)
<csr-id-06e2638e1fec0579d992792b94838629739bb1f0/>
<csr-id-48433cf36884ec9fa4cfed8bc5d4b3e8422c0ab9/>
<csr-id-45d646203704aed317ee2273b825ae708e83ca32/>
<csr-id-c35c104b49dc2f4456ed18e353bf8d4017cff640/>
### Chore
- <csr-id-06e2638e1fec0579d992792b94838629739bb1f0/> with actual await on connect
- <csr-id-48433cf36884ec9fa4cfed8bc5d4b3e8422c0ab9/> with dagger v0.2.10
- <csr-id-45d646203704aed317ee2273b825ae708e83ca32/> with async/await
- <csr-id-c35c104b49dc2f4456ed18e353bf8d4017cff640/> update ci to use dagger-sdk v0.2.6
### Documentation
- <csr-id-30b7511e454d4695cc1106a3d303b20aa8647fe4/> add changelog
### New Features
- <csr-id-691ecfbf52fa24a466d554b7b9701d67c33a42a5/> ci with dagger v0.2.2
- <csr-id-f42da8416a5450c7c3c924353c3cc9112afd18f0/> with sccache
### Bug Fixes
- <csr-id-f40ba9b40312a66b7699209fdddc0153ef139931/> with older version of dagger-sdk
- <csr-id-02006d40fc2c0383e0412c15c36db9af7eda991f/> without phantom data
- <csr-id-199fe16dbf426f287a7a5237c25bc16a4cae49bc/> update rust crate dagger-sdk to 0.2.1
- <csr-id-25fb9d4f24af8e7d6d81463c19a07a718b8a312a/> with secret
- <csr-id-d72313051b9b46a6eeaa909a11850b3d8fc75e81/> with test changes
### Commit Statistics
<csr-read-only-do-not-edit/>
- 16 commits contributed to the release over the course of 2 calendar days.
- 12 commits were understood as [conventional](https://www.conventionalcommits.org).
- 2 unique issues were worked on: [#7](https://github.com/kjuulh/dagger-rs/issues/7), [#8](https://github.com/kjuulh/dagger-rs/issues/8)
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **[#7](https://github.com/kjuulh/dagger-rs/issues/7)**
- add ci ([`4ce58a4`](https://github.com/kjuulh/dagger-rs/commit/4ce58a418c0ccef6cc0bfbaa878453f03c02dffb))
* **[#8](https://github.com/kjuulh/dagger-rs/issues/8)**
- feature with workspace ([`03e022f`](https://github.com/kjuulh/dagger-rs/commit/03e022fcaccd30ef0566dcfe31beb3473706bd1d))
* **Uncategorized**
- add changelog ([`30b7511`](https://github.com/kjuulh/dagger-rs/commit/30b7511e454d4695cc1106a3d303b20aa8647fe4))
- with actual await on connect ([`06e2638`](https://github.com/kjuulh/dagger-rs/commit/06e2638e1fec0579d992792b94838629739bb1f0))
- with dagger v0.2.10 ([`48433cf`](https://github.com/kjuulh/dagger-rs/commit/48433cf36884ec9fa4cfed8bc5d4b3e8422c0ab9))
- with older version of dagger-sdk ([`f40ba9b`](https://github.com/kjuulh/dagger-rs/commit/f40ba9b40312a66b7699209fdddc0153ef139931))
- with async/await ([`45d6462`](https://github.com/kjuulh/dagger-rs/commit/45d646203704aed317ee2273b825ae708e83ca32))
- update ci to use dagger-sdk v0.2.6 ([`c35c104`](https://github.com/kjuulh/dagger-rs/commit/c35c104b49dc2f4456ed18e353bf8d4017cff640))
- without phantom data ([`02006d4`](https://github.com/kjuulh/dagger-rs/commit/02006d40fc2c0383e0412c15c36db9af7eda991f))
- ci with dagger v0.2.2 ([`691ecfb`](https://github.com/kjuulh/dagger-rs/commit/691ecfbf52fa24a466d554b7b9701d67c33a42a5))
- with bin cache ([`3cb83bb`](https://github.com/kjuulh/dagger-rs/commit/3cb83bb79ceda52a0bf459850252e3902b7352fa))
- update rust crate dagger-sdk to 0.2.1 ([`199fe16`](https://github.com/kjuulh/dagger-rs/commit/199fe16dbf426f287a7a5237c25bc16a4cae49bc))
- with secret ([`25fb9d4`](https://github.com/kjuulh/dagger-rs/commit/25fb9d4f24af8e7d6d81463c19a07a718b8a312a))
- with sccache ([`f42da84`](https://github.com/kjuulh/dagger-rs/commit/f42da8416a5450c7c3c924353c3cc9112afd18f0))
- with test changes ([`d723130`](https://github.com/kjuulh/dagger-rs/commit/d72313051b9b46a6eeaa909a11850b3d8fc75e81))
- add ci ([`468bca4`](https://github.com/kjuulh/dagger-rs/commit/468bca4a69ec321b3ae1304d29d1be66a921a7db))
</details>

View File

@@ -8,6 +8,5 @@ edition = "2021"
[dependencies] [dependencies]
clap = "4.1.6" clap = "4.1.6"
color-eyre = "0.6.2" color-eyre = "0.6.2"
dagger-sdk = { path = "../crates/dagger-sdk/", version = "^0.2.19" } dagger-sdk = "0.2.2"
eyre = "0.6.8" eyre = "0.6.8"
tokio = { version = "1.25.0", features = ["full"] }

View File

@@ -1,28 +1,24 @@
use std::sync::Arc; use std::sync::Arc;
use clap::ArgMatches; use dagger_sdk::gen::{Container, HostDirectoryOpts, Query};
use dagger_sdk::{Container, HostDirectoryOpts, Query};
#[tokio::main] fn main() -> eyre::Result<()> {
async fn main() -> eyre::Result<()> {
color_eyre::install().unwrap(); color_eyre::install().unwrap();
let matches = clap::Command::new("ci") let matches = clap::Command::new("ci")
.subcommand_required(true) .subcommand_required(true)
.subcommand(clap::Command::new("pr")) .subcommand(clap::Command::new("pr"))
.subcommand(clap::Command::new("release")) .subcommand(clap::Command::new("release"))
.subcommand(clap::Command::new("codegen"))
.get_matches(); .get_matches();
let client = dagger_sdk::connect().await?; let client = dagger_sdk::client::connect()?;
match matches.subcommand() { match matches.subcommand() {
Some(("pr", _)) => { Some(("pr", _)) => {
let base = select_base_image(client.clone()).await?; let base = select_base_image(client.clone());
return validate_pr(client, base).await; return validate_pr(client, base);
} }
Some(("release", subm)) => return release(client, subm).await, Some(("release", subm)) => return release(client, subm),
Some(("codegen", subm)) => return run_codegen(client, subm).await,
Some(_) => { Some(_) => {
panic!("invalid subcommand selected!") panic!("invalid subcommand selected!")
} }
@@ -32,68 +28,42 @@ async fn main() -> eyre::Result<()> {
} }
} }
async fn run_codegen(client: Arc<Query>, _subm: &ArgMatches) -> eyre::Result<()> { fn release(client: Arc<Query>, subm: &clap::ArgMatches) -> Result<(), color_eyre::Report> {
let docker_cli = client let src_dir = client.host().directory(
.container() ".".into(),
.from("docker:cli") Some(HostDirectoryOpts {
.file("/usr/local/bin/docker"); exclude: Some(vec!["target/".into()]),
let socket = client.host().unix_socket("/var/run/docker.sock");
let container = get_dependencies(client).await?;
let generated_image = container
.with_exec(vec!["mkdir", "-p", "/mnt/output"])
.with_mounted_file("/usr/bin/docker", docker_cli.id().await?)
.with_unix_socket("/var/run/docker.sock", socket.id().await?)
.with_exec(vec![
"cargo",
"run",
"--",
"generate",
"--output",
"crates/dagger-sdk/gen.rs",
])
.with_exec(vec!["cargo", "fmt", "--all"])
.with_exec(vec!["cargo", "fix", "--workspace", "--allow-dirty"])
.with_exec(vec!["cargo", "fmt", "--all"])
.with_exec(vec!["mv", "crates/dagger-sdk/gen.rs", "/mnt/output/gen.rs"]);
let _ = generated_image.exit_code().await?;
generated_image
.file("/mnt/output/gen.rs")
.export("crates/dagger-sdk/src/gen.rs")
.await?;
Ok(())
}
async fn release(client: Arc<Query>, _subm: &clap::ArgMatches) -> Result<(), color_eyre::Report> {
let src_dir = client.host().directory_opts(
".",
HostDirectoryOpts {
exclude: Some(vec!["target/"]),
include: None, include: None,
}, }),
); );
let base_image = client let base_image = client
.container() .container(None)
.from("rust:latest") .from("rust:latest".into())
.with_workdir("app") .with_workdir("app".into())
.with_mounted_directory("/app/", src_dir.id().await?); .with_mounted_directory("/app/".into(), src_dir.id());
let container = base_image let container = base_image
.with_exec(vec!["cargo", "install", "cargo-smart-release"]) .with_exec(
.with_exec(vec![ vec![
"cargo", "cargo".into(),
"smart-release", "install".into(),
"--execute", "cargo-smart-release".into(),
"--allow-fully-generated-changelogs", ],
"--no-changelog-preview", None,
"dagger-sdk", )
"dagger-sdk", .with_exec(
]); vec![
let exit = container.exit_code().await?; "cargo".into(),
"smart-release".into(),
"--execute".into(),
"--allow-fully-generated-changelogs".into(),
"--no-changelog-preview".into(),
"dagger-rs".into(),
"dagger-sdk".into(),
],
None,
);
let exit = container.exit_code();
if exit != 0 { if exit != 0 {
eyre::bail!("container failed with non-zero exit code"); eyre::bail!("container failed with non-zero exit code");
} }
@@ -103,123 +73,153 @@ async fn release(client: Arc<Query>, _subm: &clap::ArgMatches) -> Result<(), col
Ok(()) Ok(())
} }
async fn get_dependencies(client: Arc<Query>) -> eyre::Result<Container> { fn get_dependencies(client: Arc<Query>) -> Container {
let cargo_dir = client.host().directory_opts( let cargo_dir = client.host().directory(
".", ".".into(),
HostDirectoryOpts { Some(HostDirectoryOpts {
exclude: None, exclude: None,
include: Some(vec![ include: Some(vec![
"**/Cargo.lock", "**/Cargo.lock".into(),
"**/Cargo.toml", "**/Cargo.toml".into(),
"**/main.rs", "**/main.rs".into(),
"**/lib.rs", "**/lib.rs".into(),
]), ]),
}, }),
); );
let src_dir = client.host().directory_opts( let src_dir = client.host().directory(
".", ".".into(),
HostDirectoryOpts { Some(HostDirectoryOpts {
exclude: Some(vec!["target/"]), exclude: Some(vec!["target/".into()]),
include: None, include: None,
}, }),
); );
let cache_cargo_index_dir = client.cache_volume("cargo_index"); let cache_cargo_index_dir = client.cache_volume("cargo_index".into());
let _cache_cargo_deps = client.cache_volume("cargo_deps"); let cache_cargo_deps = client.cache_volume("cargo_deps".into());
let cache_cargo_bin = client.cache_volume("cargo_bin_cache"); let cache_cargo_bin = client.cache_volume("cargo_bin_cache".into());
let minio_url = "https://github.com/mozilla/sccache/releases/download/v0.3.3/sccache-v0.3.3-x86_64-unknown-linux-musl.tar.gz"; let minio_url = "https://github.com/mozilla/sccache/releases/download/v0.3.3/sccache-v0.3.3-x86_64-unknown-linux-musl.tar.gz".into();
let base_image = client let base_image = client
.container() .container(None)
.from("rustlang/rust:nightly") .from("rust:latest".into())
.with_workdir("app") .with_workdir("app".into())
.with_exec(vec!["apt-get", "update"]) .with_exec(vec!["apt-get".into(), "update".into()], None)
.with_exec(vec!["apt-get", "install", "--yes", "libpq-dev", "wget"]) .with_exec(
.with_exec(vec!["wget", minio_url]) vec![
.with_exec(vec![ "apt-get".into(),
"tar", "install".into(),
"xzf", "--yes".into(),
"sccache-v0.3.3-x86_64-unknown-linux-musl.tar.gz", "libpq-dev".into(),
]) "wget".into(),
.with_exec(vec![ ],
"mv", None,
"sccache-v0.3.3-x86_64-unknown-linux-musl/sccache", )
"/usr/local/bin/sccache", .with_exec(vec!["wget".into(), minio_url], None)
]) .with_exec(
.with_exec(vec!["chmod", "+x", "/usr/local/bin/sccache"]) vec![
//.with_env_variable("RUSTC_WRAPPER", "/usr/local/bin/sccache") "tar".into(),
"xzf".into(),
"sccache-v0.3.3-x86_64-unknown-linux-musl.tar.gz".into(),
],
None,
)
.with_exec(
vec![
"mv".into(),
"sccache-v0.3.3-x86_64-unknown-linux-musl/sccache".into(),
"/usr/local/bin/sccache".into(),
],
None,
)
.with_exec(
vec!["chmod".into(), "+x".into(), "/usr/local/bin/sccache".into()],
None,
)
.with_env_variable("RUSTC_WRAPPER".into(), "/usr/local/bin/sccache".into())
.with_env_variable( .with_env_variable(
"AWS_ACCESS_KEY_ID", "AWS_ACCESS_KEY_ID".into(),
std::env::var("AWS_ACCESS_KEY_ID").unwrap_or("".into()), std::env::var("AWS_ACCESS_KEY_ID").unwrap_or("".into()),
) )
.with_env_variable( .with_env_variable(
"AWS_SECRET_ACCESS_KEY", "AWS_SECRET_ACCESS_KEY".into(),
std::env::var("AWS_SECRET_ACCESS_KEY").unwrap_or("".into()), std::env::var("AWS_SECRET_ACCESS_KEY").unwrap_or("".into()),
) )
.with_env_variable("SCCACHE_BUCKET", "sccache") .with_env_variable("SCCACHE_BUCKET".into(), "sccache".into())
.with_env_variable("SCCACHE_REGION", "auto") .with_env_variable("SCCACHE_REGION".into(), "auto".into())
.with_env_variable("SCCACHE_ENDPOINT", "https://api-minio.front.kjuulh.io") .with_env_variable(
.with_mounted_cache("~/.cargo/bin", cache_cargo_bin.id().await?) "SCCACHE_ENDPOINT".into(),
.with_mounted_cache("~/.cargo/registry/index", cache_cargo_bin.id().await?) "https://api-minio.front.kjuulh.io".into(),
.with_mounted_cache("~/.cargo/registry/cache", cache_cargo_bin.id().await?) )
.with_mounted_cache("~/.cargo/git/db", cache_cargo_bin.id().await?) .with_mounted_cache("~/.cargo/bin".into(), cache_cargo_bin.id(), None)
.with_mounted_cache("target/", cache_cargo_bin.id().await?) .with_mounted_cache("~/.cargo/registry/index".into(), cache_cargo_bin.id(), None)
.with_exec(vec!["cargo", "install", "cargo-chef"]); .with_mounted_cache("~/.cargo/registry/cache".into(), cache_cargo_bin.id(), None)
.with_mounted_cache("~/.cargo/git/db".into(), cache_cargo_bin.id(), None)
.with_mounted_cache("target/".into(), cache_cargo_bin.id(), None)
.with_exec(
vec!["cargo".into(), "install".into(), "cargo-chef".into()],
None,
);
let recipe = base_image let recipe = base_image
.with_mounted_directory(".", cargo_dir.id().await?) .with_mounted_directory(".".into(), cargo_dir.id())
.with_mounted_cache("~/.cargo/.package-cache", cache_cargo_index_dir.id().await?) .with_mounted_cache(
.with_exec(vec![ "~/.cargo/.package-cache".into(),
"cargo", cache_cargo_index_dir.id(),
"chef", None,
"prepare", )
"--recipe-path", .with_exec(
"recipe.json", vec![
]) "cargo".into(),
.file("/app/recipe.json"); "chef".into(),
"prepare".into(),
"--recipe-path".into(),
"recipe.json".into(),
],
None,
)
.file("/app/recipe.json".into());
let builder_start = base_image let builder_start = base_image
.with_mounted_file("/app/recipe.json", recipe.id().await?) .with_mounted_file("/app/recipe.json".into(), recipe.id())
.with_exec(vec![ .with_exec(
"cargo", vec![
"chef", "cargo".into(),
"cook", "chef".into(),
"--release", "cook".into(),
"--workspace", "--release".into(),
"--recipe-path", "--workspace".into(),
"recipe.json", "--recipe-path".into(),
]) "recipe.json".into(),
.with_directory("/app/", src_dir.id().await?) ],
.with_exec(vec!["cargo", "build", "--all", "--release"]); None,
)
.with_mounted_cache("/app/".into(), cache_cargo_deps.id(), None)
.with_mounted_directory("/app/".into(), src_dir.id())
.with_exec(
vec![
"cargo".into(),
"build".into(),
"--all".into(),
"--release".into(),
],
None,
);
return Ok(builder_start); return builder_start;
} }
async fn select_base_image(client: Arc<Query>) -> eyre::Result<Container> { fn select_base_image(client: Arc<Query>) -> Container {
let src_dir = get_dependencies(client.clone()).await; let src_dir = get_dependencies(client.clone());
src_dir src_dir
} }
async fn validate_pr(client: Arc<Query>, container: Container) -> eyre::Result<()> { fn validate_pr(_client: Arc<Query>, container: Container) -> eyre::Result<()> {
let exit = container.exit_code().await?; //let container = container.with_exec(vec!["cargo".into(), "test".into(), "--all".into()], None);
if exit != 0 {
eyre::bail!("container failed with non-zero exit code");
}
let docker_cli = client
.container()
.from("docker:cli")
.file("/usr/local/bin/docker");
let socket = client.host().unix_socket("/var/run/docker.sock");
let container = container let exit = container.exit_code();
.with_mounted_file("/usr/bin/docker", docker_cli.id().await?)
.with_unix_socket("/var/run/docker.sock", socket.id().await?)
.with_exec(vec!["cargo", "test", "--all"]);
let exit = container.exit_code().await?;
if exit != 0 { if exit != 0 {
eyre::bail!("container failed with non-zero exit code"); eyre::bail!("container failed with non-zero exit code");
} }

View File

@@ -1,34 +0,0 @@
[package]
name = "dagger-bootstrap"
version = "0.2.10"
edition = "2021"
readme = "README.md"
license-file = "LICENSE.MIT"
description = "A dagger sdk for rust, written in rust"
repository = "https://github.com/kjuulh/dagger-sdk"
publish = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
dagger-core = { workspace = true }
dagger-codegen = { workspace = true }
eyre = { workspace = true }
color-eyre = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true }
clap = "4.1.6"
dirs = "4.0.0"
flate2 = { version = "1.0.25", features = ["zlib"] }
graphql-introspection-query = "0.2.0"
graphql_client = { version = "0.12.0", features = ["reqwest"] }
hex = "0.4.3"
hex-literal = "0.3.4"
platform-info = "1.0.2"
reqwest = { version = "0.11.14", features = ["stream", "deflate"] }
sha2 = "0.10.6"
tar = "0.4.38"
tempfile = "3.3.0"

View File

@@ -5,225 +5,6 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## v0.2.8 (2023-02-22)
### New Features
- <csr-id-266ad32dff4c8957c7cdd291f9ef6f8a8c1d055c/> with clone
### Commit Statistics
<csr-read-only-do-not-edit/>
- 1 commit contributed to the release.
- 2 days passed between releases.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- with clone ([`266ad32`](https://github.com/kjuulh/dagger-rs/commit/266ad32dff4c8957c7cdd291f9ef6f8a8c1d055c))
</details>
## v0.2.7 (2023-02-20)
### Bug Fixes
- <csr-id-a13a2a9ecbfdfac80ed8eb0cbb9e9db317da65de/> race condition in process
### Commit Statistics
<csr-read-only-do-not-edit/>
- 3 commits contributed to the release.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-core v0.2.6, dagger-codegen v0.2.7, dagger-sdk v0.2.12 ([`7179f8b`](https://github.com/kjuulh/dagger-rs/commit/7179f8b598ef04e62925e39d3f55740253c01686))
- Release dagger-core v0.2.5, dagger-sdk v0.2.12, dagger-codegen v0.2.7 ([`1725c51`](https://github.com/kjuulh/dagger-rs/commit/1725c5188e8a81069ec4a4de569484c921a94927))
- race condition in process ([`a13a2a9`](https://github.com/kjuulh/dagger-rs/commit/a13a2a9ecbfdfac80ed8eb0cbb9e9db317da65de))
</details>
## v0.2.6 (2023-02-20)
<csr-id-803cfc4f8c4d72ab7d011be5523b3bfc6039de39/>
### Chore
- <csr-id-803cfc4f8c4d72ab7d011be5523b3bfc6039de39/> ran clippy
### Commit Statistics
<csr-read-only-do-not-edit/>
- 3 commits contributed to the release.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-core v0.2.4, dagger-codegen v0.2.6, dagger-sdk v0.2.11 ([`f869e57`](https://github.com/kjuulh/dagger-rs/commit/f869e574dd788cd60e5b1b5d502bec68e300694c))
- Release dagger-core v0.2.4, dagger-codegen v0.2.6, dagger-sdk v0.2.11 ([`17ec62a`](https://github.com/kjuulh/dagger-rs/commit/17ec62a5d58232ff57391523b9851fb7b07d02ab))
- ran clippy ([`803cfc4`](https://github.com/kjuulh/dagger-rs/commit/803cfc4f8c4d72ab7d011be5523b3bfc6039de39))
</details>
## v0.2.5 (2023-02-19)
### New Features
- <csr-id-978ede68ae52f5b5150a2aa45b8d6e1fbbbee2f4/> add documentation strings
- <csr-id-9be6f435d9ea39f31a8906e55dbd3e8b1e5ec598/> Use async runtime instead of blocking.
Default to using async runtime instead of blocking. I.e.
```rust
fn main() -> eyre::Result<()> {
// ...
client.container().from("rust").publish("somewhere")?;
// ...
}
// to
async fn main() -> eyre::Result<()> {
// ...
client.container().from("rust").publish("somewhere").await?;
// ...
}
```
### Commit Statistics
<csr-read-only-do-not-edit/>
- 3 commits contributed to the release.
- 2 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-sdk v0.2.8, dagger-codegen v0.2.5 ([`0499024`](https://github.com/kjuulh/dagger-rs/commit/04990247ba8e9d0555847f582fef14849dbedebf))
- add documentation strings ([`978ede6`](https://github.com/kjuulh/dagger-rs/commit/978ede68ae52f5b5150a2aa45b8d6e1fbbbee2f4))
- Use async runtime instead of blocking. ([`9be6f43`](https://github.com/kjuulh/dagger-rs/commit/9be6f435d9ea39f31a8906e55dbd3e8b1e5ec598))
</details>
## v0.2.4 (2023-02-19)
### New Features
- <csr-id-f29ff836cfd72d5e051ca6a71a230ba1e9933091/> without Some in _opts functions
Option has been removed as a wrapper around opts. This makes it much
more convenient to use
```rust
client.container_opts(Some(ContainerOpts{}))
// ->
client.container_opts(ContainerOpts{})
```
The same options are still available, either an empty object can be
passed, or a non _opts function can be used
- <csr-id-9762da895a164e30c5dc60e89a83e934ceae47ab/> with _opts methods
Now all opt values enter into a _opts function instead of the original.
This avoids a lot of verbosity for both None in the case opts are
unwanted, and Some() if they actually are.
They are used like so:
```rust
client.container().from("...");
client.container_opts(Some(ContainerOpts{ ... }))
```
Some from opts will be removed in a future commit/pr
- <csr-id-94336d06378f035464e233b921dc3858070f582d/> move to &str instead of String and introduce builder.
This will make the api much easier to use, as we can now rely on ""
instead of "".into() for normal string values.
Introduced builder as well, which makes it much easier to use *Opts, as
it can handle the building of that, and get the benefits from String ->
&str, as that is currently not allowed for optional values
### Bug Fixes
- <csr-id-c627595fd2695e236924175d137c42f1480ccd6b/> cargo clippy
- <csr-id-02006d40fc2c0383e0412c15c36db9af7eda991f/> without phantom data
### Commit Statistics
<csr-read-only-do-not-edit/>
- 6 commits contributed to the release.
- 5 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-sdk v0.2.5, dagger-codegen v0.2.4 ([`f727318`](https://github.com/kjuulh/dagger-rs/commit/f72731807d8358fdb3d80432136b7a08bb7b1773))
- cargo clippy ([`c627595`](https://github.com/kjuulh/dagger-rs/commit/c627595fd2695e236924175d137c42f1480ccd6b))
- without Some in _opts functions ([`f29ff83`](https://github.com/kjuulh/dagger-rs/commit/f29ff836cfd72d5e051ca6a71a230ba1e9933091))
- with _opts methods ([`9762da8`](https://github.com/kjuulh/dagger-rs/commit/9762da895a164e30c5dc60e89a83e934ceae47ab))
- without phantom data ([`02006d4`](https://github.com/kjuulh/dagger-rs/commit/02006d40fc2c0383e0412c15c36db9af7eda991f))
- move to &str instead of String and introduce builder. ([`94336d0`](https://github.com/kjuulh/dagger-rs/commit/94336d06378f035464e233b921dc3858070f582d))
</details>
## v0.2.3 (2023-02-19)
### New Features
- <csr-id-de063eae858eb3335d2558a57ee6a88689635200/> with return result instead of unwrap
- <csr-id-5d667369900a47d3a6015cd3814c240bc5c54436/> remove unnecessary option returns
### Commit Statistics
<csr-read-only-do-not-edit/>
- 3 commits contributed to the release.
- 2 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-sdk v0.2.3, dagger-codegen v0.2.3, dagger-rs v0.2.9 ([`9235030`](https://github.com/kjuulh/dagger-rs/commit/92350306b3f0da40b4fc6dcaffcd90b891e83f70))
- with return result instead of unwrap ([`de063ea`](https://github.com/kjuulh/dagger-rs/commit/de063eae858eb3335d2558a57ee6a88689635200))
- remove unnecessary option returns ([`5d66736`](https://github.com/kjuulh/dagger-rs/commit/5d667369900a47d3a6015cd3814c240bc5c54436))
</details>
## v0.2.2 (2023-02-19) ## v0.2.2 (2023-02-19)
### New Features ### New Features
@@ -234,7 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
<csr-read-only-do-not-edit/> <csr-read-only-do-not-edit/>
- 2 commits contributed to the release. - 1 commit contributed to the release.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages - 0 issues like '(#ID)' were seen in commit messages
@@ -245,7 +26,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
<details><summary>view details</summary> <details><summary>view details</summary>
* **Uncategorized** * **Uncategorized**
- Release dagger-core v0.2.2, dagger-codegen v0.2.2, dagger-rs v0.2.8 ([`1638f15`](https://github.com/kjuulh/dagger-rs/commit/1638f15fba9d16512e8452f87b908d6dce417cd9))
- update to dagger v0.3.12 ([`6e5f407`](https://github.com/kjuulh/dagger-rs/commit/6e5f4074329ab0462445b31d4153f8497c483438)) - update to dagger v0.3.12 ([`6e5f407`](https://github.com/kjuulh/dagger-rs/commit/6e5f4074329ab0462445b31d4153f8497c483438))
</details> </details>

View File

@@ -1,24 +1,21 @@
[package] [package]
name = "dagger-codegen" name = "dagger-codegen"
version = "0.2.8" version = "0.2.2"
edition = "2021" edition = "2021"
readme = "README.md" readme = "README.md"
license-file = "LICENSE.MIT" license-file = "LICENSE.MIT"
description = "dagger sdk codegen library" description = "dagger sdk codegen library"
repository = "https://github.com/kjuulh/dagger-sdk" repository = "https://github.com/kjuulh/dagger-rs"
publish = true publish = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
dagger-core = { workspace = true }
eyre = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
genco = "0.17.3"
convert_case = "0.6.0" convert_case = "0.6.0"
itertools = "0.10.5" dagger-core = { path = "../dagger-core", version = "^0.2.2" }
[dev-dependencies] eyre = "0.6.8"
genco = "0.17.3"
itertools = "0.10.5"
pretty_assertions = "1.3.0" pretty_assertions = "1.3.0"
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.93"

View File

@@ -6,8 +6,8 @@ use eyre::ContextCompat;
use crate::utility::OptionExt; use crate::utility::OptionExt;
pub trait FormatTypeFuncs { pub trait FormatTypeFuncs {
fn format_kind_list(&self, representation: &str, input: bool, immutable: bool) -> String; fn format_kind_list(&self, representation: &str) -> String;
fn format_kind_scalar_string(&self, representation: &str, input: bool) -> String; fn format_kind_scalar_string(&self, representation: &str) -> String;
fn format_kind_scalar_int(&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_float(&self, representation: &str) -> String;
fn format_kind_scalar_boolean(&self, representation: &str) -> String; fn format_kind_scalar_boolean(&self, representation: &str) -> String;
@@ -36,18 +36,14 @@ impl CommonFunctions {
} }
pub fn format_input_type(&self, t: &TypeRef) -> String { pub fn format_input_type(&self, t: &TypeRef) -> String {
self.format_type(t, true, false) self.format_type(t, true)
} }
pub fn format_output_type(&self, t: &TypeRef) -> String { pub fn format_output_type(&self, t: &TypeRef) -> String {
self.format_type(t, false, false) self.format_type(t, false)
} }
pub fn format_immutable_input_type(&self, t: &TypeRef) -> String { fn format_type(&self, t: &TypeRef, input: bool) -> String {
self.format_type(t, true, true)
}
fn format_type(&self, t: &TypeRef, input: bool, immutable: bool) -> String {
let mut representation = String::new(); let mut representation = String::new();
let mut r = Some(t.clone()); let mut r = Some(t.clone());
while r.is_some() { while r.is_some() {
@@ -61,14 +57,9 @@ impl CommonFunctions {
Scalar::Float => self Scalar::Float => self
.format_type_funcs .format_type_funcs
.format_kind_scalar_float(&mut representation), .format_kind_scalar_float(&mut representation),
Scalar::String => { Scalar::String => self
if immutable { .format_type_funcs
"&'a str".into() .format_kind_scalar_string(&mut representation),
} else {
self.format_type_funcs
.format_kind_scalar_string(&mut representation, input)
}
}
Scalar::Boolean => self Scalar::Boolean => self
.format_type_funcs .format_type_funcs
.format_kind_scalar_boolean(&mut representation), .format_kind_scalar_boolean(&mut representation),
@@ -96,15 +87,12 @@ impl CommonFunctions {
.as_ref() .as_ref()
.map(|t| t.clone()) .map(|t| t.clone())
.map(|t| *t) .map(|t| *t)
.map(|t| self.format_type(&t, input, immutable)) .map(|t| self.format_type(&t, input))
.context("could not get inner type of list") .context("could not get inner type of list")
.unwrap(); .unwrap();
representation = self.format_type_funcs.format_kind_list( representation =
&mut inner_type, self.format_type_funcs.format_kind_list(&mut inner_type);
input,
immutable,
);
return representation; return representation;
} }
@@ -153,7 +141,6 @@ impl From<&TypeRef> for Scalar {
} }
} }
#[allow(dead_code)]
pub fn get_type_from_name<'t>(types: &'t [FullType], name: &'t str) -> Option<&'t FullType> { pub fn get_type_from_name<'t>(types: &'t [FullType], name: &'t str) -> Option<&'t FullType> {
types types
.into_iter() .into_iter()
@@ -196,22 +183,6 @@ pub fn type_ref_is_scalar(type_ref: &TypeRef) -> bool {
.unwrap_or(false) .unwrap_or(false)
} }
pub fn type_ref_is_enum(type_ref: &TypeRef) -> bool {
let mut type_ref = type_ref.clone();
if type_ref
.kind
.pipe(|k| *k == __TypeKind::NON_NULL)
.unwrap_or(false)
{
type_ref = *type_ref.of_type.unwrap().clone();
}
type_ref
.kind
.pipe(|k| *k == __TypeKind::ENUM)
.unwrap_or(false)
}
pub fn type_ref_is_object(type_ref: &TypeRef) -> bool { pub fn type_ref_is_object(type_ref: &TypeRef) -> bool {
let mut type_ref = type_ref.clone(); let mut type_ref = type_ref.clone();
if type_ref if type_ref
@@ -275,7 +246,6 @@ pub fn input_values_has_optionals(input_values: &[&InputValue]) -> bool {
> 0 > 0
} }
#[allow(dead_code)]
pub fn input_values_is_empty(input_values: &[InputValue]) -> bool { pub fn input_values_is_empty(input_values: &[InputValue]) -> bool {
input_values.len() > 0 input_values.len() > 0
} }

View File

@@ -1,5 +1,3 @@
#![deny(warnings)]
mod functions; mod functions;
mod generator; mod generator;
pub mod rust; pub mod rust;

View File

@@ -5,17 +5,13 @@ use super::functions::format_name;
pub struct FormatTypeFunc; pub struct FormatTypeFunc;
impl FormatTypeFuncs for FormatTypeFunc { impl FormatTypeFuncs for FormatTypeFunc {
fn format_kind_list(&self, representation: &str, _input: bool, _immutable: bool) -> String { fn format_kind_list(&self, representation: &str) -> String {
format!("Vec<{}>", representation) format!("Vec<{}>", representation)
} }
fn format_kind_scalar_string(&self, representation: &str, input: bool) -> String { fn format_kind_scalar_string(&self, representation: &str) -> String {
let mut rep = representation.to_string(); let mut rep = representation.to_string();
if input { rep.push_str("String");
rep.push_str("impl Into<String>");
} else {
rep.push_str("String");
}
rep rep
} }

View File

@@ -1,18 +1,15 @@
use convert_case::{Case, Casing}; use convert_case::{Case, Casing};
use dagger_core::introspection::{FullTypeFields, TypeRef}; use dagger_core::introspection::FullTypeFields;
use genco::prelude::rust; use genco::prelude::rust;
use genco::quote; use genco::quote;
use genco::tokens::quoted; use genco::tokens::quoted;
use itertools::Itertools;
use crate::functions::{ use crate::functions::{
type_field_has_optional, type_ref_is_enum, type_ref_is_list, type_ref_is_list_of_objects, type_field_has_optional, type_ref_is_list_of_objects, type_ref_is_object,
type_ref_is_object, type_ref_is_optional, type_ref_is_scalar, CommonFunctions, Scalar, type_ref_is_optional, CommonFunctions,
}; };
use crate::utility::OptionExt; use crate::utility::OptionExt;
use super::templates::object_tmpl::render_optional_field_args;
pub fn format_name(s: &str) -> String { pub fn format_name(s: &str) -> String {
s.to_case(Case::Pascal) s.to_case(Case::Pascal)
} }
@@ -32,83 +29,28 @@ pub fn field_options_struct_name(field: &FullTypeFields) -> Option<String> {
} }
pub fn format_function(funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> { pub fn format_function(funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> {
let is_async = field.type_.pipe(|t| &t.type_ref).pipe(|t| {
if type_ref_is_object(&t) || type_ref_is_list_of_objects(&t) {
return None;
} else {
return Some(quote! {
async
});
};
});
let signature = quote! { let signature = quote! {
pub $(is_async) fn $(field.name.pipe(|n | format_struct_name(n))) pub fn $(field.name.pipe(|n | format_struct_name(n)))
}; };
let args = format_function_args(funcs, field);
let lifecycle = format_optional_args(funcs, field)
.pipe(|(_, contains_lifecycle)| contains_lifecycle)
.and_then(|c| {
if *c {
Some(quote! {
<'a>
})
} else {
None
}
});
let args = format_function_args(funcs, field, lifecycle.as_ref());
let output_type = field let output_type = field
.type_ .type_
.pipe(|t| &t.type_ref) .pipe(|t| &t.type_ref)
.pipe(|t| render_output_type(funcs, t)); .pipe(|t| funcs.format_output_type(t));
if let Some((args, desc, true)) = args { Some(quote! {
let required_args = format_required_function_args(funcs, field); $(signature)(
Some(quote! { $(args)
$(field.description.pipe(|d| format_struct_comment(d))) ) -> $(output_type) {
$(&desc) let mut query = self.selection.select($(quoted(field.name.as_ref())));
$(&signature)(
$(required_args)
) -> $(output_type.as_ref()) {
let mut query = self.selection.select($(quoted(field.name.as_ref())));
$(render_required_args(funcs, field)) $(render_required_args(funcs, field))
$(render_optional_args(funcs, field))
$(render_execution(funcs, field)) $(render_execution(funcs, field))
} }
})
$(field.description.pipe(|d| format_struct_comment(d)))
$(&desc)
$(&signature)_opts$(lifecycle)(
$args
) -> $(output_type) {
let mut query = self.selection.select($(quoted(field.name.as_ref())));
$(render_required_args(funcs, field))
$(render_optional_args(funcs, field))
$(render_execution(funcs, field))
}
})
} else {
Some(quote! {
$(field.description.pipe(|d| format_struct_comment(d)))
$(if let Some((_, desc, _)) = &args => $desc)
$(signature)(
$(if let Some((args, _, _)) = &args => $args)
) -> $(output_type) {
let mut query = self.selection.select($(quoted(field.name.as_ref())));
$(render_required_args(funcs, field))
$(render_optional_args(funcs, field))
$(render_execution(funcs, field))
}
})
}
} }
fn render_required_args(_funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> { fn render_required_args(_funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> {
@@ -124,48 +66,8 @@ fn render_required_args(_funcs: &CommonFunctions, field: &FullTypeFields) -> Opt
let n = format_struct_name(&s.input_value.name); let n = format_struct_name(&s.input_value.name);
let name = &s.input_value.name; let name = &s.input_value.name;
if type_ref_is_scalar(&s.input_value.type_) {
if let Scalar::String =
Scalar::from(&*s.input_value.type_.of_type.as_ref().unwrap().clone())
{
return Some(quote! {
query = query.arg($(quoted(name)), $(&n).into());
});
}
}
if type_ref_is_enum(&s.input_value.type_) {
return Some(quote! {
query = query.arg_enum($(quoted(name)), $(n));
})
}
if type_ref_is_list(&s.input_value.type_) {
let inner = *s
.input_value
.type_
.of_type
.as_ref()
.unwrap()
.clone()
.of_type
.as_ref()
.unwrap()
.clone();
println!("type: {:?}", inner);
if type_ref_is_scalar(&inner) {
if let Scalar::String =
Scalar::from(&*inner.of_type.as_ref().unwrap().clone())
{
return Some(quote! {
query = query.arg($(quoted(name)), $(&n).into_iter().map(|i| i.into()).collect::<Vec<String>>());
});
}
}
}
Some(quote! { Some(quote! {
query = query.arg($(quoted(name)), $(n)); query = query.arg($(quoted(name)), $(n)).unwrap();
}) })
}) })
}) })
@@ -194,17 +96,9 @@ fn render_optional_args(_funcs: &CommonFunctions, field: &FullTypeFields) -> Opt
let n = format_struct_name(&s.input_value.name); let n = format_struct_name(&s.input_value.name);
let name = &s.input_value.name; let name = &s.input_value.name;
if type_ref_is_enum(&s.input_value.type_) {
return Some(quote! {
if let Some($(&n)) = opts.$(&n) {
query = query.arg_enum($(quoted(name)), $(n));
}
});
}
Some(quote! { Some(quote! {
if let Some($(&n)) = opts.$(&n) { if let Some($(&n)) = opts.$(&n) {
query = query.arg($(quoted(name)), $(&n)); query = query.arg($(quoted(name)), $(&n)).unwrap();
} }
}) })
}) })
@@ -217,7 +111,9 @@ fn render_optional_args(_funcs: &CommonFunctions, field: &FullTypeFields) -> Opt
} }
let required_args = quote! { let required_args = quote! {
$(for arg in args join ($['\r']) => $arg) if let Some(opts) = opts {
$(for arg in args join ($['\r']) => $arg)
}
}; };
Some(required_args) Some(required_args)
@@ -226,20 +122,6 @@ fn render_optional_args(_funcs: &CommonFunctions, field: &FullTypeFields) -> Opt
} }
} }
fn render_output_type(funcs: &CommonFunctions, type_ref: &TypeRef) -> rust::Tokens {
let output_type = funcs.format_output_type(type_ref);
if type_ref_is_object(type_ref) || type_ref_is_list_of_objects(type_ref) {
return quote! {
$(output_type)
};
}
quote! {
eyre::Result<$output_type>
}
}
fn render_execution(funcs: &CommonFunctions, field: &FullTypeFields) -> rust::Tokens { fn render_execution(funcs: &CommonFunctions, field: &FullTypeFields) -> rust::Tokens {
if let Some(true) = field.type_.pipe(|t| type_ref_is_object(&t.type_ref)) { if let Some(true) = field.type_.pipe(|t| type_ref_is_object(&t.type_ref)) {
let output_type = funcs.format_output_type(&field.type_.as_ref().unwrap().type_ref); let output_type = funcs.format_output_type(&field.type_.as_ref().unwrap().type_ref);
@@ -281,16 +163,11 @@ fn render_execution(funcs: &CommonFunctions, field: &FullTypeFields) -> rust::To
let graphql_client = rust::import("crate::client", "graphql_client"); let graphql_client = rust::import("crate::client", "graphql_client");
quote! { quote! {
query.execute(&$graphql_client(&self.conn)).await query.execute(&$graphql_client(&self.conn)).unwrap().unwrap()
} }
} }
fn format_function_args( fn format_function_args(funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> {
funcs: &CommonFunctions,
field: &FullTypeFields,
lifecycle: Option<&rust::Tokens>,
) -> Option<(rust::Tokens, rust::Tokens, bool)> {
let mut argument_description = Vec::new();
if let Some(args) = field.args.as_ref() { if let Some(args) = field.args.as_ref() {
let args = args let args = args
.into_iter() .into_iter()
@@ -303,18 +180,6 @@ fn format_function_args(
let t = funcs.format_input_type(&s.input_value.type_); let t = funcs.format_input_type(&s.input_value.type_);
let n = format_struct_name(&s.input_value.name); let n = format_struct_name(&s.input_value.name);
if let Some(desc) = s.input_value.description.as_ref().and_then(|d| {
if d != "" {
Some(write_comment_line(&format!("* `{n}` - {}", d)))
} else {
None
}
}) {
argument_description.push(quote! {
$(desc)
});
}
Some(quote! { Some(quote! {
$(n): $(t), $(n): $(t),
}) })
@@ -328,120 +193,14 @@ fn format_function_args(
}; };
if type_field_has_optional(field) { if type_field_has_optional(field) {
let field_name = field_options_struct_name(field); Some(quote! {
argument_description.push(quote! { $(required_args)
$(field_name.pipe(|_| write_comment_line(&format!("* `opt` - optional argument, see inner type for documentation, use <func>_opts to use")))) opts: Option<$(field_options_struct_name(field))>
}); })
let description = quote! {
$(if argument_description.len() > 0 => $(format!("/// ")))
$(if argument_description.len() > 0 => $(format!("/// # Arguments")))
$(if argument_description.len() > 0 => $(format!("/// ")))
$(for arg_desc in argument_description join ($['\r']) => $arg_desc)
};
Some((
quote! {
$(required_args)
opts: $(field_name)$(lifecycle)
},
description,
true,
))
} else { } else {
let description = quote! { Some(required_args)
$(if argument_description.len() > 0 => $(format!("/// ")))
$(if argument_description.len() > 0 => $(format!("/// # Arguments")))
$(if argument_description.len() > 0 => $(format!("/// ")))
$(for arg_desc in argument_description join ($['\r']) => $arg_desc)
};
Some((required_args, description, false))
} }
} else { } else {
None None
} }
} }
fn format_required_function_args(
funcs: &CommonFunctions,
field: &FullTypeFields,
) -> Option<rust::Tokens> {
if let Some(args) = field.args.as_ref() {
let args = args
.into_iter()
.map(|a| {
a.as_ref().and_then(|s| {
if type_ref_is_optional(&s.input_value.type_) {
return None;
}
let t = funcs.format_input_type(&s.input_value.type_);
let n = format_struct_name(&s.input_value.name);
Some(quote! {
$(n): $(t),
})
})
})
.flatten()
.collect::<Vec<_>>();
let required_args = quote! {
&self,
$(for arg in args join ($['\r']) => $arg)
};
Some(required_args)
} else {
None
}
}
pub fn format_optional_args(
funcs: &CommonFunctions,
field: &FullTypeFields,
) -> Option<(rust::Tokens, bool)> {
field
.args
.pipe(|t| t.into_iter().flatten().collect::<Vec<_>>())
.map(|t| {
t.into_iter()
.filter(|t| type_ref_is_optional(&t.input_value.type_))
.sorted_by_key(|val| &val.input_value.name)
.collect::<Vec<_>>()
})
.pipe(|t| render_optional_field_args(funcs, t))
.flatten()
}
pub fn write_comment_line(content: &str) -> Option<rust::Tokens> {
let cnt = content.trim();
if cnt == "" {
return None;
}
let mut tokens = rust::Tokens::new();
for line in content.split('\n') {
tokens.append(format!("/// {}", line.trim()));
tokens.push();
}
Some(tokens)
}
pub fn format_struct_comment(desc: &str) -> Option<rust::Tokens> {
let lines = desc.trim().split("\n");
let formatted_lines = lines
.into_iter()
.map(write_comment_line)
.collect::<Vec<_>>();
if formatted_lines.len() > 0 {
Some(quote! {
$(for line in formatted_lines join($['\r']) => $line)
})
} else {
None
}
}

View File

@@ -1,7 +1,6 @@
use dagger_core::introspection::FullType; use dagger_core::introspection::FullType;
use genco::prelude::rust; use genco::prelude::rust;
use genco::quote; use genco::quote;
use itertools::Itertools;
fn render_enum_values(values: &FullType) -> Option<rust::Tokens> { fn render_enum_values(values: &FullType) -> Option<rust::Tokens> {
let values = values let values = values
@@ -11,7 +10,6 @@ fn render_enum_values(values: &FullType) -> Option<rust::Tokens> {
.map(|values| { .map(|values| {
values values
.into_iter() .into_iter()
.sorted_by_key(|a| &a.name)
.map(|val| quote! { $(val.name.as_ref()), }) .map(|val| quote! { $(val.name.as_ref()), })
}) })
.flatten() .flatten()
@@ -28,10 +26,9 @@ fn render_enum_values(values: &FullType) -> Option<rust::Tokens> {
pub fn render_enum(t: &FullType) -> eyre::Result<rust::Tokens> { pub fn render_enum(t: &FullType) -> eyre::Result<rust::Tokens> {
let serialize = rust::import("serde", "Serialize"); let serialize = rust::import("serde", "Serialize");
let deserialize = rust::import("serde", "Deserialize");
Ok(quote! { Ok(quote! {
#[derive($serialize, $deserialize, Clone, PartialEq, Debug)] #[derive($serialize)]
pub enum $(t.name.as_ref()) { pub enum $(t.name.as_ref()) {
$(render_enum_values(t)) $(render_enum_values(t))
} }

View File

@@ -1,7 +1,6 @@
use dagger_core::introspection::{FullType, FullTypeInputFields}; use dagger_core::introspection::{FullType, FullTypeInputFields};
use genco::prelude::rust; use genco::prelude::rust;
use genco::quote; use genco::quote;
use itertools::Itertools;
use crate::functions::CommonFunctions; use crate::functions::CommonFunctions;
use crate::rust::functions::{format_name, format_struct_name}; use crate::rust::functions::{format_name, format_struct_name};
@@ -10,7 +9,7 @@ pub fn render_input(funcs: &CommonFunctions, t: &FullType) -> eyre::Result<rust:
let deserialize = rust::import("serde", "Deserialize"); let deserialize = rust::import("serde", "Deserialize");
let serialize = rust::import("serde", "Serialize"); let serialize = rust::import("serde", "Serialize");
Ok(quote! { Ok(quote! {
#[derive($serialize, $deserialize, Debug, PartialEq, Clone)] #[derive($serialize, $deserialize)]
pub struct $(format_name(t.name.as_ref().unwrap())) { pub struct $(format_name(t.name.as_ref().unwrap())) {
$(render_input_fields(funcs, t.input_fields.as_ref().unwrap_or(&Vec::new()) )) $(render_input_fields(funcs, t.input_fields.as_ref().unwrap_or(&Vec::new()) ))
} }
@@ -21,10 +20,7 @@ pub fn render_input_fields(
funcs: &CommonFunctions, funcs: &CommonFunctions,
fields: &[FullTypeInputFields], fields: &[FullTypeInputFields],
) -> Option<rust::Tokens> { ) -> Option<rust::Tokens> {
let rendered_fields = fields let rendered_fields = fields.iter().map(|f| render_input_field(funcs, f));
.iter()
.sorted_by_key(|val| &val.input_value.name)
.map(|f| render_input_field(funcs, f));
if rendered_fields.len() == 0 { if rendered_fields.len() == 0 {
None None
@@ -37,6 +33,6 @@ pub fn render_input_fields(
pub fn render_input_field(funcs: &CommonFunctions, field: &FullTypeInputFields) -> rust::Tokens { pub fn render_input_field(funcs: &CommonFunctions, field: &FullTypeInputFields) -> rust::Tokens {
quote! { quote! {
pub $(format_struct_name(&field.input_value.name)): $(funcs.format_output_type(&field.input_value.type_)), pub $(format_struct_name(&field.input_value.name)): $(funcs.format_input_type(&field.input_value.type_)),
} }
} }

View File

@@ -2,21 +2,19 @@ use dagger_core::introspection::{FullType, FullTypeFields, FullTypeFieldsArgs};
use genco::prelude::rust; use genco::prelude::rust;
use genco::quote; use genco::quote;
use crate::functions::CommonFunctions; use crate::functions::{type_ref_is_optional, CommonFunctions};
use crate::rust::functions::{ use crate::rust::functions::{
field_options_struct_name, format_function, format_name, format_optional_args, field_options_struct_name, format_function, format_name, format_struct_name,
format_struct_comment, format_struct_name,
}; };
use crate::utility::OptionExt; use crate::utility::OptionExt;
pub fn render_object(funcs: &CommonFunctions, t: &FullType) -> eyre::Result<rust::Tokens> { pub fn render_object(funcs: &CommonFunctions, t: &FullType) -> eyre::Result<rust::Tokens> {
let selection = rust::import("crate::querybuilder", "Selection"); let selection = rust::import("crate::querybuilder", "Selection");
let child = rust::import("tokio::process", "Child"); let child = rust::import("std::process", "Child");
let conn = rust::import("dagger_core::connect_params", "ConnectParams"); let conn = rust::import("dagger_core::connect_params", "ConnectParams");
let arc = rust::import("std::sync", "Arc"); let arc = rust::import("std::sync", "Arc");
Ok(quote! { Ok(quote! {
#[derive(Debug, Clone)]
pub struct $(t.name.pipe(|s| format_name(s))) { pub struct $(t.name.pipe(|s| format_name(s))) {
pub proc: $arc<$child>, pub proc: $arc<$child>,
pub selection: $selection, pub selection: $selection,
@@ -52,17 +50,20 @@ fn render_optional_args(
fn render_optional_arg(funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> { fn render_optional_arg(funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> {
let output_type = field_options_struct_name(field); let output_type = field_options_struct_name(field);
let fields = format_optional_args(funcs, field); let fields = field
.args
.pipe(|t| t.into_iter().flatten().collect::<Vec<_>>())
.map(|t| {
t.into_iter()
.filter(|t| type_ref_is_optional(&t.input_value.type_))
.collect::<Vec<_>>()
})
.pipe(|t| render_optional_field_args(funcs, t))
.flatten();
let builder = rust::import("derive_builder", "Builder"); if let Some(fields) = fields {
let _phantom_data = rust::import("std::marker", "PhantomData");
if let Some((fields, contains_lifetime)) = fields {
Some(quote! { Some(quote! {
#[derive($builder, Debug, PartialEq)] pub struct $output_type {
pub struct $output_type$(if contains_lifetime => <'a>) {
//#[builder(default, setter(skip))]
//pub marker: $(phantom_data)<&'a ()>,
$fields $fields
} }
}) })
@@ -71,32 +72,22 @@ fn render_optional_arg(funcs: &CommonFunctions, field: &FullTypeFields) -> Optio
} }
} }
pub fn render_optional_field_args( fn render_optional_field_args(
funcs: &CommonFunctions, funcs: &CommonFunctions,
args: &Vec<&FullTypeFieldsArgs>, args: &Vec<&FullTypeFieldsArgs>,
) -> Option<(rust::Tokens, bool)> { ) -> Option<rust::Tokens> {
if args.len() == 0 { if args.len() == 0 {
return None; return None;
} }
let mut contains_lifetime = false;
let rendered_args = args.into_iter().map(|a| &a.input_value).map(|a| { let rendered_args = args.into_iter().map(|a| &a.input_value).map(|a| {
let type_ = funcs.format_immutable_input_type(&a.type_);
if type_.contains("str") {
contains_lifetime = true;
}
quote! { quote! {
$(a.description.pipe(|d| format_struct_comment(d))) pub $(format_struct_name(&a.name)): Option<$(funcs.format_output_type(&a.type_))>,
#[builder(setter(into, strip_option), default)]
pub $(format_struct_name(&a.name)): Option<$(type_)>,
} }
}); });
Some(( Some(quote! {
quote! { $(for arg in rendered_args join ($['\r']) => $arg)
$(for arg in rendered_args join ($['\r']) => $arg) })
},
contains_lifetime,
))
} }
fn render_functions(funcs: &CommonFunctions, fields: &Vec<FullTypeFields>) -> Option<rust::Tokens> { fn render_functions(funcs: &CommonFunctions, fields: &Vec<FullTypeFields>) -> Option<rust::Tokens> {

View File

@@ -10,19 +10,7 @@ pub fn render_scalar(t: &FullType) -> eyre::Result<rust::Tokens> {
let serialize = rust::import("serde", "Serialize"); let serialize = rust::import("serde", "Serialize");
Ok(quote! { Ok(quote! {
#[derive($serialize, $deserialize, PartialEq, Debug, Clone)] #[derive($serialize, $deserialize)]
pub struct $(t.name.pipe(|n|format_name(n)))(pub String); pub struct $(t.name.pipe(|n|format_name(n)))(String);
impl Into<$(t.name.pipe(|n| format_name(n)))> for &str {
fn into(self) -> $(t.name.pipe(|n| format_name(n))) {
$(t.name.pipe(|n| format_name(n)))(self.to_string())
}
}
impl Into<$(t.name.pipe(|n| format_name(n)))> for String {
fn into(self) -> $(t.name.pipe(|n| format_name(n))) {
$(t.name.pipe(|n| format_name(n)))(self.clone())
}
}
}) })
} }

View File

@@ -5,179 +5,6 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## v0.2.8 (2023-03-10)
### New Features
- <csr-id-41b20b6268db9d8defe333694e4d3ec019d7c923/> bump version
- <csr-id-5f9b3a19c0ab6988bc335b020052074f3f101305/> set internal warnings as errors
- <csr-id-f9e7af931d94fbedacf74f5da9a2f71b1992324b/> introduce tests again
### Bug Fixes
- <csr-id-ecca036bc644fee93fbcb69bf6da9f29169e473e/> fix builder pattern to actually work with default values
In previous versions the builder pattern required all values to be set.
This has not been fixed, so that default values are allowed.
### Commit Statistics
<csr-read-only-do-not-edit/>
- 4 commits contributed to the release over the course of 13 calendar days.
- 13 days passed between releases.
- 4 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- bump version ([`41b20b6`](https://github.com/kjuulh/dagger-rs/commit/41b20b6268db9d8defe333694e4d3ec019d7c923))
- set internal warnings as errors ([`5f9b3a1`](https://github.com/kjuulh/dagger-rs/commit/5f9b3a19c0ab6988bc335b020052074f3f101305))
- introduce tests again ([`f9e7af9`](https://github.com/kjuulh/dagger-rs/commit/f9e7af931d94fbedacf74f5da9a2f71b1992324b))
- fix builder pattern to actually work with default values ([`ecca036`](https://github.com/kjuulh/dagger-rs/commit/ecca036bc644fee93fbcb69bf6da9f29169e473e))
</details>
## v0.2.7 (2023-02-24)
### New Features
- <csr-id-3e8ca8d86eafdc1f9d5e8b69f14fb60509549e0f/> update to dagger-v0.3.13
### Commit Statistics
<csr-read-only-do-not-edit/>
- 2 commits contributed to the release.
- 4 days passed between releases.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-core v0.2.7, dagger-sdk v0.2.15 ([`6a9a560`](https://github.com/kjuulh/dagger-rs/commit/6a9a560cdca097abf23371d44599a2f1b726ae7f))
- update to dagger-v0.3.13 ([`3e8ca8d`](https://github.com/kjuulh/dagger-rs/commit/3e8ca8d86eafdc1f9d5e8b69f14fb60509549e0f))
</details>
## v0.2.6 (2023-02-20)
<csr-id-1f77d90c0f0ac832a181b2322350ea395612986c/>
### Chore
- <csr-id-1f77d90c0f0ac832a181b2322350ea395612986c/> ran clippy
### Bug Fixes
- <csr-id-8dfecf976c5537cc2c03881de2b2fd2b2508683a/> cli session keep session alive
### Commit Statistics
<csr-read-only-do-not-edit/>
- 3 commits contributed to the release.
- 2 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-core v0.2.6, dagger-codegen v0.2.7, dagger-sdk v0.2.12 ([`7179f8b`](https://github.com/kjuulh/dagger-rs/commit/7179f8b598ef04e62925e39d3f55740253c01686))
- ran clippy ([`1f77d90`](https://github.com/kjuulh/dagger-rs/commit/1f77d90c0f0ac832a181b2322350ea395612986c))
- cli session keep session alive ([`8dfecf9`](https://github.com/kjuulh/dagger-rs/commit/8dfecf976c5537cc2c03881de2b2fd2b2508683a))
</details>
## v0.2.5 (2023-02-20)
### Bug Fixes
- <csr-id-a13a2a9ecbfdfac80ed8eb0cbb9e9db317da65de/> race condition in process
### Commit Statistics
<csr-read-only-do-not-edit/>
- 2 commits contributed to the release.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-core v0.2.5, dagger-sdk v0.2.12, dagger-codegen v0.2.7 ([`1725c51`](https://github.com/kjuulh/dagger-rs/commit/1725c5188e8a81069ec4a4de569484c921a94927))
- race condition in process ([`a13a2a9`](https://github.com/kjuulh/dagger-rs/commit/a13a2a9ecbfdfac80ed8eb0cbb9e9db317da65de))
</details>
## v0.2.4 (2023-02-20)
### Bug Fixes
- <csr-id-8385aa8a15ff7b45fecc3462c482b998118c14eb/> remove blocking
- <csr-id-921e61b5e248013cb5fbf4f1bad3eef5a2673145/> remove blocking
### Commit Statistics
<csr-read-only-do-not-edit/>
- 4 commits contributed to the release.
- 2 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-core v0.2.4, dagger-codegen v0.2.6, dagger-sdk v0.2.11 ([`f869e57`](https://github.com/kjuulh/dagger-rs/commit/f869e574dd788cd60e5b1b5d502bec68e300694c))
- remove blocking ([`921e61b`](https://github.com/kjuulh/dagger-rs/commit/921e61b5e248013cb5fbf4f1bad3eef5a2673145))
- Release dagger-core v0.2.4, dagger-codegen v0.2.6, dagger-sdk v0.2.11 ([`17ec62a`](https://github.com/kjuulh/dagger-rs/commit/17ec62a5d58232ff57391523b9851fb7b07d02ab))
- remove blocking ([`8385aa8`](https://github.com/kjuulh/dagger-rs/commit/8385aa8a15ff7b45fecc3462c482b998118c14eb))
</details>
## v0.2.3 (2023-02-20)
### Bug Fixes
- <csr-id-75bc17e57db222492c6ffd2dfe80208d2bda75c9/> Fix async panic on blocking #19
Replaced internal threads with tokio spawn functions
### Commit Statistics
<csr-read-only-do-not-edit/>
- 2 commits contributed to the release.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-core v0.2.3, dagger-sdk v0.2.9, dagger-rs v0.2.10 ([`82de43a`](https://github.com/kjuulh/dagger-rs/commit/82de43aa91d6a5e09a247d1959137fdc36a40d35))
- Fix async panic on blocking #19 ([`75bc17e`](https://github.com/kjuulh/dagger-rs/commit/75bc17e57db222492c6ffd2dfe80208d2bda75c9))
</details>
## v0.2.2 (2023-02-19) ## v0.2.2 (2023-02-19)
### New Features ### New Features
@@ -188,7 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
<csr-read-only-do-not-edit/> <csr-read-only-do-not-edit/>
- 2 commits contributed to the release. - 1 commit contributed to the release.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org). - 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages - 0 issues like '(#ID)' were seen in commit messages
@@ -199,7 +26,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
<details><summary>view details</summary> <details><summary>view details</summary>
* **Uncategorized** * **Uncategorized**
- Release dagger-core v0.2.2, dagger-codegen v0.2.2, dagger-rs v0.2.8 ([`1638f15`](https://github.com/kjuulh/dagger-rs/commit/1638f15fba9d16512e8452f87b908d6dce417cd9))
- update to dagger v0.3.12 ([`6e5f407`](https://github.com/kjuulh/dagger-rs/commit/6e5f4074329ab0462445b31d4153f8497c483438)) - update to dagger v0.3.12 ([`6e5f407`](https://github.com/kjuulh/dagger-rs/commit/6e5f4074329ab0462445b31d4153f8497c483438))
</details> </details>

View File

@@ -1,30 +1,31 @@
[package] [package]
name = "dagger-core" name = "dagger-core"
version = "0.2.8" version = "0.2.2"
edition = "2021" edition = "2021"
readme = "README.md" readme = "README.md"
license-file = "LICENSE.MIT" license-file = "LICENSE.MIT"
description = "dagger sdk core library" description = "dagger sdk core library"
repository = "https://github.com/kjuulh/dagger-sdk" repository = "https://github.com/kjuulh/dagger-rs"
publish = true publish = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
eyre = { workspace = true } clap = "4.1.6"
serde = { workspace = true }
serde_json = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }
tracing-subscriber = { workspace = true }
dirs = "4.0.0" dirs = "4.0.0"
eyre = "0.6.8"
flate2 = { version = "1.0.25", features = ["zlib"] } flate2 = { version = "1.0.25", features = ["zlib"] }
genco = "0.17.3"
graphql-introspection-query = "0.2.0" graphql-introspection-query = "0.2.0"
graphql_client = { version = "0.12.0", features = ["reqwest"] } graphql_client = { version = "0.12.0", features = [
"reqwest",
"reqwest-blocking",
] }
hex = "0.4.3" hex = "0.4.3"
hex-literal = "0.3.4" hex-literal = "0.3.4"
platform-info = "1.0.2" platform-info = "1.0.2"
reqwest = { version = "0.11.14", features = ["stream", "deflate"] } reqwest = { version = "0.11.14", features = ["stream", "blocking", "deflate"] }
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.93"
sha2 = "0.10.6" sha2 = "0.10.6"
tar = "0.4.38" tar = "0.4.38"
tempfile = "3.3.0" tempfile = "3.3.0"

View File

@@ -1,6 +1,10 @@
use std::{fs::canonicalize, path::PathBuf, process::Stdio, sync::Arc}; use std::{
fs::canonicalize,
use tokio::io::AsyncBufReadExt; io::{BufRead, BufReader},
path::PathBuf,
process::{Child, Stdio},
sync::{mpsc::sync_channel, Arc},
};
use crate::{config::Config, connect_params::ConnectParams}; use crate::{config::Config, connect_params::ConnectParams};
@@ -16,12 +20,12 @@ impl CliSession {
} }
} }
pub async fn connect( pub fn connect(
&self, &self,
config: &Config, config: &Config,
cli_path: &PathBuf, cli_path: &PathBuf,
) -> eyre::Result<(ConnectParams, tokio::process::Child)> { ) -> eyre::Result<(ConnectParams, Child)> {
self.inner.connect(config, cli_path).await self.inner.connect(config, cli_path)
} }
} }
@@ -29,17 +33,17 @@ impl CliSession {
struct InnerCliSession {} struct InnerCliSession {}
impl InnerCliSession { impl InnerCliSession {
pub async fn connect( pub fn connect(
&self, &self,
config: &Config, config: &Config,
cli_path: &PathBuf, cli_path: &PathBuf,
) -> eyre::Result<(ConnectParams, tokio::process::Child)> { ) -> eyre::Result<(ConnectParams, Child)> {
let proc = self.start(config, cli_path)?; let proc = self.start(config, cli_path)?;
let params = self.get_conn(proc, config).await?; let params = self.get_conn(proc)?;
Ok(params) Ok(params)
} }
fn start(&self, config: &Config, cli_path: &PathBuf) -> eyre::Result<tokio::process::Child> { fn start(&self, config: &Config, cli_path: &PathBuf) -> eyre::Result<std::process::Child> {
let mut args: Vec<String> = vec!["session".into()]; let mut args: Vec<String> = vec!["session".into()];
if let Some(workspace) = &config.workdir_path { if let Some(workspace) = &config.workdir_path {
let abs_path = canonicalize(workspace)?; let abs_path = canonicalize(workspace)?;
@@ -50,7 +54,7 @@ impl InnerCliSession {
args.extend(["--project".into(), abs_path.to_string_lossy().to_string()]) args.extend(["--project".into(), abs_path.to_string_lossy().to_string()])
} }
let proc = tokio::process::Command::new( let proc = std::process::Command::new(
cli_path cli_path
.to_str() .to_str()
.ok_or(eyre::anyhow!("could not get string from path"))?, .ok_or(eyre::anyhow!("could not get string from path"))?,
@@ -66,11 +70,10 @@ impl InnerCliSession {
return Ok(proc); return Ok(proc);
} }
async fn get_conn( fn get_conn(
&self, &self,
mut proc: tokio::process::Child, mut proc: std::process::Child,
config: &Config, ) -> eyre::Result<(ConnectParams, std::process::Child)> {
) -> eyre::Result<(ConnectParams, tokio::process::Child)> {
let stdout = proc let stdout = proc
.stdout .stdout
.take() .take()
@@ -81,35 +84,32 @@ impl InnerCliSession {
.take() .take()
.ok_or(eyre::anyhow!("could not acquire stderr from child process"))?; .ok_or(eyre::anyhow!("could not acquire stderr from child process"))?;
let (sender, mut receiver) = tokio::sync::mpsc::channel(1); let (sender, receiver) = sync_channel(1);
let logger = config.logger.as_ref().map(|p| p.clone()); std::thread::spawn(move || {
tokio::spawn(async move { let stdout_bufr = BufReader::new(stdout);
let mut stdout_bufr = tokio::io::BufReader::new(stdout).lines(); for line in stdout_bufr.lines() {
while let Ok(Some(line)) = stdout_bufr.next_line().await { let out = line.as_ref().unwrap();
if let Ok(conn) = serde_json::from_str::<ConnectParams>(&line) { if let Ok(conn) = serde_json::from_str::<ConnectParams>(&out) {
sender.send(conn).await.unwrap(); sender.send(conn).unwrap();
} }
if let Ok(line) = line {
if let Some(logger) = &logger { println!("dagger: {}", line);
logger.stdout(&line).unwrap();
} }
} }
}); });
let logger = config.logger.as_ref().map(|p| p.clone()); std::thread::spawn(|| {
tokio::spawn(async move { let stderr_bufr = BufReader::new(stderr);
let mut stderr_bufr = tokio::io::BufReader::new(stderr).lines(); for line in stderr_bufr.lines() {
while let Ok(Some(line)) = stderr_bufr.next_line().await { if let Ok(line) = line {
if let Some(logger) = &logger { println!("dagger: {}", line);
logger.stdout(&line).unwrap();
} }
//panic!("could not start dagger session: {}", out)
} }
}); });
let conn = receiver.recv().await.ok_or(eyre::anyhow!( let conn = receiver.recv()?;
"could not receive ok signal from dagger-engine"
))?;
Ok((conn, proc)) Ok((conn, proc))
} }

View File

@@ -1,18 +1,15 @@
use std::path::PathBuf; use std::path::PathBuf;
use crate::logger::DynLogger;
pub struct Config { pub struct Config {
pub workdir_path: Option<PathBuf>, pub workdir_path: Option<PathBuf>,
pub config_path: Option<PathBuf>, pub config_path: Option<PathBuf>,
pub timeout_ms: u64, pub timeout_ms: u64,
pub execute_timeout_ms: Option<u64>, pub execute_timeout_ms: Option<u64>,
pub logger: Option<DynLogger>,
} }
impl Default for Config { impl Default for Config {
fn default() -> Self { fn default() -> Self {
Self::new(None, None, None, None, None) Self::new(None, None, None, None)
} }
} }
@@ -22,14 +19,12 @@ impl Config {
config_path: Option<PathBuf>, config_path: Option<PathBuf>,
timeout_ms: Option<u64>, timeout_ms: Option<u64>,
execute_timeout_ms: Option<u64>, execute_timeout_ms: Option<u64>,
logger: Option<DynLogger>,
) -> Self { ) -> Self {
Self { Self {
workdir_path, workdir_path,
config_path, config_path,
timeout_ms: timeout_ms.unwrap_or(10 * 1000), timeout_ms: timeout_ms.unwrap_or(10 * 1000),
execute_timeout_ms, execute_timeout_ms,
logger,
} }
} }
} }

View File

@@ -1,6 +1,6 @@
use std::{ use std::{
fs::File, fs::File,
io::{copy, Write}, io::{copy, Read, Write},
os::unix::prelude::PermissionsExt, os::unix::prelude::PermissionsExt,
path::PathBuf, path::PathBuf,
}; };
@@ -27,7 +27,6 @@ impl Platform {
let normalize_arch = match arch.as_str() { let normalize_arch = match arch.as_str() {
"x86_64" => "amd64", "x86_64" => "amd64",
"aarch" => "arm64", "aarch" => "arm64",
"aarch64" => "arm64",
arch => arch, arch => arch,
}; };
@@ -120,7 +119,7 @@ impl Downloader {
Ok(path) Ok(path)
} }
pub async fn get_cli(&self) -> eyre::Result<PathBuf> { pub fn get_cli(&self) -> eyre::Result<PathBuf> {
let version = &self.version; let version = &self.version;
let mut cli_bin_path = self.cache_dir()?; let mut cli_bin_path = self.cache_dir()?;
cli_bin_path.push(format!("{CLI_BIN_PREFIX}{version}")); cli_bin_path.push(format!("{CLI_BIN_PREFIX}{version}"));
@@ -131,7 +130,6 @@ impl Downloader {
if !cli_bin_path.exists() { if !cli_bin_path.exists() {
cli_bin_path = self cli_bin_path = self
.download(cli_bin_path) .download(cli_bin_path)
.await
.context("failed to download CLI from archive")?; .context("failed to download CLI from archive")?;
} }
@@ -139,11 +137,6 @@ impl Downloader {
if let Ok(entry) = file { if let Ok(entry) = file {
let path = entry.path(); let path = entry.path();
if path != cli_bin_path { if path != cli_bin_path {
tracing::debug!(
path = path.display().to_string(),
cli_bin_path = cli_bin_path.display().to_string(),
"deleting existing dagger-engine"
);
std::fs::remove_file(path)?; std::fs::remove_file(path)?;
} }
} }
@@ -152,11 +145,11 @@ impl Downloader {
Ok(cli_bin_path) Ok(cli_bin_path)
} }
async fn download(&self, path: PathBuf) -> eyre::Result<PathBuf> { fn download(&self, path: PathBuf) -> eyre::Result<PathBuf> {
let expected_checksum = self.expected_checksum().await?; let expected_checksum = self.expected_checksum()?;
let mut bytes = vec![]; let mut bytes = vec![];
let actual_hash = self.extract_cli_archive(&mut bytes).await?; let actual_hash = self.extract_cli_archive(&mut bytes)?;
if expected_checksum != actual_hash { if expected_checksum != actual_hash {
eyre::bail!("downloaded CLI binary checksum doesn't match checksum from checksums.txt") eyre::bail!("downloaded CLI binary checksum doesn't match checksum from checksums.txt")
@@ -172,15 +165,15 @@ impl Downloader {
Ok(path) Ok(path)
} }
async fn expected_checksum(&self) -> eyre::Result<String> { fn expected_checksum(&self) -> eyre::Result<String> {
let archive_url = &self.archive_url(); let archive_url = &self.archive_url();
let archive_path = PathBuf::from(&archive_url); let archive_path = PathBuf::from(&archive_url);
let archive_name = archive_path let archive_name = archive_path
.file_name() .file_name()
.ok_or(eyre::anyhow!("could not get file_name from archive_url"))?; .ok_or(eyre::anyhow!("could not get file_name from archive_url"))?;
let resp = reqwest::get(self.checksum_url()).await?; let resp = reqwest::blocking::get(self.checksum_url())?;
let resp = resp.error_for_status()?; let resp = resp.error_for_status()?;
for line in resp.text().await?.lines() { for line in resp.text()?.lines() {
let mut content = line.split_whitespace(); let mut content = line.split_whitespace();
let checksum = content let checksum = content
.next() .next()
@@ -197,20 +190,26 @@ impl Downloader {
eyre::bail!("could not find a matching version or binary in checksums.txt") eyre::bail!("could not find a matching version or binary in checksums.txt")
} }
pub async fn extract_cli_archive(&self, dest: &mut Vec<u8>) -> eyre::Result<String> { pub fn extract_cli_archive(&self, dest: &mut Vec<u8>) -> eyre::Result<String> {
let archive_url = self.archive_url(); let archive_url = self.archive_url();
let resp = reqwest::get(&archive_url).await?; let resp = reqwest::blocking::get(&archive_url)?;
let resp = resp.error_for_status()?; let mut resp = resp.error_for_status()?;
let bytes = resp.bytes().await?; let mut bytes = vec![];
let lines = resp.read_to_end(&mut bytes)?;
if lines == 0 {
eyre::bail!("nothing was downloaded")
}
let mut hasher = sha2::Sha256::new(); let mut hasher = sha2::Sha256::new();
hasher.update(&bytes); hasher.update(bytes.as_slice());
let res = hasher.finalize(); let res = hasher.finalize();
println!("{}", hex::encode(&res));
if archive_url.ends_with(".zip") { if archive_url.ends_with(".zip") {
// TODO: Nothing for now // TODO: Nothing for now
todo!() todo!()
} else { } else {
self.extract_from_tar(&bytes, dest)?; self.extract_from_tar(bytes.as_slice(), dest)?;
} }
Ok(hex::encode(res)) Ok(hex::encode(res))
@@ -224,6 +223,8 @@ impl Downloader {
let mut entry = entry?; let mut entry = entry?;
let path = entry.path()?; let path = entry.path()?;
println!("path: {:?}", path);
if path.ends_with("dagger") { if path.ends_with("dagger") {
copy(&mut entry, output)?; copy(&mut entry, output)?;
@@ -239,13 +240,9 @@ impl Downloader {
mod test { mod test {
use super::Downloader; use super::Downloader;
#[tokio::test] #[test]
async fn download() { fn download() {
let cli_path = Downloader::new("0.3.10".into()) let cli_path = Downloader::new("0.3.10".into()).unwrap().get_cli().unwrap();
.unwrap()
.get_cli()
.await
.unwrap();
assert_eq!( assert_eq!(
Some("dagger-0.3.10"), Some("dagger-0.3.10"),

View File

@@ -1,4 +1,5 @@
use crate::DAGGER_ENGINE_VERSION; use std::process::Child;
use crate::{ use crate::{
cli_session::CliSession, config::Config, connect_params::ConnectParams, downloader::Downloader, cli_session::CliSession, config::Config, connect_params::ConnectParams, downloader::Downloader,
}; };
@@ -10,23 +11,38 @@ impl Engine {
Self {} Self {}
} }
async fn from_cli(&self, cfg: &Config) -> eyre::Result<(ConnectParams, tokio::process::Child)> { fn from_cli(&self, cfg: &Config) -> eyre::Result<(ConnectParams, Child)> {
let cli = Downloader::new(DAGGER_ENGINE_VERSION.into())? let cli = Downloader::new("0.3.12".into())?.get_cli()?;
.get_cli()
.await?;
let cli_session = CliSession::new(); let cli_session = CliSession::new();
Ok(cli_session.connect(cfg, &cli).await?) Ok(cli_session.connect(cfg, &cli)?)
} }
pub async fn start( pub fn start(&self, cfg: &Config) -> eyre::Result<(ConnectParams, Child)> {
&self,
cfg: &Config,
) -> eyre::Result<(ConnectParams, tokio::process::Child)> {
tracing::info!("starting dagger-engine");
// TODO: Add from existing session as well // TODO: Add from existing session as well
self.from_cli(cfg).await self.from_cli(cfg)
}
}
#[cfg(test)]
mod tests {
use crate::{config::Config, connect_params::ConnectParams};
use super::Engine;
// TODO: these tests potentially have a race condition
#[test]
fn engine_can_start() {
let engine = Engine::new();
let params = engine.start(&Config::new(None, None, None, None)).unwrap();
assert_ne!(
params.0,
ConnectParams {
port: 123,
session_token: "123".into()
}
)
} }
} }

View File

@@ -241,7 +241,6 @@ pub struct SchemaTypes {
pub full_type: FullType, pub full_type: FullType,
} }
#[allow(dead_code)]
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct SchemaDirectivesArgs { pub struct SchemaDirectivesArgs {
@@ -258,7 +257,6 @@ pub struct SchemaDirectives {
pub args: Option<Vec<Option<SchemaDirectivesArgs>>>, pub args: Option<Vec<Option<SchemaDirectivesArgs>>>,
} }
#[allow(dead_code)]
#[derive(Clone, Debug, Deserialize)] #[derive(Clone, Debug, Deserialize)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Schema { pub struct Schema {

View File

@@ -1,14 +1,9 @@
#![deny(warnings)]
pub const DAGGER_ENGINE_VERSION: &'static str = "0.4.0";
pub mod cli_session; pub mod cli_session;
pub mod config; pub mod config;
pub mod connect_params; pub mod connect_params;
pub mod downloader; pub mod downloader;
pub mod engine; pub mod engine;
pub mod introspection; pub mod introspection;
pub mod logger;
pub mod schema; pub mod schema;
pub mod session; pub mod session;

View File

@@ -1,8 +0,0 @@
use std::sync::Arc;
pub trait Logger {
fn stdout(&self, output: &str) -> eyre::Result<()>;
fn stderr(&self, output: &str) -> eyre::Result<()>;
}
pub type DynLogger = Arc<dyn Logger + Send + Sync>;

View File

@@ -1,14 +1,24 @@
use crate::introspection::IntrospectionResponse; use crate::introspection::IntrospectionResponse;
use crate::{config::Config, engine::Engine, session::Session}; use crate::{config::Config, engine::Engine, session::Session};
pub async fn get_schema() -> eyre::Result<IntrospectionResponse> { pub fn get_schema() -> eyre::Result<IntrospectionResponse> {
let cfg = Config::default(); let cfg = Config::new(None, None, None, None);
//TODO: Implement context for proc //TODO: Implement context for proc
let (conn, _proc) = Engine::new().start(&cfg).await?; let (conn, _proc) = Engine::new().start(&cfg)?;
let session = Session::new(); let session = Session::new();
let req_builder = session.start(&cfg, &conn)?; let req_builder = session.start(&cfg, &conn)?;
let schema = session.schema(req_builder).await?; let schema = session.schema(req_builder)?;
Ok(schema) Ok(schema)
} }
#[cfg(test)]
mod tests {
use super::get_schema;
#[test]
fn can_get_schema() {
let _ = get_schema().unwrap();
}
}

View File

@@ -1,7 +1,7 @@
use graphql_client::GraphQLQuery; use graphql_client::GraphQLQuery;
use reqwest::{ use reqwest::{
blocking::{Client, RequestBuilder},
header::{HeaderMap, HeaderValue, ACCEPT, CONTENT_TYPE}, header::{HeaderMap, HeaderValue, ACCEPT, CONTENT_TYPE},
Client, RequestBuilder,
}; };
use crate::{config::Config, connect_params::ConnectParams, introspection::IntrospectionResponse}; use crate::{config::Config, connect_params::ConnectParams, introspection::IntrospectionResponse};
@@ -37,14 +37,14 @@ impl Session {
Ok(req_builder) Ok(req_builder)
} }
pub async fn schema(&self, req_builder: RequestBuilder) -> eyre::Result<IntrospectionResponse> { pub fn schema(&self, req_builder: RequestBuilder) -> eyre::Result<IntrospectionResponse> {
let request_body: graphql_client::QueryBody<()> = graphql_client::QueryBody { let request_body: graphql_client::QueryBody<()> = graphql_client::QueryBody {
variables: (), variables: (),
query: introspection_query::QUERY, query: introspection_query::QUERY,
operation_name: introspection_query::OPERATION_NAME, operation_name: introspection_query::OPERATION_NAME,
}; };
let res = req_builder.json(&request_body).send().await?; let res = req_builder.json(&request_body).send()?;
if res.status().is_success() { if res.status().is_success() {
// do nothing // do nothing
@@ -52,7 +52,7 @@ impl Session {
return Err(eyre::anyhow!("server error!")); return Err(eyre::anyhow!("server error!"));
} else { } else {
let status = res.status(); let status = res.status();
let error_message = match res.text().await { let error_message = match res.text() {
Ok(msg) => match serde_json::from_str::<serde_json::Value>(&msg) { Ok(msg) => match serde_json::from_str::<serde_json::Value>(&msg) {
Ok(json) => { Ok(json) => {
format!("HTTP {}\n{}", status, serde_json::to_string_pretty(&json)?) format!("HTTP {}\n{}", status, serde_json::to_string_pretty(&json)?)
@@ -64,7 +64,7 @@ impl Session {
return Err(eyre::anyhow!(error_message)); return Err(eyre::anyhow!(error_message));
} }
let json: IntrospectionResponse = res.json().await?; let json: IntrospectionResponse = res.json()?;
Ok(json) Ok(json)
} }

View File

@@ -3,595 +3,7 @@
All notable changes to this project will be documented in this file. All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## v0.2.19 (2023-03-14)
### Chore
- <csr-id-6629d2db4fbc7cdba9b2e4a241e4b0a2592cf384/> fix release version
### Bug Fixes
- <csr-id-8fd6bb983ef00b1aa2cf1ba3088028329033c38f/> serialization of enum args for graphql
### Commit Statistics
<csr-read-only-do-not-edit/>
- 2 commits contributed to the release.
- 2 commits were understood as [conventional](https://www.conventionalcommits.org).
- 1 unique issue was worked on: [#34](https://github.com/kjuulh/dagger-rs/issues/34)
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **[#34](https://github.com/kjuulh/dagger-rs/issues/34)**
- serialization of enum args for graphql ([`8fd6bb9`](https://github.com/kjuulh/dagger-rs/commit/8fd6bb983ef00b1aa2cf1ba3088028329033c38f))
* **Uncategorized**
- fix release version ([`6629d2d`](https://github.com/kjuulh/dagger-rs/commit/6629d2db4fbc7cdba9b2e4a241e4b0a2592cf384))
</details>
## v0.2.17 (2023-03-13)
<csr-id-f67928155f02076cbb41abd4010523879ff3caf1/>
<csr-id-2cc0231c5f29993081f0f7e15e44cac95a7d6086/>
<csr-id-9ba01396cb44ee02cf7a16008e3f0bdae9f78754/>
<csr-id-e9e35edb1cb67eee8cc033212aba3b1888def78f/>
### Bug Fixes
- <csr-id-1bfd084cd28e2b984c61de7f3f9a065cc41be007/> make sure tests have a command to execute
- <csr-id-5593fce2e16e0aa97a2e6843f15d3bb1121048f5/> remove unused imports
- <csr-id-c025d1742482d701946c292dcf104421d3cade8e/> add support for String as well
- <csr-id-d7317e5cf34ee84a7b092357f5fbb15cd2bae2e3/> add public tuple field and into func
- <csr-id-44fa0240f8197f49fdf942b5c3d89079b59195d1/> update rust crate futures to 0.3.27
### Other
- <csr-id-f67928155f02076cbb41abd4010523879ff3caf1/> initial issue
### Refactor
- <csr-id-2cc0231c5f29993081f0f7e15e44cac95a7d6086/> remove export and instead use exitcode
- <csr-id-9ba01396cb44ee02cf7a16008e3f0bdae9f78754/> move issues to actual tests and refactor
- <csr-id-e9e35edb1cb67eee8cc033212aba3b1888def78f/> move issues to another folder
### Commit Statistics
<csr-read-only-do-not-edit/>
- 10 commits contributed to the release over the course of 2 calendar days.
- 2 days passed between releases.
- 9 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-sdk v0.2.17 ([`a8e6dde`](https://github.com/kjuulh/dagger-rs/commit/a8e6dde615029d9a94d159ed84b5373121cd201f))
- make sure tests have a command to execute ([`1bfd084`](https://github.com/kjuulh/dagger-rs/commit/1bfd084cd28e2b984c61de7f3f9a065cc41be007))
- remove unused imports ([`5593fce`](https://github.com/kjuulh/dagger-rs/commit/5593fce2e16e0aa97a2e6843f15d3bb1121048f5))
- remove export and instead use exitcode ([`2cc0231`](https://github.com/kjuulh/dagger-rs/commit/2cc0231c5f29993081f0f7e15e44cac95a7d6086))
- move issues to actual tests and refactor ([`9ba0139`](https://github.com/kjuulh/dagger-rs/commit/9ba01396cb44ee02cf7a16008e3f0bdae9f78754))
- add support for String as well ([`c025d17`](https://github.com/kjuulh/dagger-rs/commit/c025d1742482d701946c292dcf104421d3cade8e))
- move issues to another folder ([`e9e35ed`](https://github.com/kjuulh/dagger-rs/commit/e9e35edb1cb67eee8cc033212aba3b1888def78f))
- add public tuple field and into func ([`d7317e5`](https://github.com/kjuulh/dagger-rs/commit/d7317e5cf34ee84a7b092357f5fbb15cd2bae2e3))
- initial issue ([`f679281`](https://github.com/kjuulh/dagger-rs/commit/f67928155f02076cbb41abd4010523879ff3caf1))
- update rust crate futures to 0.3.27 ([`44fa024`](https://github.com/kjuulh/dagger-rs/commit/44fa0240f8197f49fdf942b5c3d89079b59195d1))
</details>
## v0.2.16 (2023-03-10)
<csr-id-e642778d9028726dfb07217814e15ad1dd3b83f2/>
### Chore
- <csr-id-e642778d9028726dfb07217814e15ad1dd3b83f2/> fix tasks
### Documentation
- <csr-id-13b7805e7e6fcf47e0a1318adcc25b4ab773a3c9/> fix missing await in connect
### New Features
- <csr-id-7133bfae9508bc5977548e373c49342a1248d6e4/> with dagger-engine v.0.4.0
- <csr-id-4381af029521c2cbac9325278d261db79a994657/> add tests to sdk
- <csr-id-5f9b3a19c0ab6988bc335b020052074f3f101305/> set internal warnings as errors
### Bug Fixes
- <csr-id-ecca036bc644fee93fbcb69bf6da9f29169e473e/> fix builder pattern to actually work with default values
In previous versions the builder pattern required all values to be set.
This has not been fixed, so that default values are allowed.
### Commit Statistics
<csr-read-only-do-not-edit/>
- 7 commits contributed to the release over the course of 13 calendar days.
- 13 days passed between releases.
- 6 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-core v0.2.8, dagger-sdk v0.2.16 ([`f390eac`](https://github.com/kjuulh/dagger-rs/commit/f390eac29f1d041d18d2207a5aa0a8d993aab68c))
- fix tasks ([`e642778`](https://github.com/kjuulh/dagger-rs/commit/e642778d9028726dfb07217814e15ad1dd3b83f2))
- with dagger-engine v.0.4.0 ([`7133bfa`](https://github.com/kjuulh/dagger-rs/commit/7133bfae9508bc5977548e373c49342a1248d6e4))
- fix missing await in connect ([`13b7805`](https://github.com/kjuulh/dagger-rs/commit/13b7805e7e6fcf47e0a1318adcc25b4ab773a3c9))
- add tests to sdk ([`4381af0`](https://github.com/kjuulh/dagger-rs/commit/4381af029521c2cbac9325278d261db79a994657))
- set internal warnings as errors ([`5f9b3a1`](https://github.com/kjuulh/dagger-rs/commit/5f9b3a19c0ab6988bc335b020052074f3f101305))
- fix builder pattern to actually work with default values ([`ecca036`](https://github.com/kjuulh/dagger-rs/commit/ecca036bc644fee93fbcb69bf6da9f29169e473e))
</details>
## v0.2.15 (2023-02-24)
### New Features
- <csr-id-3e8ca8d86eafdc1f9d5e8b69f14fb60509549e0f/> update to dagger-v0.3.13
### Bug Fixes
- <csr-id-e578b0e371e13bc30ada793b7cd6ebe75ba83a07/> set deserialize on enums as well
### Commit Statistics
<csr-read-only-do-not-edit/>
- 3 commits contributed to the release.
- 2 days passed between releases.
- 2 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-core v0.2.7, dagger-sdk v0.2.15 ([`6a9a560`](https://github.com/kjuulh/dagger-rs/commit/6a9a560cdca097abf23371d44599a2f1b726ae7f))
- set deserialize on enums as well ([`e578b0e`](https://github.com/kjuulh/dagger-rs/commit/e578b0e371e13bc30ada793b7cd6ebe75ba83a07))
- update to dagger-v0.3.13 ([`3e8ca8d`](https://github.com/kjuulh/dagger-rs/commit/3e8ca8d86eafdc1f9d5e8b69f14fb60509549e0f))
</details>
## v0.2.14 (2023-02-22)
<csr-id-e331ca003546f4ebe00f33b65c3b45c6b0586514/>
### Chore
- <csr-id-e331ca003546f4ebe00f33b65c3b45c6b0586514/> fix whitespace
### Commit Statistics
<csr-read-only-do-not-edit/>
- 2 commits contributed to the release.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-sdk v0.2.14 ([`88b055c`](https://github.com/kjuulh/dagger-rs/commit/88b055cb47d3d474e2c37d8fa8259df5faad9da5))
- fix whitespace ([`e331ca0`](https://github.com/kjuulh/dagger-rs/commit/e331ca003546f4ebe00f33b65c3b45c6b0586514))
</details>
## v0.2.13 (2023-02-22)
<csr-id-7c3654d276bb5f66e692a210cb60cdf46b19e226/>
<csr-id-1f77d90c0f0ac832a181b2322350ea395612986c/>
### Chore
- <csr-id-7c3654d276bb5f66e692a210cb60cdf46b19e226/> ran clippy
- <csr-id-1f77d90c0f0ac832a181b2322350ea395612986c/> ran clippy
### New Features
- <csr-id-266ad32dff4c8957c7cdd291f9ef6f8a8c1d055c/> with clone
### Bug Fixes
- <csr-id-a13a2a9ecbfdfac80ed8eb0cbb9e9db317da65de/> race condition in process
### Commit Statistics
<csr-read-only-do-not-edit/>
- 7 commits contributed to the release over the course of 2 calendar days.
- 2 days passed between releases.
- 4 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-codegen v0.2.8, dagger-sdk v0.2.13 ([`456f483`](https://github.com/kjuulh/dagger-rs/commit/456f48389b5514d7f743a600a7732fb02dd87418))
- ran clippy ([`7c3654d`](https://github.com/kjuulh/dagger-rs/commit/7c3654d276bb5f66e692a210cb60cdf46b19e226))
- with clone ([`266ad32`](https://github.com/kjuulh/dagger-rs/commit/266ad32dff4c8957c7cdd291f9ef6f8a8c1d055c))
- Release dagger-core v0.2.6, dagger-codegen v0.2.7, dagger-sdk v0.2.12 ([`7179f8b`](https://github.com/kjuulh/dagger-rs/commit/7179f8b598ef04e62925e39d3f55740253c01686))
- ran clippy ([`1f77d90`](https://github.com/kjuulh/dagger-rs/commit/1f77d90c0f0ac832a181b2322350ea395612986c))
- Release dagger-core v0.2.5, dagger-sdk v0.2.12, dagger-codegen v0.2.7 ([`1725c51`](https://github.com/kjuulh/dagger-rs/commit/1725c5188e8a81069ec4a4de569484c921a94927))
- race condition in process ([`a13a2a9`](https://github.com/kjuulh/dagger-rs/commit/a13a2a9ecbfdfac80ed8eb0cbb9e9db317da65de))
</details>
## v0.2.12 (2023-02-20)
<csr-id-1f77d90c0f0ac832a181b2322350ea395612986c/>
### Chore
- <csr-id-1f77d90c0f0ac832a181b2322350ea395612986c/> ran clippy
### Bug Fixes
- <csr-id-a13a2a9ecbfdfac80ed8eb0cbb9e9db317da65de/> race condition in process
## v0.2.11 (2023-02-20)
<csr-id-803cfc4f8c4d72ab7d011be5523b3bfc6039de39/>
### Chore
- <csr-id-803cfc4f8c4d72ab7d011be5523b3bfc6039de39/> ran clippy
### Commit Statistics
<csr-read-only-do-not-edit/>
- 3 commits contributed to the release.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-core v0.2.4, dagger-codegen v0.2.6, dagger-sdk v0.2.11 ([`f869e57`](https://github.com/kjuulh/dagger-rs/commit/f869e574dd788cd60e5b1b5d502bec68e300694c))
- Release dagger-core v0.2.4, dagger-codegen v0.2.6, dagger-sdk v0.2.11 ([`17ec62a`](https://github.com/kjuulh/dagger-rs/commit/17ec62a5d58232ff57391523b9851fb7b07d02ab))
- ran clippy ([`803cfc4`](https://github.com/kjuulh/dagger-rs/commit/803cfc4f8c4d72ab7d011be5523b3bfc6039de39))
</details>
## v0.2.10 (2023-02-20)
Alignment release
### Bug Fixes
- <csr-id-b100285312df522218bfd4bc00bbf41b857a81bf/> changelog
### Commit Statistics
<csr-read-only-do-not-edit/>
- 8 commits contributed to the release.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-sdk v0.2.10 ([`5cb9729`](https://github.com/kjuulh/dagger-rs/commit/5cb97296b61677fb37e4bdb8519d30a484f93621))
- changelog ([`b100285`](https://github.com/kjuulh/dagger-rs/commit/b100285312df522218bfd4bc00bbf41b857a81bf))
- Adjusting changelogs prior to release of dagger-sdk v0.2.10 ([`8ed0647`](https://github.com/kjuulh/dagger-rs/commit/8ed06476e56f3290a419d2a67e7f25da575c63ad))
- update changelog ([`09aa658`](https://github.com/kjuulh/dagger-rs/commit/09aa658b6fb3c1e9a2de668c4a69bbe5be13202f))
- Adjusting changelogs prior to release of dagger-sdk v0.2.10 ([`b436f27`](https://github.com/kjuulh/dagger-rs/commit/b436f27a535f085bb8a4e66c7c4b3df461e74c21))
- Adjusting changelogs prior to release of dagger-sdk v0.2.10, dagger-rs v0.2.10 ([`577a293`](https://github.com/kjuulh/dagger-rs/commit/577a293c6777b9305a4f5fc7c3abee4aff4d74b5))
- Adjusting changelogs prior to release of dagger-sdk v0.2.10, dagger-rs v0.2.10 ([`76bb1fc`](https://github.com/kjuulh/dagger-rs/commit/76bb1fcedd03bd2d3b1e0f841f10325e4a85e108))
- Release dagger-rs v0.2.10 ([`dc3487b`](https://github.com/kjuulh/dagger-rs/commit/dc3487b840beb9543699f72d4282147e4ebc72f2))
</details>
## v0.2.10
([`577a293`](https://github.com/kjuulh/dagger-rs/commit/577a293c6777b9305a4f5fc7c3abee4aff4d74b5))
- Adjusting changelogs prior to release of dagger-sdk v0.2.10, dagger-rs
## v0.2.10
([`76bb1fc`](https://github.com/kjuulh/dagger-rs/commit/76bb1fcedd03bd2d3b1e0f841f10325e4a85e108))
- Release dagger-rs v0.2.10
([`dc3487b`](https://github.com/kjuulh/dagger-rs/commit/dc3487b840beb9543699f72d4282147e4ebc72f2))
</details>
## v0.2.10
([`577a293`](https://github.com/kjuulh/dagger-rs/commit/577a293c6777b9305a4f5fc7c3abee4aff4d74b5))
- Adjusting changelogs prior to release of dagger-sdk v0.2.10, dagger-rs
## v0.2.10
([`76bb1fc`](https://github.com/kjuulh/dagger-rs/commit/76bb1fcedd03bd2d3b1e0f841f10325e4a85e108))
- Release dagger-rs v0.2.10
([`dc3487b`](https://github.com/kjuulh/dagger-rs/commit/dc3487b840beb9543699f72d4282147e4ebc72f2))
</details>
## v0.2.9 (2023-02-20)
### Bug Fixes
- <csr-id-75bc17e57db222492c6ffd2dfe80208d2bda75c9/> Fix async panic on blocking
#19 Replaced internal threads with tokio spawn functions
### Commit Statistics
<csr-read-only-do-not-edit/>
- 2 commits contributed to the release.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-core v0.2.3, dagger-sdk v0.2.9, dagger-rs v0.2.10 ([`82de43a`](https://github.com/kjuulh/dagger-rs/commit/82de43aa91d6a5e09a247d1959137fdc36a40d35))
- Fix async panic on blocking #19 ([`75bc17e`](https://github.com/kjuulh/dagger-rs/commit/75bc17e57db222492c6ffd2dfe80208d2bda75c9))
</details>
## v0.2.8 (2023-02-19)
### New Features
- <csr-id-978ede68ae52f5b5150a2aa45b8d6e1fbbbee2f4/> add documentation strings
### Commit Statistics
<csr-read-only-do-not-edit/>
- 2 commits contributed to the release.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-sdk v0.2.8, dagger-codegen v0.2.5 ([`0499024`](https://github.com/kjuulh/dagger-rs/commit/04990247ba8e9d0555847f582fef14849dbedebf))
- add documentation strings ([`978ede6`](https://github.com/kjuulh/dagger-rs/commit/978ede68ae52f5b5150a2aa45b8d6e1fbbbee2f4))
</details>
## v0.2.7 (2023-02-19)
### Documentation
- <csr-id-93f40b356c48f14e910968516bed9487912095c1/> change to await syntax
### New Features
- <csr-id-9be6f435d9ea39f31a8906e55dbd3e8b1e5ec598/> Use async runtime instead
of blocking. Default to using async runtime instead of blocking. I.e.
```rust
fn main() -> eyre::Result<()> {
// ...
client.container().from("rust").publish("somewhere")?;
// ...
}
// to
async fn main() -> eyre::Result<()> {
// ...
client.container().from("rust").publish("somewhere").await?;
// ...
}
```
### Commit Statistics
<csr-read-only-do-not-edit/>
- 3 commits contributed to the release.
- 2 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-sdk v0.2.7 ([`a1887af`](https://github.com/kjuulh/dagger-rs/commit/a1887afc8b51f61491ba7f13c5e7a5b7619623c4))
- change to await syntax ([`93f40b3`](https://github.com/kjuulh/dagger-rs/commit/93f40b356c48f14e910968516bed9487912095c1))
- Use async runtime instead of blocking. ([`9be6f43`](https://github.com/kjuulh/dagger-rs/commit/9be6f435d9ea39f31a8906e55dbd3e8b1e5ec598))
</details>
## v0.2.6 (2023-02-19)
### Documentation
- <csr-id-04e70ce964b343e28b3dbd0c46d10ccda958ab8c/> fix readme
### Commit Statistics
<csr-read-only-do-not-edit/>
- 2 commits contributed to the release.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-sdk v0.2.6 ([`c312bc5`](https://github.com/kjuulh/dagger-rs/commit/c312bc57ad3e5380b6a2a927f3bb758aa5344efd))
- fix readme ([`04e70ce`](https://github.com/kjuulh/dagger-rs/commit/04e70ce964b343e28b3dbd0c46d10ccda958ab8c))
</details>
## v0.2.5 (2023-02-19)
### New Features
- <csr-id-f29ff836cfd72d5e051ca6a71a230ba1e9933091/> without Some in _opts
functions Option has been removed as a wrapper around opts. This makes it much
more convenient to use
```rust
client.container_opts(Some(ContainerOpts{}))
// ->
client.container_opts(ContainerOpts{})
```
The same options are still available, either an empty object can be passed, or
a non _opts function can be used
- <csr-id-9762da895a164e30c5dc60e89a83e934ceae47ab/> with _opts methods Now all
opt values enter into a _opts function instead of the original. This avoids a
lot of verbosity for both None in the case opts are unwanted, and Some() if
they actually are.
They are used like so:
```rust
client.container().from("...");
client.container_opts(Some(ContainerOpts{ ... }))
```
Some from opts will be removed in a future commit/pr
- <csr-id-94336d06378f035464e233b921dc3858070f582d/> move to &str instead of
String and introduce builder. This will make the api much easier to use, as we
can now rely on "" instead of "".into() for normal string values.
Introduced builder as well, which makes it much easier to use *Opts, as it can
handle the building of that, and get the benefits from String -> &str, as that
is currently not allowed for optional values
### Bug Fixes
- <csr-id-c627595fd2695e236924175d137c42f1480ccd6b/> cargo clippy
- <csr-id-02006d40fc2c0383e0412c15c36db9af7eda991f/> without phantom data
- <csr-id-6e2292cf11942fbd26a52fe4e0fc8471e6eb70a3/> dependencies
### Commit Statistics
<csr-read-only-do-not-edit/>
- 7 commits contributed to the release.
- 6 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-sdk v0.2.5, dagger-codegen v0.2.4 ([`f727318`](https://github.com/kjuulh/dagger-rs/commit/f72731807d8358fdb3d80432136b7a08bb7b1773))
- cargo clippy ([`c627595`](https://github.com/kjuulh/dagger-rs/commit/c627595fd2695e236924175d137c42f1480ccd6b))
- without Some in _opts functions ([`f29ff83`](https://github.com/kjuulh/dagger-rs/commit/f29ff836cfd72d5e051ca6a71a230ba1e9933091))
- with _opts methods ([`9762da8`](https://github.com/kjuulh/dagger-rs/commit/9762da895a164e30c5dc60e89a83e934ceae47ab))
- without phantom data ([`02006d4`](https://github.com/kjuulh/dagger-rs/commit/02006d40fc2c0383e0412c15c36db9af7eda991f))
- move to &str instead of String and introduce builder. ([`94336d0`](https://github.com/kjuulh/dagger-rs/commit/94336d06378f035464e233b921dc3858070f582d))
- dependencies ([`6e2292c`](https://github.com/kjuulh/dagger-rs/commit/6e2292cf11942fbd26a52fe4e0fc8471e6eb70a3))
</details>
## v0.2.4 (2023-02-19)
### Bug Fixes
- <csr-id-7d04ab1240e497e7804fed23a378d28c78f50a0a/> readme dagger-rs ->
dagger-sdk
### Commit Statistics
<csr-read-only-do-not-edit/>
- 2 commits contributed to the release.
- 1 commit was understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-sdk v0.2.4 ([`cc81124`](https://github.com/kjuulh/dagger-rs/commit/cc81124f899f44f80c1ee7d1e23a7e02d8cc4b7c))
- readme dagger-rs -> dagger-sdk ([`7d04ab1`](https://github.com/kjuulh/dagger-rs/commit/7d04ab1240e497e7804fed23a378d28c78f50a0a))
</details>
## v0.2.3 (2023-02-19)
### New Features
- <csr-id-19ed6c267f779b72430422c463ceed553f6fc618/> re-export through lib.rs
this means that you can now use dagger_sdk::connect() instead of
dagger_sdk::client::connect();
- <csr-id-de063eae858eb3335d2558a57ee6a88689635200/> with return result instead
of unwrap
- <csr-id-5d667369900a47d3a6015cd3814c240bc5c54436/> remove unnecessary option
returns
### Commit Statistics
<csr-read-only-do-not-edit/>
- 4 commits contributed to the release.
- 3 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages
### Commit Details
<csr-read-only-do-not-edit/>
<details><summary>view details</summary>
* **Uncategorized**
- Release dagger-sdk v0.2.3, dagger-codegen v0.2.3, dagger-rs v0.2.9 ([`9235030`](https://github.com/kjuulh/dagger-rs/commit/92350306b3f0da40b4fc6dcaffcd90b891e83f70))
- re-export through lib.rs ([`19ed6c2`](https://github.com/kjuulh/dagger-rs/commit/19ed6c267f779b72430422c463ceed553f6fc618))
- with return result instead of unwrap ([`de063ea`](https://github.com/kjuulh/dagger-rs/commit/de063eae858eb3335d2558a57ee6a88689635200))
- remove unnecessary option returns ([`5d66736`](https://github.com/kjuulh/dagger-rs/commit/5d667369900a47d3a6015cd3814c240bc5c54436))
</details>
## v0.2.2 (2023-02-19) ## v0.2.2 (2023-02-19)
@@ -607,7 +19,7 @@ Alignment release
<csr-read-only-do-not-edit/> <csr-read-only-do-not-edit/>
- 4 commits contributed to the release. - 3 commits contributed to the release.
- 2 commits were understood as [conventional](https://www.conventionalcommits.org). - 2 commits were understood as [conventional](https://www.conventionalcommits.org).
- 0 issues like '(#ID)' were seen in commit messages - 0 issues like '(#ID)' were seen in commit messages
@@ -618,7 +30,6 @@ Alignment release
<details><summary>view details</summary> <details><summary>view details</summary>
* **Uncategorized** * **Uncategorized**
- Release dagger-sdk v0.2.2 ([`e921ba1`](https://github.com/kjuulh/dagger-rs/commit/e921ba13638987ccf5beaa48c4be9be5fd879bd0))
- Release dagger-core v0.2.2, dagger-codegen v0.2.2, dagger-rs v0.2.8 ([`1638f15`](https://github.com/kjuulh/dagger-rs/commit/1638f15fba9d16512e8452f87b908d6dce417cd9)) - Release dagger-core v0.2.2, dagger-codegen v0.2.2, dagger-rs v0.2.8 ([`1638f15`](https://github.com/kjuulh/dagger-rs/commit/1638f15fba9d16512e8452f87b908d6dce417cd9))
- fixed fmt errors ([`10bc6f3`](https://github.com/kjuulh/dagger-rs/commit/10bc6f3846b65cc82c2fb343d8cfe921784bef1b)) - fixed fmt errors ([`10bc6f3`](https://github.com/kjuulh/dagger-rs/commit/10bc6f3846b65cc82c2fb343d8cfe921784bef1b))
- update to dagger v0.3.12 ([`6e5f407`](https://github.com/kjuulh/dagger-rs/commit/6e5f4074329ab0462445b31d4153f8497c483438)) - update to dagger v0.3.12 ([`6e5f407`](https://github.com/kjuulh/dagger-rs/commit/6e5f4074329ab0462445b31d4153f8497c483438))

View File

@@ -1,32 +1,27 @@
[package] [package]
name = "dagger-sdk" name = "dagger-sdk"
version = "0.2.19" version = "0.2.2"
edition = "2021" edition = "2021"
readme = "README.md" readme = "README.md"
license-file = "LICENSE.MIT" license-file = "LICENSE.MIT"
description = "A dagger sdk for rust, written in rust" description = "A dagger sdk for rust, written in rust"
repository = "https://github.com/kjuulh/dagger-sdk" repository = "https://github.com/kjuulh/dagger-rs"
publish = true publish = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
dagger-core = { workspace = true }
eyre = { workspace = true }
tokio = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tracing.workspace = true
tracing-subscriber.workspace = true
base64 = "0.21.0" base64 = "0.21.0"
futures = "0.3.27" dagger-core = { path = "../dagger-core", version = "^0.2.2" }
eyre = "0.6.8"
futures = "0.3.26"
genco = "0.17.3"
gql_client = "1.0.7" gql_client = "1.0.7"
derive_builder = "0.12.0" pretty_assertions = "1.3.0"
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.93"
tokio = { version = "1.25.0", features = ["full"] }
[dev-dependencies] [dev-dependencies]
pretty_assertions = "1.3.0"
rand = "0.8.5" rand = "0.8.5"
genco = "0.17.3"
tracing-test = "0.2.4"

View File

@@ -1,4 +1,4 @@
# dagger-sdk # dagger-rs
A dagger sdk written in rust for rust. A dagger sdk written in rust for rust.
@@ -19,21 +19,20 @@ The examples match the folder name in each directory in examples
Simply install like: Simply install like:
```bash ```bash
cargo add dagger-sdk cargo install dagger-sdk
``` ```
### Usage ### Usage
```rust ```rust
#[tokio::main] fn main() -> eyre::Result<()> {
async fn main() -> eyre::Result<()> { let client = dagger_sdk::client::connect()?;
let client = dagger_sdk::connect().await?;
let version = client let version = client
.container() .container(None)
.from("golang:1.19") .from("golang:1.19".into())
.with_exec(vec!["go", "version"]) .with_exec(vec!["go".into(), "version".into()], None)
.stdout().await?; .stdout();
println!("Hello from Dagger and {}", version.trim()); println!("Hello from Dagger and {}", version.trim());

View File

@@ -1,35 +1,42 @@
use dagger_sdk::HostDirectoryOpts; use dagger_sdk::gen::HostDirectoryOpts;
#[tokio::main] fn main() -> eyre::Result<()> {
async fn main() -> eyre::Result<()> { let client = dagger_sdk::client::connect()?;
let client = dagger_sdk::connect().await?;
let host_source_dir = client.host().directory_opts( let host_source_dir = client.host().directory(
"examples/build-the-application/app", "examples/build-the-application/app".into(),
HostDirectoryOpts { Some(HostDirectoryOpts {
exclude: Some(vec!["node_modules".into(), "ci/".into()]), exclude: Some(vec!["node_modules".into(), "ci/".into()]),
include: None, include: None,
}, }),
); );
let source = client let source = client
.container() .container(None)
.from("node:16") .from("node:16".into())
.with_mounted_directory("/src", host_source_dir.id().await?); .with_mounted_directory("/src".into(), host_source_dir.id());
let runner = source let runner = source
.with_workdir("/src") .with_workdir("/src".into())
.with_exec(vec!["npm", "install"]); .with_exec(vec!["npm".into(), "install".into()], None);
let test = runner.with_exec(vec!["npm", "test", "--", "--watchAll=false"]); let test = runner.with_exec(
vec![
"npm".into(),
"test".into(),
"--".into(),
"--watchAll=false".into(),
],
None,
);
let build_dir = test let build_dir = test
.with_exec(vec!["npm", "run", "build"]) .with_exec(vec!["npm".into(), "run".into(), "build".into()], None)
.directory("./build"); .directory("./build".into());
let _ = build_dir.export("./build"); let _ = build_dir.export("./build".into());
let entries = build_dir.entries().await; let entries = build_dir.entries(None);
println!("build dir contents: \n {:?}", entries); println!("build dir contents: \n {:?}", entries);

View File

@@ -1,42 +1,53 @@
use dagger_sdk::gen::HostDirectoryOpts;
use rand::Rng; use rand::Rng;
#[tokio::main] fn main() -> eyre::Result<()> {
async fn main() -> eyre::Result<()> { let client = dagger_sdk::client::connect()?;
let client = dagger_sdk::connect().await?;
let host_source_dir = client.host().directory_opts( let host_source_dir = client.host().directory(
"./examples/caching/app", "./examples/caching/app".into(),
dagger_sdk::HostDirectoryOptsBuilder::default() Some(HostDirectoryOpts {
.exclude(vec!["node_modules", "ci/"]) exclude: Some(vec!["node_modules".into(), "ci/".into()]),
.build()?, include: None,
}),
); );
let node_cache = client.cache_volume("node").id().await?; let node_cache = client.cache_volume("node".into()).id();
let source = client let source = client
.container() .container(None)
.from("node:16") .from("node:16".into())
.with_mounted_directory("/src", host_source_dir.id().await?) .with_mounted_directory("/src".into(), host_source_dir.id())
.with_mounted_cache("/src/node_modules", node_cache); .with_mounted_cache("/src/node_modules".into(), node_cache, None);
let runner = source let runner = source
.with_workdir("/src") .with_workdir("/src".into())
.with_exec(vec!["npm", "install"]); .with_exec(vec!["npm".into(), "install".into()], None);
let test = runner.with_exec(vec!["npm", "test", "--", "--watchAll=false"]); let test = runner.with_exec(
vec![
"npm".into(),
"test".into(),
"--".into(),
"--watchAll=false".into(),
],
None,
);
let build_dir = test let build_dir = test
.with_exec(vec!["npm", "run", "build"]) .with_exec(vec!["npm".into(), "run".into(), "build".into()], None)
.directory("./build"); .directory("./build".into());
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let ref_ = client let ref_ = client
.container() .container(None)
.from("nginx") .from("nginx".into())
.with_directory("/usr/share/nginx/html", build_dir.id().await?) .with_directory("/usr/share/nginx/html".into(), build_dir.id(), None)
.publish(format!("ttl.sh/hello-dagger-sdk-{}:1h", rng.gen::<u64>())) .publish(
.await?; format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::<u64>()),
None,
);
println!("published image to: {}", ref_); println!("published image to: {}", ref_);

View File

@@ -1,20 +1,22 @@
use rand::Rng; use rand::Rng;
#[tokio::main] fn main() -> eyre::Result<()> {
async fn main() -> eyre::Result<()> {
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let client = dagger_sdk::connect().await?; let client = dagger_sdk::client::connect()?;
let context_dir = client let context_dir = client
.host() .host()
.directory("./examples/existing-dockerfile/app"); .directory("./examples/existing-dockerfile/app".into(), None);
let ref_ = client let ref_ = client
.container() .container(None)
.build(context_dir.id().await?) .build(context_dir.id(), None)
.publish(format!("ttl.sh/hello-dagger-sdk-{}:1h", rng.gen::<u64>())) .publish(
.await?; format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::<u64>()),
None,
);
println!("published image to: {}", ref_); println!("published image to: {}", ref_);

View File

@@ -1,13 +1,11 @@
#[tokio::main] fn main() -> eyre::Result<()> {
async fn main() -> eyre::Result<()> { let client = dagger_sdk::client::connect()?;
let client = dagger_sdk::connect().await?;
let version = client let version = client
.container() .container(None)
.from("golang:1.19") .from("golang:1.19".into())
.with_exec(vec!["go", "version"]) .with_exec(vec!["go".into(), "version".into()], None)
.stdout() .stdout();
.await?;
println!("Hello from Dagger and {}", version.trim()); println!("Hello from Dagger and {}", version.trim());

View File

@@ -1,25 +0,0 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
build-*

View File

@@ -1,17 +0,0 @@
# React Build
This is based on the [Getting Started guide for Nodejs](https://docs.dagger.io/sdk/nodejs/783645/get-started#step-5-test-against-multiple-nodejs-versions)
A simple react app is created with `create-react-app` which is built and tested by `build.js` or `build.ts`.
Run:
`npm install`
and then:
`node --loader ts-node/esm ./build.ts`
or
`node ./build.js`

File diff suppressed because it is too large Load Diff

View File

@@ -1,48 +0,0 @@
{
"name": "react-build",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.6",
"@types/react": "^18.0.26",
"@types/react-dom": "^18.0.9",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"ts-node": "^10.9.1",
"typescript": "^4.9.3",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"type": "module",
"devDependencies": {
"@dagger.io/dagger": "^0.3.2"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

View File

@@ -1,43 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

View File

@@ -1,25 +0,0 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

View File

@@ -1,3 +0,0 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:

View File

@@ -1,38 +0,0 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

View File

@@ -1,9 +0,0 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

View File

@@ -1,26 +0,0 @@
import React from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.tsx</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
</header>
</div>
);
}
export default App;

View File

@@ -1,13 +0,0 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

View File

@@ -1,19 +0,0 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

View File

@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

View File

@@ -1 +0,0 @@
/// <reference types="react-scripts" />

View File

@@ -1,15 +0,0 @@
import { ReportHandler } from 'web-vitals';
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

View File

@@ -1,5 +0,0 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

View File

@@ -1,26 +0,0 @@
{
"compilerOptions": {
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": [
"src"
]
}

View File

@@ -1,49 +0,0 @@
use std::sync::Arc;
use dagger_sdk::logging::TracingLogger;
use dagger_sdk::HostDirectoryOpts;
#[tokio::main]
async fn main() -> eyre::Result<()> {
dagger_sdk::logging::default_logging()?;
let client = dagger_sdk::connect_opts(dagger_sdk::Config {
workdir_path: None,
config_path: None,
timeout_ms: 1000,
execute_timeout_ms: None,
logger: Some(Arc::new(TracingLogger::default())),
})
.await?;
let host_source_dir = client.host().directory_opts(
"examples/build-the-application/app",
HostDirectoryOpts {
exclude: Some(vec!["node_modules".into(), "ci/".into()]),
include: None,
},
);
let source = client
.container()
.from("node:16")
.with_mounted_directory("/src", host_source_dir.id().await?);
let runner = source
.with_workdir("/src")
.with_exec(vec!["npm", "install"]);
let test = runner.with_exec(vec!["npm", "test", "--", "--watchAll=false"]);
let build_dir = test
.with_exec(vec!["npm", "run", "build"])
.directory("./build");
let _ = build_dir.export("./build");
let entries = build_dir.entries().await;
println!("build dir contents: \n {:?}", entries);
Ok(())
}

View File

@@ -1,41 +1,50 @@
use dagger_sdk::HostDirectoryOpts; use dagger_sdk::gen::HostDirectoryOpts;
use rand::Rng; use rand::Rng;
#[tokio::main] fn main() -> eyre::Result<()> {
async fn main() -> eyre::Result<()> { let client = dagger_sdk::client::connect()?;
let client = dagger_sdk::connect().await?;
let host_source_dir = client.host().directory_opts( let host_source_dir = client.host().directory(
"examples/publish-the-application/app", "examples/publish-the-application/app".into(),
HostDirectoryOpts { Some(HostDirectoryOpts {
exclude: Some(vec!["node_modules", "ci/"]), exclude: Some(vec!["node_modules".into(), "ci/".into()]),
include: None, include: None,
}, }),
); );
let source = client let source = client
.container() .container(None)
.from("node:16") .from("node:16".into())
.with_mounted_directory("/src", host_source_dir.id().await?); .with_mounted_directory("/src".into(), host_source_dir.id());
let runner = source let runner = source
.with_workdir("/src") .with_workdir("/src".into())
.with_exec(vec!["npm", "install"]); .with_exec(vec!["npm".into(), "install".into()], None);
let test = runner.with_exec(vec!["npm", "test", "--", "--watchAll=false"]); let test = runner.with_exec(
vec![
"npm".into(),
"test".into(),
"--".into(),
"--watchAll=false".into(),
],
None,
);
let build_dir = test let build_dir = test
.with_exec(vec!["npm", "run", "build"]) .with_exec(vec!["npm".into(), "run".into(), "build".into()], None)
.directory("./build"); .directory("./build".into());
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let ref_ = client let ref_ = client
.container() .container(None)
.from("nginx") .from("nginx".into())
.with_directory("/usr/share/nginx/html", build_dir.id().await?) .with_directory("/usr/share/nginx/html".into(), build_dir.id(), None)
.publish(format!("ttl.sh/hello-dagger-sdk-{}:1h", rng.gen::<u64>())) .publish(
.await?; format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::<u64>()),
None,
);
println!("published image to: {}", ref_); println!("published image to: {}", ref_);

View File

@@ -1,46 +1,56 @@
use dagger_sdk::HostDirectoryOpts; use dagger_sdk::gen::HostDirectoryOpts;
use rand::Rng; use rand::Rng;
#[tokio::main] fn main() -> eyre::Result<()> {
async fn main() -> eyre::Result<()> { let client = dagger_sdk::client::connect()?;
let client = dagger_sdk::connect().await?;
let output = "examples/publish-the-application/app/build"; let output = "examples/publish-the-application/app/build";
let host_source_dir = client.host().directory_opts( let host_source_dir = client.host().directory(
"examples/publish-the-application/app", "examples/publish-the-application/app".into(),
HostDirectoryOpts { Some(HostDirectoryOpts {
exclude: Some(vec!["node_modules", "ci/"]), exclude: Some(vec!["node_modules".into(), "ci/".into()]),
include: None, include: None,
}, }),
); );
let source = client let source = client
.container() .container(None)
.from("node:16") .from("node:16".into())
.with_mounted_directory("/src", host_source_dir.id().await?); .with_mounted_directory("/src".into(), host_source_dir.id());
let runner = source let runner = source
.with_workdir("/src") .with_workdir("/src".into())
.with_exec(vec!["npm", "install"]); .with_exec(vec!["npm".into(), "install".into()], None);
let test = runner.with_exec(vec!["npm", "test", "--", "--watchAll=false"]); let test = runner.with_exec(
vec![
"npm".into(),
"test".into(),
"--".into(),
"--watchAll=false".into(),
],
None,
);
let _ = test let _ = test
.with_exec(vec!["npm", "run", "build"]) .with_exec(vec!["npm".into(), "run".into(), "build".into()], None)
.directory("./build") .directory("./build".into())
.export(output); .export(output.into());
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
let ref_ = client let ref_ = client
.container() .container(None)
.from("nginx") .from("nginx".into())
.with_directory( .with_directory(
"/usr/share/nginx/html", "/usr/share/nginx/html".into(),
client.host().directory(output).id().await?, client.host().directory(output.into(), None).id(),
None,
) )
.publish(format!("ttl.sh/hello-dagger-sdk-{}:1h", rng.gen::<u64>())) .publish(
.await?; format!("ttl.sh/hello-dagger-rs-{}:1h", rng.gen::<u64>()),
None,
);
println!("published image to: {}", ref_); println!("published image to: {}", ref_);

View File

@@ -1,30 +1,36 @@
use dagger_sdk::HostDirectoryOpts; use dagger_sdk::gen::HostDirectoryOpts;
#[tokio::main] fn main() -> eyre::Result<()> {
async fn main() -> eyre::Result<()> { let client = dagger_sdk::client::connect()?;
let client = dagger_sdk::connect().await?;
let host_source_dir = client.host().directory_opts( let host_source_dir = client.host().directory(
"examples/test-the-application/app", "examples/test-the-application/app".into(),
HostDirectoryOpts { Some(HostDirectoryOpts {
exclude: Some(vec!["node_modules", "ci/"]), exclude: Some(vec!["node_modules".into(), "ci/".into()]),
include: None, include: None,
}, }),
); );
let source = client let source = client
.container() .container(None)
.from("node:16") .from("node:16".into())
.with_mounted_directory("/src", host_source_dir.id().await?); .with_mounted_directory("/src".into(), host_source_dir.id());
let runner = source let runner = source
.with_workdir("/src") .with_workdir("/src".into())
.with_exec(vec!["npm", "install"]); .with_exec(vec!["npm".into(), "install".into()], None);
let out = runner let out = runner
.with_exec(vec!["npm", "test", "--", "--watchAll=false"]) .with_exec(
.stderr() vec![
.await?; "npm".into(),
"test".into(),
"--".into(),
"--watchAll=false".into(),
],
None,
)
.stderr();
println!("{}", out); println!("{}", out);

View File

@@ -3,26 +3,19 @@ use std::sync::Arc;
use base64::engine::general_purpose; use base64::engine::general_purpose;
use base64::Engine; use base64::Engine;
use gql_client::ClientConfig;
use dagger_core::config::Config; use dagger_core::config::Config;
use dagger_core::connect_params::ConnectParams; use dagger_core::connect_params::ConnectParams;
use dagger_core::engine::Engine as DaggerEngine; use dagger_core::engine::Engine as DaggerEngine;
use gql_client::ClientConfig;
use crate::gen::Query; use crate::gen::Query;
use crate::logging::StdLogger;
use crate::querybuilder::query; use crate::querybuilder::query;
pub type DaggerConn = Arc<Query>; pub type DaggerConn = Arc<Query>;
pub async fn connect() -> eyre::Result<DaggerConn> { pub fn connect() -> eyre::Result<DaggerConn> {
let cfg = Config::new(None, None, None, None, Some(Arc::new(StdLogger::default()))); let cfg = Config::default();
let (conn, proc) = DaggerEngine::new().start(&cfg)?;
connect_opts(cfg).await
}
pub async fn connect_opts(cfg: Config) -> eyre::Result<DaggerConn> {
let (conn, proc) = DaggerEngine::new().start(&cfg).await?;
Ok(Arc::new(Query { Ok(Arc::new(Query {
conn, conn,
@@ -51,8 +44,8 @@ pub fn graphql_client(conn: &ConnectParams) -> gql_client::Client {
mod test { mod test {
use super::connect; use super::connect;
#[tokio::test] #[test]
async fn test_connect() { fn test_connect() {
let _ = connect().await.unwrap(); let _ = connect().unwrap();
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +1,18 @@
#![deny(warnings)] pub mod client;
pub mod gen;
mod client;
mod gen;
pub mod logging;
mod querybuilder; mod querybuilder;
pub use client::*; pub fn add(left: usize, right: usize) -> usize {
pub use dagger_core::config::Config; left + right
pub use gen::*; }
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = add(2, 2);
assert_eq!(result, 4);
}
}

View File

@@ -1,81 +0,0 @@
use dagger_core::logger::{DynLogger, Logger};
use tracing::Level;
pub fn default_logging() -> eyre::Result<()> {
tracing_subscriber::fmt().with_max_level(Level::INFO).init();
Ok(())
}
pub struct StdLogger {}
impl Default for StdLogger {
fn default() -> Self {
Self {}
}
}
impl Logger for StdLogger {
fn stdout(&self, output: &str) -> eyre::Result<()> {
println!("{}", output);
Ok(())
}
fn stderr(&self, output: &str) -> eyre::Result<()> {
eprintln!("{}", output);
Ok(())
}
}
pub struct TracingLogger {}
impl Default for TracingLogger {
fn default() -> Self {
Self {}
}
}
impl Logger for TracingLogger {
fn stdout(&self, output: &str) -> eyre::Result<()> {
tracing::info!(output = output, "dagger-sdk");
Ok(())
}
fn stderr(&self, output: &str) -> eyre::Result<()> {
tracing::warn!(output = output, "dagger-sdk");
Ok(())
}
}
pub struct AggregateLogger {
pub loggers: Vec<DynLogger>,
}
impl Default for AggregateLogger {
fn default() -> Self {
Self {
loggers: Vec::new(),
}
}
}
impl Logger for AggregateLogger {
fn stdout(&self, output: &str) -> eyre::Result<()> {
for logger in &self.loggers {
logger.stdout(output).unwrap()
}
Ok(())
}
fn stderr(&self, output: &str) -> eyre::Result<()> {
for logger in &self.loggers {
logger.stderr(output).unwrap()
}
Ok(())
}
}

View File

@@ -46,13 +46,13 @@ impl Selection {
} }
} }
pub fn arg<S>(&self, name: &str, value: S) -> Selection pub fn arg<S>(&self, name: &str, value: S) -> eyre::Result<Selection>
where where
S: Serialize, S: Serialize,
{ {
let mut s = self.clone(); let mut s = self.clone();
let val = serde_json::to_string(&value).unwrap(); let val = serde_json::to_string(&value)?;
match s.args.as_mut() { match s.args.as_mut() {
Some(args) => { Some(args) => {
@@ -65,30 +65,7 @@ impl Selection {
} }
} }
s Ok(s)
}
pub fn arg_enum<S>(&self, name: &str, value: S) -> Selection
where
S: Serialize,
{
let mut s = self.clone();
let val = serde_json::to_string(&value).unwrap();
let val = val[1..val.len() - 1].to_string();
match s.args.as_mut() {
Some(args) => {
let _ = args.insert(name.to_string(), val);
}
None => {
let mut hm = HashMap::new();
let _ = hm.insert(name.to_string(), val);
s.args = Some(hm);
}
}
s
} }
pub fn build(&self) -> eyre::Result<String> { pub fn build(&self) -> eyre::Result<String> {
@@ -99,7 +76,7 @@ impl Selection {
if let Some(args) = sel.args { if let Some(args) = sel.args {
let actualargs = args let actualargs = args
.iter() .iter()
.map(|(name, arg)| format!("{name}:{}", arg.as_str())) .map(|(name, arg)| format!("{name}:{arg}"))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
query = query.add(&format!("({})", actualargs.join(", "))); query = query.add(&format!("({})", actualargs.join(", ")));
@@ -116,22 +93,25 @@ impl Selection {
Ok(fields.join("{") + &"}".repeat(fields.len() - 1)) Ok(fields.join("{") + &"}".repeat(fields.len() - 1))
} }
pub async fn execute<D>(&self, gql_client: &gql_client::Client) -> eyre::Result<D> pub fn execute<D>(&self, gql_client: &gql_client::Client) -> eyre::Result<Option<D>>
where where
D: for<'de> Deserialize<'de>, D: for<'de> Deserialize<'de>,
{ {
let query = self.build()?; let query = self.build()?;
tracing::trace!(query = query.as_str(), "dagger-query"); let basic = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
let resp: Option<serde_json::Value> = match gql_client.query(&query).await { 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)?; let resp: Option<D> = self.unpack_resp(resp)?;
Ok(resp.unwrap()) Ok(resp)
} }
fn path(&self) -> Vec<Selection> { fn path(&self) -> Vec<Selection> {
@@ -191,8 +171,10 @@ mod tests {
.select("core") .select("core")
.select("image") .select("image")
.arg("ref", "alpine") .arg("ref", "alpine")
.unwrap()
.select("file") .select("file")
.arg("path", "/etc/alpine-release"); .arg("path", "/etc/alpine-release")
.unwrap();
let query = root.build().unwrap(); let query = root.build().unwrap();
@@ -208,8 +190,10 @@ mod tests {
.select("core") .select("core")
.select("image") .select("image")
.arg("ref", "alpine") .arg("ref", "alpine")
.unwrap()
.select_with_alias("foo", "file") .select_with_alias("foo", "file")
.arg("path", "/etc/alpine-release"); .arg("path", "/etc/alpine-release")
.unwrap();
let query = root.build().unwrap(); let query = root.build().unwrap();
@@ -224,8 +208,10 @@ mod tests {
let root = query() let root = query()
.select("a") .select("a")
.arg("arg", "one") .arg("arg", "one")
.unwrap()
.select("b") .select("b")
.arg("arg", "two"); .arg("arg", "two")
.unwrap();
let query = root.build().unwrap(); let query = root.build().unwrap();
@@ -236,7 +222,7 @@ mod tests {
fn test_vec_arg() { fn test_vec_arg() {
let input = vec!["some-string"]; let input = vec!["some-string"];
let root = query().select("a").arg("arg", input); let root = query().select("a").arg("arg", input).unwrap();
let query = root.build().unwrap(); let query = root.build().unwrap();
assert_eq!(query, r#"query{a(arg:["some-string"])}"#.to_string()) assert_eq!(query, r#"query{a(arg:["some-string"])}"#.to_string())
@@ -246,7 +232,7 @@ mod tests {
fn test_ref_slice_arg() { fn test_ref_slice_arg() {
let input = &["some-string"]; let input = &["some-string"];
let root = query().select("a").arg("arg", input); let root = query().select("a").arg("arg", input).unwrap();
let query = root.build().unwrap(); let query = root.build().unwrap();
assert_eq!(query, r#"query{a(arg:["some-string"])}"#.to_string()) assert_eq!(query, r#"query{a(arg:["some-string"])}"#.to_string())
@@ -256,7 +242,7 @@ mod tests {
fn test_stringb_arg() { fn test_stringb_arg() {
let input = "some-string".to_string(); let input = "some-string".to_string();
let root = query().select("a").arg("arg", input); let root = query().select("a").arg("arg", input).unwrap();
let query = root.build().unwrap(); let query = root.build().unwrap();
assert_eq!(query, r#"query{a(arg:"some-string")}"#.to_string()) assert_eq!(query, r#"query{a(arg:"some-string")}"#.to_string())
@@ -289,7 +275,7 @@ mod tests {
})), })),
}; };
let root = query().select("a").arg("arg", input); let root = query().select("a").arg("arg", input).unwrap();
let query = root.build().unwrap(); let query = root.build().unwrap();
assert_eq!( assert_eq!(

View File

@@ -1,47 +0,0 @@
use dagger_sdk::{QueryContainerOpts, QueryContainerOptsBuilder};
static PLATFORMS: [&str; 2] = ["linux/arm64", "linux/x86_64"];
#[tokio::test]
async fn test_issue_30_alt() -> eyre::Result<()> {
let client = dagger_sdk::connect().await?;
for platform in PLATFORMS {
let ref_ = client
.container_opts(QueryContainerOpts {
id: None,
platform: Some(platform.to_string().into()),
})
.from("alpine")
.with_exec(vec!["echo", "'hello'"])
.exit_code()
.await?;
println!("published image to: {:#?}", ref_);
}
Ok(())
}
#[tokio::test]
async fn test_issue_30() -> eyre::Result<()> {
let client = dagger_sdk::connect().await?;
for platform in PLATFORMS {
let ref_ = client
.container_opts(
QueryContainerOptsBuilder::default()
.platform(platform)
.build()
.unwrap(),
)
.from("alpine")
.with_exec(vec!["echo", "'hello'"])
.exit_code()
.await?;
println!("published image to: {:#?}", ref_);
}
Ok(())
}

View File

@@ -1,29 +0,0 @@
use dagger_sdk::{ContainerWithExposedPortOpts, NetworkProtocol};
#[tokio::test]
async fn test_issue_30_alt() -> eyre::Result<()> {
let client = dagger_sdk::connect().await?;
client
.container()
.from("denoland/deno:debian-1.30.3")
.with_exposed_port_opts(
53,
ContainerWithExposedPortOpts {
protocol: Some(NetworkProtocol::TCP),
description: None,
},
)
.with_exposed_port_opts(
53,
ContainerWithExposedPortOpts {
protocol: Some(NetworkProtocol::UDP),
description: None,
},
)
.with_exec(vec!["echo", "hello"])
.exit_code()
.await?;
Ok(())
}

View File

@@ -1,2 +0,0 @@
mod iss_30;
mod iss_33;

View File

@@ -1,120 +1,21 @@
mod issues; use dagger_sdk::client::connect;
use dagger_sdk::gen::ContainerExecOpts;
use dagger_sdk::{connect, ContainerExecOptsBuilder}; #[test]
use pretty_assertions::assert_eq; fn test_example_container() {
let client = connect().unwrap();
#[tokio::test] let alpine = client.container(None).from("alpine:3.16.2".into());
async fn test_example_container() {
let client = connect().await.unwrap();
let alpine = client.container().from("alpine:3.16.2");
let out = alpine let out = alpine
.exec_opts( .exec(Some(ContainerExecOpts {
ContainerExecOptsBuilder::default() args: Some(vec!["cat".into(), "/etc/alpine-release".into()]),
.args(vec!["cat", "/etc/alpine-release"]) stdin: None,
.build() redirect_stdout: None,
.unwrap(), redirect_stderr: None,
) experimental_privileged_nesting: None,
.stdout() }))
.await .stdout();
.unwrap();
assert_eq!(out, "3.16.2\n".to_string()) assert_eq!(out, "3.16.2\n".to_string())
} }
#[tokio::test]
async fn test_directory() {
let c = connect().await.unwrap();
let contents = c
.directory()
.with_new_file("/hello.txt", "world")
.file("/hello.txt")
.contents()
.await
.unwrap();
assert_eq!("world", contents)
}
#[tokio::test]
async fn test_git() {
let c = connect().await.unwrap();
let tree = c.git("github.com/dagger/dagger").branch("main").tree();
let _ = tree
.entries()
.await
.unwrap()
.iter()
.find(|f| f.as_str() == "README.md")
.unwrap();
let readme_file = tree.file("README.md");
let readme = readme_file.contents().await.unwrap();
assert_eq!(true, readme.find("Dagger").is_some());
let readme_id = readme_file.id().await.unwrap();
let other_readme = c.file(readme_id).contents().await.unwrap();
assert_eq!(readme, other_readme);
}
#[tokio::test]
async fn test_container() {
let client = connect().await.unwrap();
let alpine = client.container().from("alpine:3.16.2");
let contents = alpine
.fs()
.file("/etc/alpine-release")
.contents()
.await
.unwrap();
assert_eq!(contents, "3.16.2\n".to_string());
let out = alpine
.exec_opts(
ContainerExecOptsBuilder::default()
.args(vec!["cat", "/etc/alpine-release"])
.build()
.unwrap(),
)
.stdout()
.await
.unwrap();
assert_eq!(out, "3.16.2\n".to_string());
let id = alpine.id().await.unwrap();
let contents = client
.container_opts(dagger_sdk::QueryContainerOpts {
id: Some(id),
platform: None,
})
.fs()
.file("/etc/alpine-release")
.contents()
.await
.unwrap();
assert_eq!(contents, "3.16.2\n".to_string());
}
#[tokio::test]
async fn test_err_message() {
let client = connect().await.unwrap();
let alpine = client.container().from("fake.invalid:latest").id().await;
assert_eq!(alpine.is_err(), true);
let err = alpine.expect_err("Tests expect err");
let error_msg = r#"
GQLClient Error: Look at json field for more details
Message: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
"#;
assert_eq!(err.to_string().as_str(), error_msg);
}

View File

@@ -13,11 +13,11 @@ impl Cli {
}) })
} }
pub async fn execute(self, args: &[&str]) -> eyre::Result<()> { pub fn execute(self, args: &[&str]) -> eyre::Result<()> {
let matches = self.cmd.get_matches_from(args); let matches = self.cmd.get_matches_from(args);
match matches.subcommand() { match matches.subcommand() {
Some(("generate", args)) => cli_generate::GenerateCommand::exec(args).await?, Some(("generate", args)) => cli_generate::GenerateCommand::exec(args)?,
_ => eyre::bail!("command missing"), _ => eyre::bail!("command missing"),
} }

View File

@@ -17,12 +17,12 @@ impl GenerateCommand {
clap::Command::new("generate").arg(Arg::new("output").long("output")) clap::Command::new("generate").arg(Arg::new("output").long("output"))
} }
pub async fn exec(arg_matches: &ArgMatches) -> eyre::Result<()> { pub fn exec(arg_matches: &ArgMatches) -> eyre::Result<()> {
let cfg = Config::default(); let cfg = Config::default();
let (conn, _proc) = Engine::new().start(&cfg).await?; let (conn, _proc) = Engine::new().start(&cfg)?;
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).await?; let schema = session.schema(req)?;
let code = generate( let code = generate(
schema.into_schema().schema.unwrap(), schema.into_schema().schema.unwrap(),
Arc::new(RustGenerator {}), Arc::new(RustGenerator {}),

View File

@@ -3,15 +3,16 @@ use cli::Cli;
pub mod cli; pub mod cli;
mod cli_generate; mod cli_generate;
#[tokio::main] fn main() -> eyre::Result<()> {
async fn main() -> eyre::Result<()> { //
color_eyre::install().unwrap(); color_eyre::install().unwrap();
let args = std::env::args(); let args = std::env::args();
let args = args.collect::<Vec<String>>(); let args = args.collect::<Vec<String>>();
let args = args.iter().map(|s| s.as_str()).collect::<Vec<&str>>(); let args = args.iter().map(|s| s.as_str()).collect::<Vec<&str>>();
Cli::new()?.execute(args.as_slice()).await?; Cli::new()?.execute(args.as_slice())?;
Ok(()) Ok(())
} }