Compare commits

...

31 Commits

Author SHA1 Message Date
82de43aa91 Release dagger-core v0.2.3, dagger-sdk v0.2.9, dagger-rs v0.2.10 2023-02-20 10:21:34 +01:00
f40ba9b403 fix(ci): with older version of dagger-sdk 2023-02-20 10:19:43 +01:00
75bc17e57d fix(core): Fix async panic on blocking #19
Replaced internal threads with tokio spawn functions
2023-02-20 10:19:43 +01:00
45d6462037 chore(ci): with async/await 2023-02-19 22:51:34 +01:00
04990247ba Release dagger-sdk v0.2.8, dagger-codegen v0.2.5 2023-02-19 22:43:48 +01:00
978ede68ae feat(sdk): add documentation strings 2023-02-19 22:43:12 +01:00
a1887afc8b Release dagger-sdk v0.2.7 2023-02-19 21:48:55 +01:00
d3faa996e6 docs: check async variant 2023-02-19 21:48:30 +01:00
93f40b356c docs(sdk): change to await syntax 2023-02-19 21:47:40 +01:00
9be6f435d9 feat(sdk,core): 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?;

  // ...
}
```
2023-02-19 21:47:40 +01:00
c35c104b49 chore(ci): update ci to use dagger-sdk v0.2.6 2023-02-19 18:28:47 +01:00
c312bc57ad Release dagger-sdk v0.2.6 2023-02-19 18:04:24 +01:00
04e70ce964 docs: fix readme 2023-02-19 18:04:10 +01:00
f72731807d Release dagger-sdk v0.2.5, dagger-codegen v0.2.4 2023-02-19 18:00:27 +01:00
c627595fd2 fix: cargo clippy 2023-02-19 18:00:04 +01:00
3f13c40ab8 fix: roadmap item api stabilization 2023-02-19 18:00:04 +01:00
f29ff836cf feat(sdk): 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
2023-02-19 18:00:04 +01:00
9762da895a feat(sdk): 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
2023-02-19 18:00:04 +01:00
02006d40fc fix(sdk): without phantom data 2023-02-19 18:00:04 +01:00
94336d0637 feat(sdk): 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
2023-02-19 18:00:04 +01:00
6e2292cf11 fix(sdk): dependencies 2023-02-19 15:39:10 +01:00
cc81124f89 Release dagger-sdk v0.2.4 2023-02-19 15:34:07 +01:00
7d04ab1240 fix(sdk): readme dagger-rs -> dagger-sdk 2023-02-19 15:33:48 +01:00
92350306b3 Release dagger-sdk v0.2.3, dagger-codegen v0.2.3, dagger-rs v0.2.9 2023-02-19 15:30:08 +01:00
19ed6c267f feat(sdk): re-export through lib.rs
this means that you can now use dagger_sdk::connect() instead of
dagger_sdk::client::connect();
2023-02-19 15:29:03 +01:00
de063eae85 feat(sdk): with return result instead of unwrap 2023-02-19 15:29:03 +01:00
5d66736990 feat(core,sdk): remove unnecessary option returns 2023-02-19 15:29:03 +01:00
9ada74960a feat(ci): add gha caching 2023-02-19 14:41:23 +01:00
90ab2e2b7d feat: clear release-cycle roadmap item 2023-02-19 14:37:23 +01:00
818ef6f74d feat(ci): lint pr 2023-02-19 12:57:32 +01:00
691ecfbf52 feat(ci): ci with dagger v0.2.2 2023-02-19 12:44:03 +01:00
42 changed files with 2870 additions and 1070 deletions

View File

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

15
.github/workflows/lint-pr.yml vendored Normal file
View File

@@ -0,0 +1,15 @@
name: "Lint PR"
on:
pull_request_target:
types:
- opened
- edited
- synchronize
jobs:
main:
name: Validate PR title
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@v5
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -5,6 +5,57 @@ 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.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)
### New Features

105
Cargo.lock generated
View File

@@ -114,8 +114,9 @@ version = "0.1.0"
dependencies = [
"clap",
"color-eyre",
"dagger-sdk 0.2.1",
"dagger-sdk 0.2.8",
"eyre",
"tokio",
]
[[package]]
@@ -245,10 +246,10 @@ dependencies = [
[[package]]
name = "dagger-codegen"
version = "0.2.2"
version = "0.2.5"
dependencies = [
"convert_case",
"dagger-core 0.2.2",
"dagger-core 0.2.3",
"eyre",
"genco",
"itertools",
@@ -259,9 +260,9 @@ dependencies = [
[[package]]
name = "dagger-core"
version = "0.2.1"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4805375918d0605477dac436be1c4d13a46c6f3fa1383b8eb624a31688a4b99b"
checksum = "7efe798e1fe0d882e335aab8928d5deaafb0d27869b69ec7e9e4686548e11753"
dependencies = [
"clap",
"dirs",
@@ -283,7 +284,7 @@ dependencies = [
[[package]]
name = "dagger-core"
version = "0.2.2"
version = "0.2.3"
dependencies = [
"clap",
"dirs",
@@ -301,16 +302,17 @@ dependencies = [
"sha2",
"tar",
"tempfile",
"tokio",
]
[[package]]
name = "dagger-rs"
version = "0.2.8"
version = "0.2.10"
dependencies = [
"clap",
"color-eyre",
"dagger-codegen",
"dagger-core 0.2.2",
"dagger-core 0.2.3",
"dirs",
"eyre",
"flate2",
@@ -326,21 +328,21 @@ dependencies = [
"sha2",
"tar",
"tempfile",
"tokio",
]
[[package]]
name = "dagger-sdk"
version = "0.2.1"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91342638dfdcd44ca5d3a2cc1b962e3f2c0e461487e90fe62972ef31df74c061"
checksum = "e90636d5b74ce8a62e8507a8d075c4d997c3123a1709596d0f97c3070f993b2d"
dependencies = [
"base64",
"dagger-core 0.2.1",
"dagger-core 0.2.2",
"derive_builder",
"eyre",
"futures",
"genco",
"gql_client",
"pretty_assertions",
"serde",
"serde_json",
"tokio",
@@ -348,10 +350,11 @@ dependencies = [
[[package]]
name = "dagger-sdk"
version = "0.2.2"
version = "0.2.9"
dependencies = [
"base64",
"dagger-core 0.2.2",
"dagger-core 0.2.3",
"derive_builder",
"eyre",
"futures",
"genco",
@@ -363,6 +366,72 @@ dependencies = [
"tokio",
]
[[package]]
name = "darling"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0808e1bd8671fb44a113a14e13497557533369847788fa2ae912b6ebfce9fa8"
dependencies = [
"darling_core",
"darling_macro",
]
[[package]]
name = "darling_core"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "001d80444f28e193f30c2f293455da62dcf9a6b29918a4253152ae2b1de592cb"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn",
]
[[package]]
name = "darling_macro"
version = "0.14.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685"
dependencies = [
"darling_core",
"quote",
"syn",
]
[[package]]
name = "derive_builder"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8"
dependencies = [
"derive_builder_macro",
]
[[package]]
name = "derive_builder_core"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f"
dependencies = [
"darling",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "derive_builder_macro"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e"
dependencies = [
"derive_builder_core",
"syn",
]
[[package]]
name = "diff"
version = "0.1.13"
@@ -839,6 +908,12 @@ dependencies = [
"tokio-native-tls",
]
[[package]]
name = "ident_case"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
[[package]]
name = "idna"
version = "0.3.0"

View File

@@ -1,6 +1,6 @@
[package]
name = "dagger-rs"
version = "0.2.8"
version = "0.2.10"
edition = "2021"
readme = "README.md"
license-file = "LICENSE.MIT"
@@ -19,8 +19,8 @@ members = [
]
[dependencies]
dagger-codegen = { path = "crates/dagger-codegen", version = "^0.2.2" }
dagger-core = { path = "crates/dagger-core", version = "^0.2.2" }
dagger-codegen = { path = "crates/dagger-codegen", version = "^0.2.3" }
dagger-core = { path = "crates/dagger-core", version = "^0.2.3" }
clap = "4.1.6"
dirs = "4.0.0"
@@ -42,3 +42,4 @@ sha2 = "0.10.6"
tar = "0.4.38"
tempfile = "3.3.0"
color-eyre = "0.6.2"
tokio = { version = "1.25.0", features = ["full"] }

View File

@@ -21,10 +21,10 @@ See [dagger-sdk](./crates/dagger-sdk/README.md)
- [x] Context
- [x] Deserializer for nested response (bind)
- [x] Add codegen to hook into querier
- [ ] fix build / release cycle
- [ ] general api stabilisation
- [x] fix build / release cycle
- [x] general api stabilisation
- [x] document usage
- [ ] make async variant
- [x] make async variant
## Architecture

View File

@@ -8,5 +8,6 @@ edition = "2021"
[dependencies]
clap = "4.1.6"
color-eyre = "0.6.2"
dagger-sdk = "0.2.1"
dagger-sdk = "0.2.6"
eyre = "0.6.8"
tokio = { version = "1.25.0", features = ["full"] }

View File

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

View File

@@ -5,6 +5,145 @@ 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.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/>
- 2 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**
- 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)
### New Features
@@ -15,7 +154,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
<csr-read-only-do-not-edit/>
- 1 commit contributed to the release.
- 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
@@ -26,6 +165,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
<details><summary>view details</summary>
* **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))
</details>

View File

@@ -1,6 +1,6 @@
[package]
name = "dagger-codegen"
version = "0.2.2"
version = "0.2.5"
edition = "2021"
readme = "README.md"
license-file = "LICENSE.MIT"

View File

@@ -6,8 +6,8 @@ use eyre::ContextCompat;
use crate::utility::OptionExt;
pub trait FormatTypeFuncs {
fn format_kind_list(&self, representation: &str) -> String;
fn format_kind_scalar_string(&self, representation: &str) -> String;
fn format_kind_list(&self, representation: &str, input: bool, immutable: bool) -> String;
fn format_kind_scalar_string(&self, representation: &str, input: bool) -> String;
fn format_kind_scalar_int(&self, representation: &str) -> String;
fn format_kind_scalar_float(&self, representation: &str) -> String;
fn format_kind_scalar_boolean(&self, representation: &str) -> String;
@@ -36,14 +36,18 @@ impl CommonFunctions {
}
pub fn format_input_type(&self, t: &TypeRef) -> String {
self.format_type(t, true)
self.format_type(t, true, false)
}
pub fn format_output_type(&self, t: &TypeRef) -> String {
self.format_type(t, false)
self.format_type(t, false, false)
}
fn format_type(&self, t: &TypeRef, input: bool) -> String {
pub fn format_immutable_input_type(&self, t: &TypeRef) -> 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 r = Some(t.clone());
while r.is_some() {
@@ -57,9 +61,14 @@ impl CommonFunctions {
Scalar::Float => self
.format_type_funcs
.format_kind_scalar_float(&mut representation),
Scalar::String => self
.format_type_funcs
.format_kind_scalar_string(&mut representation),
Scalar::String => {
if immutable {
"&'a str".into()
} else {
self.format_type_funcs
.format_kind_scalar_string(&mut representation, input)
}
}
Scalar::Boolean => self
.format_type_funcs
.format_kind_scalar_boolean(&mut representation),
@@ -87,12 +96,15 @@ impl CommonFunctions {
.as_ref()
.map(|t| t.clone())
.map(|t| *t)
.map(|t| self.format_type(&t, input))
.map(|t| self.format_type(&t, input, immutable))
.context("could not get inner type of list")
.unwrap();
representation =
self.format_type_funcs.format_kind_list(&mut inner_type);
representation = self.format_type_funcs.format_kind_list(
&mut inner_type,
input,
immutable,
);
return representation;
}

View File

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

View File

@@ -1,15 +1,17 @@
use convert_case::{Case, Casing};
use dagger_core::introspection::FullTypeFields;
use dagger_core::introspection::{FullTypeFields, TypeRef};
use genco::prelude::rust;
use genco::quote;
use genco::tokens::quoted;
use crate::functions::{
type_field_has_optional, type_ref_is_list_of_objects, type_ref_is_object,
type_ref_is_optional, CommonFunctions,
type_field_has_optional, type_ref_is_list, type_ref_is_list_of_objects, type_ref_is_object,
type_ref_is_optional, type_ref_is_scalar, CommonFunctions, Scalar,
};
use crate::utility::OptionExt;
use super::templates::object_tmpl::render_optional_field_args;
pub fn format_name(s: &str) -> String {
s.to_case(Case::Pascal)
}
@@ -29,28 +31,83 @@ pub fn field_options_struct_name(field: &FullTypeFields) -> Option<String> {
}
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! {
pub fn $(field.name.pipe(|n | format_struct_name(n)))
pub $(is_async) 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
.type_
.pipe(|t| &t.type_ref)
.pipe(|t| funcs.format_output_type(t));
.pipe(|t| render_output_type(funcs, t));
Some(quote! {
$(signature)(
$(args)
) -> $(output_type) {
let mut query = self.selection.select($(quoted(field.name.as_ref())));
if let Some((args, desc, true)) = args {
let required_args = format_required_function_args(funcs, field);
Some(quote! {
$(field.description.pipe(|d| format_struct_comment(d)))
$(&desc)
$(&signature)(
$(required_args)
) -> $(output_type.as_ref()) {
let mut query = self.selection.select($(quoted(field.name.as_ref())));
$(render_required_args(funcs, field))
$(render_optional_args(funcs, field))
$(render_required_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> {
@@ -66,8 +123,42 @@ fn render_required_args(_funcs: &CommonFunctions, field: &FullTypeFields) -> Opt
let n = format_struct_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_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! {
query = query.arg($(quoted(name)), $(n)).unwrap();
query = query.arg($(quoted(name)), $(n));
})
})
})
@@ -98,7 +189,7 @@ fn render_optional_args(_funcs: &CommonFunctions, field: &FullTypeFields) -> Opt
Some(quote! {
if let Some($(&n)) = opts.$(&n) {
query = query.arg($(quoted(name)), $(&n)).unwrap();
query = query.arg($(quoted(name)), $(&n));
}
})
})
@@ -111,9 +202,7 @@ fn render_optional_args(_funcs: &CommonFunctions, field: &FullTypeFields) -> Opt
}
let required_args = quote! {
if let Some(opts) = opts {
$(for arg in args join ($['\r']) => $arg)
}
$(for arg in args join ($['\r']) => $arg)
};
Some(required_args)
@@ -122,6 +211,20 @@ 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 {
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);
@@ -163,11 +266,91 @@ fn render_execution(funcs: &CommonFunctions, field: &FullTypeFields) -> rust::To
let graphql_client = rust::import("crate::client", "graphql_client");
quote! {
query.execute(&$graphql_client(&self.conn)).unwrap().unwrap()
query.execute(&$graphql_client(&self.conn)).await
}
}
fn format_function_args(funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> {
fn format_function_args(
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() {
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);
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! {
$(n): $(t),
})
})
})
.flatten()
.collect::<Vec<_>>();
let required_args = quote! {
&self,
$(for arg in args join ($['\r']) => $arg)
};
if type_field_has_optional(field) {
let field_name = field_options_struct_name(field);
argument_description.push(quote! {
$(field_name.pipe(|_| write_comment_line(&format!("* `opt` - optional argument, see inner type for documentation, use <func>_opts to use"))))
});
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 {
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((required_args, description, false))
}
} else {
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()
@@ -192,14 +375,56 @@ fn format_function_args(funcs: &CommonFunctions, field: &FullTypeFields) -> Opti
$(for arg in args join ($['\r']) => $arg)
};
if type_field_has_optional(field) {
Some(quote! {
$(required_args)
opts: Option<$(field_options_struct_name(field))>
})
} else {
Some(required_args)
}
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_))
.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

@@ -28,7 +28,7 @@ pub fn render_enum(t: &FullType) -> eyre::Result<rust::Tokens> {
let serialize = rust::import("serde", "Serialize");
Ok(quote! {
#[derive($serialize)]
#[derive($serialize, Clone, PartialEq, Debug)]
pub enum $(t.name.as_ref()) {
$(render_enum_values(t))
}

View File

@@ -9,7 +9,7 @@ pub fn render_input(funcs: &CommonFunctions, t: &FullType) -> eyre::Result<rust:
let deserialize = rust::import("serde", "Deserialize");
let serialize = rust::import("serde", "Serialize");
Ok(quote! {
#[derive($serialize, $deserialize)]
#[derive($serialize, $deserialize, Debug, PartialEq, Clone)]
pub struct $(format_name(t.name.as_ref().unwrap())) {
$(render_input_fields(funcs, t.input_fields.as_ref().unwrap_or(&Vec::new()) ))
}
@@ -33,6 +33,6 @@ pub fn render_input_fields(
pub fn render_input_field(funcs: &CommonFunctions, field: &FullTypeInputFields) -> rust::Tokens {
quote! {
pub $(format_struct_name(&field.input_value.name)): $(funcs.format_input_type(&field.input_value.type_)),
pub $(format_struct_name(&field.input_value.name)): $(funcs.format_output_type(&field.input_value.type_)),
}
}

View File

@@ -1,10 +1,12 @@
use dagger_core::introspection::{FullType, FullTypeFields, FullTypeFieldsArgs};
use genco::prelude::rust;
use genco::quote;
use itertools::Itertools;
use crate::functions::{type_ref_is_optional, CommonFunctions};
use crate::rust::functions::{
field_options_struct_name, format_function, format_name, format_struct_name,
field_options_struct_name, format_function, format_name, format_optional_args,
format_struct_comment, format_struct_name,
};
use crate::utility::OptionExt;
@@ -50,20 +52,17 @@ fn render_optional_args(
fn render_optional_arg(funcs: &CommonFunctions, field: &FullTypeFields) -> Option<rust::Tokens> {
let output_type = field_options_struct_name(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 fields = format_optional_args(funcs, field);
if let Some(fields) = fields {
let builder = rust::import("derive_builder", "Builder");
let _phantom_data = rust::import("std::marker", "PhantomData");
if let Some((fields, contains_lifetime)) = fields {
Some(quote! {
pub struct $output_type {
#[derive($builder, Debug, PartialEq)]
pub struct $output_type$(if contains_lifetime => <'a>) {
//#[builder(default, setter(skip))]
//pub marker: $(phantom_data)<&'a ()>,
$fields
}
})
@@ -72,22 +71,32 @@ fn render_optional_arg(funcs: &CommonFunctions, field: &FullTypeFields) -> Optio
}
}
fn render_optional_field_args(
pub fn render_optional_field_args(
funcs: &CommonFunctions,
args: &Vec<&FullTypeFieldsArgs>,
) -> Option<rust::Tokens> {
) -> Option<(rust::Tokens, bool)> {
if args.len() == 0 {
return None;
}
let mut contains_lifetime = false;
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! {
pub $(format_struct_name(&a.name)): Option<$(funcs.format_output_type(&a.type_))>,
$(a.description.pipe(|d| format_struct_comment(d)))
#[builder(setter(into, strip_option))]
pub $(format_struct_name(&a.name)): Option<$(type_)>,
}
});
Some(quote! {
$(for arg in rendered_args join ($['\r']) => $arg)
})
Some((
quote! {
$(for arg in rendered_args join ($['\r']) => $arg)
},
contains_lifetime,
))
}
fn render_functions(funcs: &CommonFunctions, fields: &Vec<FullTypeFields>) -> Option<rust::Tokens> {

View File

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

View File

@@ -5,11 +5,12 @@ 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.2.2 (2023-02-19)
## v0.2.3 (2023-02-20)
### New Features
### Bug Fixes
- <csr-id-6e5f4074329ab0462445b31d4153f8497c483438/> update to dagger v0.3.12
- <csr-id-75bc17e57db222492c6ffd2dfe80208d2bda75c9/> Fix async panic on blocking #19
Replaced internal threads with tokio spawn functions
### Commit Statistics
@@ -26,6 +27,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
<details><summary>view details</summary>
* **Uncategorized**
- Fix async panic on blocking #19 ([`75bc17e`](https://github.com/kjuulh/dagger-rs/commit/75bc17e57db222492c6ffd2dfe80208d2bda75c9))
</details>
## v0.2.2 (2023-02-19)
### New Features
- <csr-id-6e5f4074329ab0462445b31d4153f8497c483438/> update to dagger v0.3.12
### 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.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))
</details>

View File

@@ -1,6 +1,6 @@
[package]
name = "dagger-core"
version = "0.2.2"
version = "0.2.3"
edition = "2021"
readme = "README.md"
license-file = "LICENSE.MIT"
@@ -29,3 +29,4 @@ serde_json = "1.0.93"
sha2 = "0.10.6"
tar = "0.4.38"
tempfile = "3.3.0"
tokio = { version = "1.25.0", features = ["full"] }

View File

@@ -3,7 +3,7 @@ use std::{
io::{BufRead, BufReader},
path::PathBuf,
process::{Child, Stdio},
sync::{mpsc::sync_channel, Arc},
sync::Arc,
};
use crate::{config::Config, connect_params::ConnectParams};
@@ -20,12 +20,12 @@ impl CliSession {
}
}
pub fn connect(
pub async fn connect(
&self,
config: &Config,
cli_path: &PathBuf,
) -> eyre::Result<(ConnectParams, Child)> {
self.inner.connect(config, cli_path)
self.inner.connect(config, cli_path).await
}
}
@@ -33,13 +33,13 @@ impl CliSession {
struct InnerCliSession {}
impl InnerCliSession {
pub fn connect(
pub async fn connect(
&self,
config: &Config,
cli_path: &PathBuf,
) -> eyre::Result<(ConnectParams, Child)> {
let proc = self.start(config, cli_path)?;
let params = self.get_conn(proc)?;
let params = self.get_conn(proc).await?;
Ok(params)
}
@@ -70,7 +70,7 @@ impl InnerCliSession {
return Ok(proc);
}
fn get_conn(
async fn get_conn(
&self,
mut proc: std::process::Child,
) -> eyre::Result<(ConnectParams, std::process::Child)> {
@@ -84,14 +84,14 @@ impl InnerCliSession {
.take()
.ok_or(eyre::anyhow!("could not acquire stderr from child process"))?;
let (sender, receiver) = sync_channel(1);
let (sender, mut receiver) = tokio::sync::mpsc::channel(1);
std::thread::spawn(move || {
tokio::spawn(async move {
let stdout_bufr = BufReader::new(stdout);
for line in stdout_bufr.lines() {
let out = line.as_ref().unwrap();
if let Ok(conn) = serde_json::from_str::<ConnectParams>(&out) {
sender.send(conn).unwrap();
sender.send(conn).await.unwrap();
}
if let Ok(line) = line {
println!("dagger: {}", line);
@@ -99,7 +99,7 @@ impl InnerCliSession {
}
});
std::thread::spawn(|| {
tokio::spawn(async move {
let stderr_bufr = BufReader::new(stderr);
for line in stderr_bufr.lines() {
if let Ok(line) = line {
@@ -109,7 +109,7 @@ impl InnerCliSession {
}
});
let conn = receiver.recv()?;
let conn = receiver.recv().await.ok_or(eyre::anyhow!("could not receive ok signal from dagger-engine"))?;
Ok((conn, proc))
}

View File

@@ -119,7 +119,7 @@ impl Downloader {
Ok(path)
}
pub fn get_cli(&self) -> eyre::Result<PathBuf> {
pub async fn get_cli(&self) -> eyre::Result<PathBuf> {
let version = &self.version;
let mut cli_bin_path = self.cache_dir()?;
cli_bin_path.push(format!("{CLI_BIN_PREFIX}{version}"));
@@ -129,7 +129,7 @@ impl Downloader {
if !cli_bin_path.exists() {
cli_bin_path = self
.download(cli_bin_path)
.download(cli_bin_path).await
.context("failed to download CLI from archive")?;
}
@@ -145,8 +145,8 @@ impl Downloader {
Ok(cli_bin_path)
}
fn download(&self, path: PathBuf) -> eyre::Result<PathBuf> {
let expected_checksum = self.expected_checksum()?;
async fn download(&self, path: PathBuf) -> eyre::Result<PathBuf> {
let expected_checksum = self.expected_checksum().await?;
let mut bytes = vec![];
let actual_hash = self.extract_cli_archive(&mut bytes)?;
@@ -165,15 +165,15 @@ impl Downloader {
Ok(path)
}
fn expected_checksum(&self) -> eyre::Result<String> {
async fn expected_checksum(&self) -> eyre::Result<String> {
let archive_url = &self.archive_url();
let archive_path = PathBuf::from(&archive_url);
let archive_name = archive_path
.file_name()
.ok_or(eyre::anyhow!("could not get file_name from archive_url"))?;
let resp = reqwest::blocking::get(self.checksum_url())?;
let resp = reqwest::get(self.checksum_url()).await?;
let resp = resp.error_for_status()?;
for line in resp.text()?.lines() {
for line in resp.text().await?.lines() {
let mut content = line.split_whitespace();
let checksum = content
.next()
@@ -240,9 +240,9 @@ impl Downloader {
mod test {
use super::Downloader;
#[test]
fn download() {
let cli_path = Downloader::new("0.3.10".into()).unwrap().get_cli().unwrap();
#[tokio::test]
async fn download() {
let cli_path = Downloader::new("0.3.10".into()).unwrap().get_cli().await.unwrap();
assert_eq!(
Some("dagger-0.3.10"),

View File

@@ -11,17 +11,17 @@ impl Engine {
Self {}
}
fn from_cli(&self, cfg: &Config) -> eyre::Result<(ConnectParams, Child)> {
let cli = Downloader::new("0.3.12".into())?.get_cli()?;
async fn from_cli(&self, cfg: &Config) -> eyre::Result<(ConnectParams, Child)> {
let cli = Downloader::new("0.3.12".into())?.get_cli().await?;
let cli_session = CliSession::new();
Ok(cli_session.connect(cfg, &cli)?)
Ok(cli_session.connect(cfg, &cli).await?)
}
pub fn start(&self, cfg: &Config) -> eyre::Result<(ConnectParams, Child)> {
pub async fn start(&self, cfg: &Config) -> eyre::Result<(ConnectParams, Child)> {
// TODO: Add from existing session as well
self.from_cli(cfg)
self.from_cli(cfg).await
}
}
@@ -32,10 +32,10 @@ mod tests {
use super::Engine;
// TODO: these tests potentially have a race condition
#[test]
fn engine_can_start() {
#[tokio::test]
async fn engine_can_start() {
let engine = Engine::new();
let params = engine.start(&Config::new(None, None, None, None)).unwrap();
let params = engine.start(&Config::new(None, None, None, None)).await.unwrap();
assert_ne!(
params.0,

View File

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

View File

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

View File

@@ -5,15 +5,86 @@ 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.2.2 (2023-02-19)
### New Features
- <csr-id-6e5f4074329ab0462445b31d4153f8497c483438/> update to dagger v0.3.12
## v0.2.9 (2023-02-20)
### Bug Fixes
- <csr-id-10bc6f3846b65cc82c2fb343d8cfe921784bef1b/> fixed fmt errors
- <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.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
@@ -30,6 +101,185 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
<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)
### New Features
- <csr-id-6e5f4074329ab0462445b31d4153f8497c483438/> update to dagger v0.3.12
### Bug Fixes
- <csr-id-10bc6f3846b65cc82c2fb343d8cfe921784bef1b/> fixed fmt errors
### 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-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))
- 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))

View File

@@ -1,6 +1,6 @@
[package]
name = "dagger-sdk"
version = "0.2.2"
version = "0.2.9"
edition = "2021"
readme = "README.md"
license-file = "LICENSE.MIT"
@@ -11,17 +11,18 @@ publish = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
dagger-core = { path = "../dagger-core", version = "^0.2.3" }
base64 = "0.21.0"
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"
pretty_assertions = "1.3.0"
serde = { version = "1.0.152", features = ["derive"] }
serde_json = "1.0.93"
tokio = { version = "1.25.0", features = ["full"] }
derive_builder = "0.12.0"
[dev-dependencies]
pretty_assertions = "1.3.0"
rand = "0.8.5"
genco = "0.17.3"

View File

@@ -1,4 +1,4 @@
# dagger-rs
# dagger-sdk
A dagger sdk written in rust for rust.
@@ -19,20 +19,21 @@ The examples match the folder name in each directory in examples
Simply install like:
```bash
cargo install dagger-sdk
cargo add dagger-sdk
```
### Usage
```rust
fn main() -> eyre::Result<()> {
let client = dagger_sdk::client::connect()?;
#[tokio::main]
async fn main() -> eyre::Result<()> {
let client = dagger_sdk::connect()?;
let version = client
.container(None)
.from("golang:1.19".into())
.with_exec(vec!["go".into(), "version".into()], None)
.stdout();
.container()
.from("golang:1.19")
.with_exec(vec!["go", "version"])
.stdout().await?;
println!("Hello from Dagger and {}", version.trim());
@@ -45,3 +46,9 @@ And run it like a normal application:
```bash
cargo run
```
### Disclaimer
You are free to use something else than `tokio`, I haven't tested it with
anything else, but it should work with any other runtime. We don't rely on it
specifically. That might change in the future though.

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -13,9 +13,9 @@ use crate::querybuilder::query;
pub type DaggerConn = Arc<Query>;
pub fn connect() -> eyre::Result<DaggerConn> {
pub async fn connect() -> eyre::Result<DaggerConn> {
let cfg = Config::default();
let (conn, proc) = DaggerEngine::new().start(&cfg)?;
let (conn, proc) = DaggerEngine::new().start(&cfg).await?;
Ok(Arc::new(Query {
conn,
@@ -44,8 +44,8 @@ pub fn graphql_client(conn: &ConnectParams) -> gql_client::Client {
mod test {
use super::connect;
#[test]
fn test_connect() {
let _ = connect().unwrap();
#[tokio::test]
async fn test_connect() {
let _ = connect().await.unwrap();
}
}

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -46,13 +46,13 @@ impl Selection {
}
}
pub fn arg<S>(&self, name: &str, value: S) -> eyre::Result<Selection>
pub fn arg<S>(&self, name: &str, value: S) -> Selection
where
S: Serialize,
{
let mut s = self.clone();
let val = serde_json::to_string(&value)?;
let val = serde_json::to_string(&value).unwrap();
match s.args.as_mut() {
Some(args) => {
@@ -65,7 +65,7 @@ impl Selection {
}
}
Ok(s)
s
}
pub fn build(&self) -> eyre::Result<String> {
@@ -93,25 +93,20 @@ impl Selection {
Ok(fields.join("{") + &"}".repeat(fields.len() - 1))
}
pub fn execute<D>(&self, gql_client: &gql_client::Client) -> eyre::Result<Option<D>>
pub async fn execute<D>(&self, gql_client: &gql_client::Client) -> eyre::Result<D>
where
D: for<'de> Deserialize<'de>,
{
let query = self.build()?;
let basic = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
let resp: Option<serde_json::Value> = match basic.block_on(gql_client.query(&query)) {
let resp: Option<serde_json::Value> = match gql_client.query(&query).await {
Ok(r) => r,
Err(e) => eyre::bail!(e),
};
let resp: Option<D> = self.unpack_resp(resp)?;
Ok(resp)
Ok(resp.unwrap())
}
fn path(&self) -> Vec<Selection> {
@@ -171,10 +166,8 @@ mod tests {
.select("core")
.select("image")
.arg("ref", "alpine")
.unwrap()
.select("file")
.arg("path", "/etc/alpine-release")
.unwrap();
.arg("path", "/etc/alpine-release");
let query = root.build().unwrap();
@@ -190,10 +183,8 @@ mod tests {
.select("core")
.select("image")
.arg("ref", "alpine")
.unwrap()
.select_with_alias("foo", "file")
.arg("path", "/etc/alpine-release")
.unwrap();
.arg("path", "/etc/alpine-release");
let query = root.build().unwrap();
@@ -208,10 +199,8 @@ mod tests {
let root = query()
.select("a")
.arg("arg", "one")
.unwrap()
.select("b")
.arg("arg", "two")
.unwrap();
.arg("arg", "two");
let query = root.build().unwrap();
@@ -222,7 +211,7 @@ mod tests {
fn test_vec_arg() {
let input = vec!["some-string"];
let root = query().select("a").arg("arg", input).unwrap();
let root = query().select("a").arg("arg", input);
let query = root.build().unwrap();
assert_eq!(query, r#"query{a(arg:["some-string"])}"#.to_string())
@@ -232,7 +221,7 @@ mod tests {
fn test_ref_slice_arg() {
let input = &["some-string"];
let root = query().select("a").arg("arg", input).unwrap();
let root = query().select("a").arg("arg", input);
let query = root.build().unwrap();
assert_eq!(query, r#"query{a(arg:["some-string"])}"#.to_string())
@@ -242,7 +231,7 @@ mod tests {
fn test_stringb_arg() {
let input = "some-string".to_string();
let root = query().select("a").arg("arg", input).unwrap();
let root = query().select("a").arg("arg", input);
let query = root.build().unwrap();
assert_eq!(query, r#"query{a(arg:"some-string")}"#.to_string())
@@ -275,7 +264,7 @@ mod tests {
})),
};
let root = query().select("a").arg("arg", input).unwrap();
let root = query().select("a").arg("arg", input);
let query = root.build().unwrap();
assert_eq!(

View File

@@ -1,21 +1,21 @@
use dagger_sdk::client::connect;
use dagger_sdk::gen::ContainerExecOpts;
use dagger_sdk::{connect, ContainerExecOptsBuilder};
#[test]
fn test_example_container() {
let client = connect().unwrap();
#[tokio::test]
async fn test_example_container() {
let client = connect().await.unwrap();
let alpine = client.container(None).from("alpine:3.16.2".into());
let alpine = client.container().from("alpine:3.16.2");
let out = alpine
.exec(Some(ContainerExecOpts {
args: Some(vec!["cat".into(), "/etc/alpine-release".into()]),
stdin: None,
redirect_stdout: None,
redirect_stderr: None,
experimental_privileged_nesting: None,
}))
.stdout();
.exec_opts(
ContainerExecOptsBuilder::default()
.args(vec!["cat", "/etc/alpine-release"])
.build()
.unwrap(),
)
.stdout()
.await
.unwrap();
assert_eq!(out, "3.16.2\n".to_string())
}

View File

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

View File

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

View File

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