Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/backend/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,10 @@ impl Backend for CargoBackend {
);
}

// cargo may sync the toolchain through rustup, which can't run concurrently
let _rust_state_locks =
crate::plugins::core::rust::lock_rust_state_for_config(&config, &tv.install_env())
.await?;
let mut cmd = CmdLineRunner::new(
self.spawn_program(&ctx.config, Some(&ctx.ts), "cargo")
.await,
Expand Down
2 changes: 1 addition & 1 deletion src/plugins/core/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ mod ruby_common;
pub(crate) fn gemfile_watch_patterns(path: &std::path::Path) -> Vec<String> {
ruby_common::gemfile_watch_patterns(path)
}
mod rust;
pub(crate) mod rust;
mod swift;
mod zig;

Expand Down
24 changes: 24 additions & 0 deletions src/plugins/core/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -973,6 +973,30 @@ fn rust_state_lock_identities(rustup_home: &Path, cargo_home: &Path) -> Vec<Path
identities
}

/// Serializes rustup state changes for the homes `config` resolves to. Callers that spawn
/// `cargo` (which may run rustup itself) must hold this so they don't race the rust plugin.
pub(crate) async fn lock_rust_state_for_config(
config: &Arc<Config>,
install_env: &IndexMap<String, crate::config::env_directive::EnvValue>,
) -> Result<Vec<fslock::LockFile>> {
let mut config_env = config.env().await?.clone();
for (key, value) in install_env {
match value.clone().into_string() {
Some(value) => config_env.insert(key.clone(), value),
None => config_env.shift_remove(key),
};
}
let settings = Settings::get();
let homes = RustHomes::from_sources(
&config_env,
settings.rust.cargo_home.clone(),
env::var_path("CARGO_HOME"),
settings.rust.rustup_home.clone(),
env::var_path("RUSTUP_HOME"),
);
lock_rust_state(&homes).await
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
}

async fn lock_rust_state(homes: &RustHomes) -> Result<Vec<fslock::LockFile>> {
let identities = rust_state_lock_identities(&homes.rustup, &homes.cargo);
tokio::task::spawn_blocking(move || {
Expand Down
Loading