diff --git a/Cargo.lock b/Cargo.lock index b473ea7..2952338 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -278,6 +278,7 @@ dependencies = [ "sha2", "tar", "tempfile", + "tokio", ] [[package]] @@ -327,6 +328,7 @@ dependencies = [ "sha2", "tar", "tempfile", + "tokio", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 1f77454..8ea43b4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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"] } diff --git a/crates/dagger-core/Cargo.toml b/crates/dagger-core/Cargo.toml index 9a31351..53c2051 100644 --- a/crates/dagger-core/Cargo.toml +++ b/crates/dagger-core/Cargo.toml @@ -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"] } diff --git a/crates/dagger-core/src/cli_session.rs b/crates/dagger-core/src/cli_session.rs index 5cf9ed4..42a62d6 100644 --- a/crates/dagger-core/src/cli_session.rs +++ b/crates/dagger-core/src/cli_session.rs @@ -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::(&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)) } diff --git a/crates/dagger-core/src/downloader.rs b/crates/dagger-core/src/downloader.rs index 7e5d1a8..6489bc4 100644 --- a/crates/dagger-core/src/downloader.rs +++ b/crates/dagger-core/src/downloader.rs @@ -119,7 +119,7 @@ impl Downloader { Ok(path) } - pub fn get_cli(&self) -> eyre::Result { + pub async fn get_cli(&self) -> eyre::Result { 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 { - let expected_checksum = self.expected_checksum()?; + async fn download(&self, path: PathBuf) -> eyre::Result { + 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 { + async fn expected_checksum(&self) -> eyre::Result { 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"), diff --git a/crates/dagger-core/src/engine.rs b/crates/dagger-core/src/engine.rs index f993f68..873a337 100644 --- a/crates/dagger-core/src/engine.rs +++ b/crates/dagger-core/src/engine.rs @@ -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, diff --git a/crates/dagger-core/src/schema.rs b/crates/dagger-core/src/schema.rs index b52729d..7b3dbed 100644 --- a/crates/dagger-core/src/schema.rs +++ b/crates/dagger-core/src/schema.rs @@ -1,14 +1,14 @@ use crate::introspection::IntrospectionResponse; use crate::{config::Config, engine::Engine, session::Session}; -pub fn get_schema() -> eyre::Result { +pub async fn get_schema() -> eyre::Result { 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 { 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(); } } diff --git a/crates/dagger-core/src/session.rs b/crates/dagger-core/src/session.rs index d719f30..6f4c083 100644 --- a/crates/dagger-core/src/session.rs +++ b/crates/dagger-core/src/session.rs @@ -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 { + pub async fn schema(&self, req_builder: RequestBuilder) -> eyre::Result { 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::(&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) } diff --git a/crates/dagger-sdk/examples/build-the-application/main.rs b/crates/dagger-sdk/examples/build-the-application/main.rs index 8f9d2b4..e387c05 100644 --- a/crates/dagger-sdk/examples/build-the-application/main.rs +++ b/crates/dagger-sdk/examples/build-the-application/main.rs @@ -2,7 +2,7 @@ use dagger_sdk::HostDirectoryOpts; #[tokio::main] async fn main() -> eyre::Result<()> { - let client = dagger_sdk::connect()?; + let client = dagger_sdk::connect().await?; let host_source_dir = client.host().directory_opts( "examples/build-the-application/app", diff --git a/crates/dagger-sdk/examples/caching/main.rs b/crates/dagger-sdk/examples/caching/main.rs index 2d8819c..c2c9b36 100644 --- a/crates/dagger-sdk/examples/caching/main.rs +++ b/crates/dagger-sdk/examples/caching/main.rs @@ -2,7 +2,7 @@ use rand::Rng; #[tokio::main] async fn main() -> eyre::Result<()> { - let client = dagger_sdk::connect()?; + let client = dagger_sdk::connect().await?; let host_source_dir = client.host().directory_opts( "./examples/caching/app", diff --git a/crates/dagger-sdk/examples/existing-dockerfile/main.rs b/crates/dagger-sdk/examples/existing-dockerfile/main.rs index c1b4e77..7cb0e26 100644 --- a/crates/dagger-sdk/examples/existing-dockerfile/main.rs +++ b/crates/dagger-sdk/examples/existing-dockerfile/main.rs @@ -4,7 +4,7 @@ use rand::Rng; async fn main() -> eyre::Result<()> { let mut rng = rand::thread_rng(); - let client = dagger_sdk::connect()?; + let client = dagger_sdk::connect().await?; let context_dir = client .host() diff --git a/crates/dagger-sdk/examples/first-pipeline/main.rs b/crates/dagger-sdk/examples/first-pipeline/main.rs index 2c2c088..192cf6e 100644 --- a/crates/dagger-sdk/examples/first-pipeline/main.rs +++ b/crates/dagger-sdk/examples/first-pipeline/main.rs @@ -1,6 +1,6 @@ #[tokio::main] async fn main() -> eyre::Result<()> { - let client = dagger_sdk::connect()?; + let client = dagger_sdk::connect().await?; let version = client .container() diff --git a/crates/dagger-sdk/examples/multi-stage-build/main.rs b/crates/dagger-sdk/examples/multi-stage-build/main.rs index 5baeac2..1bc0e06 100644 --- a/crates/dagger-sdk/examples/multi-stage-build/main.rs +++ b/crates/dagger-sdk/examples/multi-stage-build/main.rs @@ -3,7 +3,7 @@ use rand::Rng; #[tokio::main] async fn main() -> eyre::Result<()> { - let client = dagger_sdk::connect()?; + let client = dagger_sdk::connect().await?; let host_source_dir = client.host().directory_opts( "examples/publish-the-application/app", diff --git a/crates/dagger-sdk/examples/publish-the-application/main.rs b/crates/dagger-sdk/examples/publish-the-application/main.rs index cba4b0d..ba80ad1 100644 --- a/crates/dagger-sdk/examples/publish-the-application/main.rs +++ b/crates/dagger-sdk/examples/publish-the-application/main.rs @@ -3,7 +3,7 @@ use rand::Rng; #[tokio::main] async fn main() -> eyre::Result<()> { - let client = dagger_sdk::connect()?; + let client = dagger_sdk::connect().await?; let output = "examples/publish-the-application/app/build"; let host_source_dir = client.host().directory_opts( diff --git a/crates/dagger-sdk/examples/test-the-application/main.rs b/crates/dagger-sdk/examples/test-the-application/main.rs index a3b69c1..c758763 100644 --- a/crates/dagger-sdk/examples/test-the-application/main.rs +++ b/crates/dagger-sdk/examples/test-the-application/main.rs @@ -2,7 +2,7 @@ use dagger_sdk::HostDirectoryOpts; #[tokio::main] async fn main() -> eyre::Result<()> { - let client = dagger_sdk::connect()?; + let client = dagger_sdk::connect().await?; let host_source_dir = client.host().directory_opts( "examples/test-the-application/app", diff --git a/crates/dagger-sdk/src/client.rs b/crates/dagger-sdk/src/client.rs index b0b4a8f..482654f 100644 --- a/crates/dagger-sdk/src/client.rs +++ b/crates/dagger-sdk/src/client.rs @@ -13,9 +13,9 @@ use crate::querybuilder::query; pub type DaggerConn = Arc; -pub fn connect() -> eyre::Result { +pub async fn connect() -> eyre::Result { 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(); } } diff --git a/crates/dagger-sdk/src/gen.rs b/crates/dagger-sdk/src/gen.rs index 4c76fff..5b2108c 100644 --- a/crates/dagger-sdk/src/gen.rs +++ b/crates/dagger-sdk/src/gen.rs @@ -22,8 +22,8 @@ pub struct SecretId(String); pub struct SocketId(String); #[derive(Serialize, Deserialize, Debug, PartialEq, Clone)] pub struct BuildArg { - pub name: String, pub value: String, + pub name: String, } pub struct CacheVolume { pub proc: Arc, diff --git a/crates/dagger-sdk/tests/mod.rs b/crates/dagger-sdk/tests/mod.rs index 9de0a06..6980530 100644 --- a/crates/dagger-sdk/tests/mod.rs +++ b/crates/dagger-sdk/tests/mod.rs @@ -2,7 +2,7 @@ use dagger_sdk::{connect, ContainerExecOptsBuilder}; #[tokio::test] async fn test_example_container() { - let client = connect().unwrap(); + let client = connect().await.unwrap(); let alpine = client.container().from("alpine:3.16.2"); diff --git a/src/cli.rs b/src/cli.rs index ae5f005..943d6ae 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -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"), } diff --git a/src/cli_generate.rs b/src/cli_generate.rs index c9c5e75..d2457fb 100644 --- a/src/cli_generate.rs +++ b/src/cli_generate.rs @@ -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 {}), diff --git a/src/main.rs b/src/main.rs index a9cbd75..545d401 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,14 +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::>(); let args = args.iter().map(|s| s.as_str()).collect::>(); - Cli::new()?.execute(args.as_slice())?; + Cli::new()?.execute(args.as_slice()).await?; Ok(()) }