diff --git a/Cargo.lock b/Cargo.lock index 06aaf26fc..b12a8253c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -87,109 +87,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" -[[package]] -name = "async-channel" -version = "1.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf46fee83e5ccffc220104713af3292ff9bc7c64c7de289f66dae8e38d826833" -dependencies = [ - "concurrent-queue", - "event-listener", - "futures-core", -] - -[[package]] -name = "async-executor" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17adb73da160dfb475c183343c8cccd80721ea5a605d3eb57125f0a7b7a92d0b" -dependencies = [ - "async-lock", - "async-task", - "concurrent-queue", - "fastrand", - "futures-lite", - "slab", -] - -[[package]] -name = "async-fs" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "279cf904654eeebfa37ac9bb1598880884924aab82e290aa65c9e77a0e142e06" -dependencies = [ - "async-lock", - "autocfg", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-io" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c374dda1ed3e7d8f0d9ba58715f924862c63eae6849c92d3a18e7fbde9e2794" -dependencies = [ - "async-lock", - "autocfg", - "concurrent-queue", - "futures-lite", - "libc", - "log", - "parking", - "polling", - "slab", - "socket2", - "waker-fn", - "windows-sys 0.42.0", -] - -[[package]] -name = "async-lock" -version = "2.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685" -dependencies = [ - "event-listener", - "futures-lite", -] - -[[package]] -name = "async-net" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4051e67316bc7eff608fe723df5d32ed639946adcd69e07df41fd42a7b411f1f" -dependencies = [ - "async-io", - "autocfg", - "blocking", - "futures-lite", -] - -[[package]] -name = "async-process" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6381ead98388605d0d9ff86371043b5aa922a3905824244de40dc263a14fcba4" -dependencies = [ - "async-io", - "async-lock", - "autocfg", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "libc", - "signal-hook", - "windows-sys 0.42.0", -] - -[[package]] -name = "async-task" -version = "4.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524" - [[package]] name = "async-trait" version = "0.1.66" @@ -210,12 +107,6 @@ dependencies = [ "num-traits 0.2.15", ] -[[package]] -name = "atomic-waker" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "debc29dde2e69f9e47506b525f639ed42300fc014a3e007832592448fa8e4599" - [[package]] name = "atty" version = "0.2.14" @@ -263,20 +154,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "blocking" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c67b173a56acffd6d2326fb7ab938ba0b00a71480e14902b2591c87bc5741e8" -dependencies = [ - "async-channel", - "async-lock", - "async-task", - "atomic-waker", - "fastrand", - "futures-lite", -] - [[package]] name = "bstr" version = "0.2.17" @@ -321,6 +198,12 @@ version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" +[[package]] +name = "bytes" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" + [[package]] name = "bytesize" version = "1.1.0" @@ -881,15 +764,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82a90734b3d5dcf656e7624cca6bce9c3a90ee11f900e80141a7427ccfb3d317" -[[package]] -name = "concurrent-queue" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c278839b831783b70278b14df4d45e1beb1aad306c07bb796637de9a0e323e8e" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "console" version = "0.15.5" @@ -1286,12 +1160,6 @@ dependencies = [ "libc", ] -[[package]] -name = "event-listener" -version = "2.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - [[package]] name = "fastrand" version = "1.9.0" @@ -1400,21 +1268,6 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" -[[package]] -name = "futures-lite" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48" -dependencies = [ - "fastrand", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] - [[package]] name = "futures-macro" version = "0.3.26" @@ -2487,6 +2340,18 @@ dependencies = [ "adler", ] +[[package]] +name = "mio" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b9d9a46eff5b4ff64b45a9e316a6d1e0bc719ef429cbec4dc630684212bfdf9" +dependencies = [ + "libc", + "log", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.45.0", +] + [[package]] name = "ndarray" version = "0.13.1" @@ -2704,12 +2569,6 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" -[[package]] -name = "parking" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72" - [[package]] name = "parking_lot" version = "0.11.2" @@ -2836,20 +2695,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "polling" -version = "2.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22122d5ec4f9fe1b3916419b76be1e80bcb93f618d071d2edf841b137b2a2bd6" -dependencies = [ - "autocfg", - "cfg-if", - "libc", - "log", - "wepoll-ffi", - "windows-sys 0.42.0", -] - [[package]] name = "portable-atomic" version = "0.3.19" @@ -3182,12 +3027,11 @@ dependencies = [ "serde_json", "serde_test", "similar-asserts", - "smol", - "smol-potat", "smol_str", "snapbox", "test-case", "thiserror", + "tokio", "toml 0.7.2", "toml_edit 0.19.6", "tracing", @@ -3356,44 +3200,6 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" -[[package]] -name = "smol" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13f2b548cd8447f8de0fdf1c592929f70f4fc7039a05e47404b0d096ec6987a1" -dependencies = [ - "async-channel", - "async-executor", - "async-fs", - "async-io", - "async-lock", - "async-net", - "async-process", - "blocking", - "futures-lite", -] - -[[package]] -name = "smol-potat" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "894ffa61af5c0fab697c8c29b1ab10cb6ec4978a1ccac4a81b5b312df1ffd88e" -dependencies = [ - "async-io", - "smol-potat-macro", -] - -[[package]] -name = "smol-potat-macro" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b7cd8129a18069385b4eadaa81182b1451fab312ad6f58d1d99253082bf3932" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "smol_str" version = "0.1.24" @@ -3431,16 +3237,6 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "485e65c1203eb37244465e857d15a26d3a85a5410648ccb53b18bd44cb3a7336" -[[package]] -name = "socket2" -version = "0.4.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "sprs" version = "0.7.1" @@ -3656,6 +3452,35 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" +[[package]] +name = "tokio" +version = "1.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03201d01c3c27a29c8a5cee5b55a93ddae1ccf6f08f65365c2c918f8c1b76f64" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "pin-project-lite", + "signal-hook-registry", + "tokio-macros", + "windows-sys 0.45.0", +] + +[[package]] +name = "tokio-macros" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d266c00fde287f55d3f1c3e96c500c362a2b8c695076ec180f27918820bc6df8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "toml" version = "0.4.10" @@ -3890,12 +3715,6 @@ dependencies = [ "libc", ] -[[package]] -name = "waker-fn" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca" - [[package]] name = "walkdir" version = "2.3.2" @@ -3973,15 +3792,6 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" -[[package]] -name = "wepoll-ffi" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb" -dependencies = [ - "cc", -] - [[package]] name = "which" version = "4.4.0" diff --git a/Cargo.toml b/Cargo.toml index e31ed86ae..398ffc8bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -58,7 +58,7 @@ snapbox = { version = "0.4.8", features = ["cmd", "path"] } tempfile = "3.4.0" test-case = "3.0.0" thiserror = "1.0.39" -tokio = { version = "1.26.0", features = ["macros", "process", "rt-multi-thread", "sync"] } +tokio = { version = "1.26.0", features = ["macros", "process", "io-util", "rt", "rt-multi-thread", "sync"] } toml = "0.7.1" toml_edit = { version = "0.19.6", features = ["serde"] } tracing = "0.1.37" diff --git a/scarb/src/bin/scarb/main.rs b/scarb/src/bin/scarb/main.rs index 9566c25df..e605d8e0b 100644 --- a/scarb/src/bin/scarb/main.rs +++ b/scarb/src/bin/scarb/main.rs @@ -68,5 +68,7 @@ fn cli_main(args: ScarbArgs) -> Result<()> { .log_filter_directive(env::var_os("SCARB_LOG")) .build()?; + let _ = config.tokio_runtime(); + commands::run(args.command, &mut config) } diff --git a/scarb/src/core/config.rs b/scarb/src/core/config.rs index 9d37487cb..35f34c206 100644 --- a/scarb/src/core/config.rs +++ b/scarb/src/core/config.rs @@ -7,6 +7,7 @@ use std::{env, mem}; use anyhow::{anyhow, Context, Result}; use camino::{Utf8Path, Utf8PathBuf}; use once_cell::sync::OnceCell; +use tokio::runtime::{Builder, Runtime}; use tracing::trace; use which::which_in; @@ -32,6 +33,7 @@ pub struct Config { log_filter_directive: OsString, offline: bool, compilers: CompilerRepository, + tokio_runtime: OnceCell, } impl Config { @@ -77,6 +79,7 @@ impl Config { log_filter_directive: b.log_filter_directive.unwrap_or_default(), offline: b.offline, compilers, + tokio_runtime: OnceCell::new(), }) } @@ -171,6 +174,11 @@ impl Config { not_static_al } + pub fn tokio_runtime(&self) -> &Runtime { + self.tokio_runtime + .get_or_init(|| Builder::new_multi_thread().build().unwrap()) + } + /// States whether the _Offline Mode_ is turned on. /// /// For checking whether Scarb can communicate with the network, prefer to use diff --git a/scarb/src/flock.rs b/scarb/src/flock.rs index 81b82c636..a12bb17f3 100644 --- a/scarb/src/flock.rs +++ b/scarb/src/flock.rs @@ -84,8 +84,8 @@ impl<'f> AdvisoryLock<'f> { /// This lock is global per-process and can be acquired recursively. /// An RAII structure is returned to release the lock, and if this process abnormally /// terminates the lock is also released. - pub fn acquire(&self) -> Result { - self.acquire_async().await_sync() + pub fn acquire(&self, config: &Config) -> Result { + self.acquire_async().await_sync(config.tokio_runtime()) } /// Async version of [`Self::acquire`]. diff --git a/scarb/src/internal/asyncx.rs b/scarb/src/internal/asyncx.rs index 7ce94f470..765df45ea 100644 --- a/scarb/src/internal/asyncx.rs +++ b/scarb/src/internal/asyncx.rs @@ -1,17 +1,18 @@ use std::future::IntoFuture; +use tokio::runtime::Runtime; pub trait AwaitSync { /// The output that the future will produce on completion. type Output; /// Synchronously await a future by starting a small one-off runtime internally. - fn await_sync(self) -> Self::Output; + fn await_sync(self, runtime: &Runtime) -> Self::Output; } impl AwaitSync for F { type Output = F::Output; - fn await_sync(self) -> Self::Output { - smol::block_on(self.into_future()) + fn await_sync(self, runtime: &Runtime) -> Self::Output { + runtime.block_on(self.into_future()) } } diff --git a/scarb/src/ops/resolve.rs b/scarb/src/ops/resolve.rs index b2e6d229c..3cdcd3841 100644 --- a/scarb/src/ops/resolve.rs +++ b/scarb/src/ops/resolve.rs @@ -51,7 +51,7 @@ pub fn resolve_workspace(ws: &Workspace<'_>) -> Result { Ok(WorkspaceResolve { resolve, packages }) } - .await_sync() + .await_sync(ws.config().tokio_runtime()) } #[tracing::instrument(skip_all, level = "debug")] diff --git a/scarb/src/process.rs b/scarb/src/process.rs index 611f83047..60243a9ea 100644 --- a/scarb/src/process.rs +++ b/scarb/src/process.rs @@ -1,11 +1,11 @@ use std::ffi::OsStr; -use std::io::{BufRead, BufReader, Read}; +use std::fmt; use std::path::Path; use std::process::{Command, Stdio}; use std::sync::Arc; -use std::{fmt, thread}; use anyhow::{anyhow, bail, Context, Result}; +use tokio::io::{AsyncBufReadExt, AsyncRead, BufReader}; use tracing::{debug, debug_span, warn, Span}; use crate::core::Config; @@ -49,62 +49,73 @@ pub fn exec_replace(cmd: &mut Command) -> Result<()> { /// Runs the process, waiting for completion, and mapping non-success exit codes to an error. #[tracing::instrument(level = "trace", skip_all)] -pub fn exec(cmd: &mut Command, config: &Config) -> Result<()> { - let cmd_str = shlex_join(cmd); +pub async fn async_exec(cmd: &mut tokio::process::Command, config: &Config) -> Result<()> { + // let cmd_str = ShlexJoin::from(&*cmd).to_string(); + let cmd_str = shlex_join(cmd.as_std()); config.ui().verbose(Status::new("Running", &cmd_str)); let _spinner = config.ui().widget(Spinner::new(cmd_str.clone())); - return thread::scope(move |s| { - let mut proc = cmd - .stdin(Stdio::null()) - .stdout(Stdio::piped()) - .stderr(Stdio::piped()) - .spawn() - .with_context(|| anyhow!("could not execute process: {cmd_str}"))?; - - let span = Arc::new(debug_span!("exec", pid = proc.id())); + async fn pipe_to_logs(span: &Span, stream: T) { let _enter = span.enter(); - debug!("{cmd_str}"); - - let stdout = proc.stdout.take().expect("we asked Rust to pipe stdout"); - s.spawn({ - let span = debug_span!("out"); - move || { - let mut stdout = stdout; - pipe_to_logs(&span, &mut stdout); - } - }); - - let stderr = proc.stderr.take().expect("we asked Rust to pipe stderr"); - s.spawn({ - let span = debug_span!("err"); - move || { - let mut stderr = stderr; - pipe_to_logs(&span, &mut stderr); - } - }); - - let exit_status = proc - .wait() - .with_context(|| anyhow!("could not wait for proces termination: {cmd_str}"))?; - if exit_status.success() { - Ok(()) - } else { - bail!("process did not exit successfully: {exit_status}"); - } - }); - - fn pipe_to_logs(span: &Span, stream: &mut dyn Read) { - let _enter = span.enter(); - let stream = BufReader::with_capacity(128, stream); - for line in stream.lines() { + let mut reader = BufReader::new(stream).lines(); + loop { + let line = reader.next_line().await; match line { - Ok(line) => debug!("{line}"), + Ok(Some(line)) => debug!("{line}"), + Ok(None) => break, Err(err) => warn!("{err:?}"), } } } + let runtime = config.tokio_runtime(); + let mut proc = cmd + .stdin(Stdio::null()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) + .spawn() + .with_context(|| anyhow!("could not execute process: {cmd_str}"))?; + + let span = Arc::new(debug_span!("exec", pid = proc.id())); + let _enter = span.enter(); + debug!("{cmd_str}"); + + let stdout = proc.stdout.take().expect("we asked Rust to pipe stdout"); + runtime.spawn(async move { + let span = debug_span!("out"); + // move || { + let mut stdout = stdout; + pipe_to_logs(&span, &mut stdout).await; + // } + }); + + let stderr = proc.stderr.take().expect("we asked Rust to pipe stderr"); + runtime.spawn(async move { + let span = debug_span!("err"); + // move || { + let mut stderr = stderr; + pipe_to_logs(&span, &mut stderr).await; + // } + }); + + // tokio::spawn(async move { + // let status = child.wait().await + // .expect("child process encountered an error"); + // + // println!("child status was: {}", status); + // }); + // runtime.spawn(async move { + let exit_status = proc + .wait() + .await + .with_context(|| anyhow!("could not wait for proces termination: {cmd_str}"))?; + if exit_status.success() { + Ok(()) + } else { + bail!("process did not exit successfully: {exit_status}"); + } + // }); + // Ok(()) } #[cfg(unix)] diff --git a/scarb/src/resolver/mod.rs b/scarb/src/resolver/mod.rs index 1d21440a2..631b95ebb 100644 --- a/scarb/src/resolver/mod.rs +++ b/scarb/src/resolver/mod.rs @@ -122,6 +122,7 @@ mod tests { use itertools::Itertools; use semver::Version; use similar_asserts::assert_serde_eq; + use tokio::runtime::Builder; use crate::core::package::PackageName; use crate::core::registry::mock::{deps, pkgs, registry, MockRegistry}; @@ -133,6 +134,7 @@ mod tests { roots: &[&[ManifestDependency]], expected: Result<&[PackageId], &str>, ) { + let runtime = Builder::new_multi_thread().build().unwrap(); let root_names = (1..).map(|n| PackageName::new(format!("ROOT_{n}"))); let summaries = roots @@ -150,7 +152,7 @@ mod tests { }) .collect_vec(); - let resolve = super::resolve(&summaries, &mut registry).await_sync(); + let resolve = super::resolve(&summaries, &mut registry).await_sync(&runtime); let resolve = resolve .map(|r| { diff --git a/scarb/src/sources/git/client.rs b/scarb/src/sources/git/client.rs index 43189c804..2ccaef4b1 100644 --- a/scarb/src/sources/git/client.rs +++ b/scarb/src/sources/git/client.rs @@ -8,14 +8,15 @@ //! repositories as source of super important information. use std::fmt; -use std::process::Command; +use std::path::Path; use anyhow::{anyhow, bail, Context, Result}; use camino::Utf8PathBuf; +use tokio::process::Command; use crate::core::{Config, GitReference}; use crate::flock::Filesystem; -use crate::process::exec; +use crate::process::async_exec; use crate::ui::Verbosity; use super::canonical_url::CanonicalUrl; @@ -58,12 +59,14 @@ impl fmt::Debug for GitDatabase { /// A local checkout of a particular Git commit. #[derive(Debug)] -pub struct GitCheckout<'d> { - pub db: &'d GitDatabase, +pub struct GitCheckout { + // pub db: &'d GitDatabase, pub location: Utf8PathBuf, pub rev: Rev, } +// unsafe impl Send for GitCheckout<'_> {} + #[derive(Copy, Clone, Eq, PartialEq)] pub struct Rev { oid: gix::ObjectId, @@ -96,8 +99,8 @@ impl GitRemote { self.url.ident() } - #[tracing::instrument(level = "trace", skip(config))] - pub fn checkout( + #[tracing::instrument(le vel = "trace", skip(config))] + pub async fn checkout( &self, fs: &Filesystem<'_>, db: Option, @@ -110,6 +113,7 @@ impl GitRemote { // version of `reference`, so return that database and the rev we resolve to. if let Some(db) = db { db.fetch(self.url.as_str(), reference, config) + .await .with_context(|| format!("failed to fetch into: {fs}"))?; match locked_rev { Some(rev) => { @@ -133,6 +137,7 @@ impl GitRemote { } let db = GitDatabase::init_bare(self, fs)?; db.fetch(self.url.as_str(), reference, config) + .await .with_context(|| format!("failed to clone into: {fs}"))?; let rev = match locked_rev { Some(rev) => rev, @@ -167,7 +172,7 @@ impl GitDatabase { } #[tracing::instrument(level = "trace", skip(config))] - fn fetch(&self, url: &str, reference: &GitReference, config: &Config) -> Result<()> { + async fn fetch(&self, url: &str, reference: &GitReference, config: &Config) -> Result<()> { if !config.network_allowed() { bail!("cannot fetch from `{}` in offline mode", self.remote); } @@ -187,17 +192,18 @@ impl GitDatabase { cmd.arg(url); cmd.args(refspecs); cmd.current_dir(self.repo.path()); - exec(&mut cmd, config) + async_exec(&mut cmd, config).await } - pub fn copy_to( + pub async fn copy_to( &self, fs: &Filesystem<'_>, rev: Rev, config: &Config, - ) -> Result> { - let checkout = GitCheckout::clone(self, fs, rev, config)?; - checkout.reset(config)?; + ) -> Result { + let path = self.repo.path().clone(); + let checkout = GitCheckout::clone(path, fs, rev, config).await?; + checkout.reset(config).await?; Ok(checkout) } @@ -249,9 +255,15 @@ impl GitDatabase { } } -impl<'d> GitCheckout<'d> { +impl GitCheckout { #[tracing::instrument(level = "trace", skip(config))] - fn clone(db: &'d GitDatabase, fs: &Filesystem<'_>, rev: Rev, config: &Config) -> Result { + async fn clone( + // db: &'d GitDatabase, + repo_path: &Path, + fs: &Filesystem<'_>, + rev: Rev, + config: &Config, + ) -> Result { unsafe { fs.recreate()?; } @@ -263,20 +275,25 @@ impl<'d> GitCheckout<'d> { with_verbosity_flags(&mut cmd, config); cmd.args(["--config", "core.autocrlf=false"]); cmd.arg("--recurse-submodules"); - cmd.arg(db.repo.path()); + // cmd.arg(db.repo.path()); + cmd.arg(repo_path); cmd.arg(&location); - exec(&mut cmd, config)?; + async_exec(&mut cmd, config).await?; - Ok(Self { db, location, rev }) + Ok(Self { + // db, + location, + rev, + }) } #[tracing::instrument(level = "trace", skip(config))] - fn reset(&self, config: &Config) -> Result<()> { + async fn reset(&self, config: &Config) -> Result<()> { let mut cmd = git_command(); cmd.args(["reset", "--hard"]); cmd.arg(self.rev.to_string()); cmd.current_dir(&self.location); - exec(&mut cmd, config) + async_exec(&mut cmd, config).await } } diff --git a/scarb/src/sources/git/mod.rs b/scarb/src/sources/git/mod.rs index a8872b0f9..efaab3d95 100644 --- a/scarb/src/sources/git/mod.rs +++ b/scarb/src/sources/git/mod.rs @@ -2,8 +2,7 @@ use std::{fmt, mem}; use anyhow::{Context, Result}; use async_trait::async_trait; -use smol::lock::OnceCell; -use smol::unblock; +use tokio::sync::OnceCell; use url::Url; use canonical_url::CanonicalUrl; @@ -13,6 +12,7 @@ use crate::core::source::Source; use crate::core::{ Config, GitReference, ManifestDependency, Package, PackageId, SourceId, Summary, }; +use crate::internal::asyncx::AwaitSync; use crate::sources::git::client::GitDatabase; use crate::ui::Status; @@ -81,8 +81,16 @@ impl<'c> GitSource<'c> { // but `smol::unblock` lifetime bounds force us to think so. let config: &'static Config = unsafe { mem::transmute(self.config) }; - return unblock(move || inner(source_id, remote, requested_reference, locked_rev, config)) - .await; + // return unblock(move || inner(source_id, remote, requested_reference, locked_rev, config)) + // .await; + + return inner( + source_id, + remote, + requested_reference, + locked_rev, + self.config, + ); fn inner( source_id: SourceId, @@ -91,6 +99,7 @@ impl<'c> GitSource<'c> { locked_rev: Option, config: &Config, ) -> Result> { + let runtime = config.tokio_runtime(); let remote_ident = remote.ident(); let registry_fs = config.dirs().registry_dir(); @@ -124,14 +133,18 @@ impl<'c> GitSource<'c> { .print(Status::new("Updating", &format!("git repository {remote}"))); } - remote.checkout(&db_fs, db, &requested_reference, locked_rev, config)? + remote + .checkout(&db_fs, db, &requested_reference, locked_rev, config) + .await_sync(runtime)? } }; let all_checkouts_fs = git_fs.child("checkouts"); let db_checkouts_fs = all_checkouts_fs.child(&remote_ident); let checkout_fs = db_checkouts_fs.child(db.short_id_of(actual_rev)?); - let checkout = db.copy_to(&checkout_fs, actual_rev, config)?; + let checkout = db + .copy_to(&checkout_fs, actual_rev, config) + .await_sync(runtime)?; let path_source = PathSource::recursive_at(&checkout.location, source_id, config); diff --git a/scarb/tests/e2e/flock.rs b/scarb/tests/e2e/flock.rs index 1c4cb1684..43627e6ac 100644 --- a/scarb/tests/e2e/flock.rs +++ b/scarb/tests/e2e/flock.rs @@ -22,6 +22,7 @@ fn locking_build_artifacts() { let manifest = t.child("Scarb.toml"); let config = Scarb::test_config(manifest); + let _ = config.tokio_runtime(); thread::scope(|s| { let lock = @@ -87,7 +88,7 @@ fn locking_package_cache() { let config = Scarb::test_config(manifest); thread::scope(|s| { - let lock = config.package_cache_lock().acquire(); + let lock = config.package_cache_lock().acquire(&config); let barrier = Arc::new(Barrier::new(2)); s.spawn({