mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-24 22:30:03 +00:00
Refactor, improvements and bugfix for resolution and installation process (#619)
* Refactor: Extract new mod `ops::resolve::resolution` * Refactor: Extract new type `ResolutionFetch` * Refactor: Extract new type `ResolutionSource` * Improve `Resolution::print`: Provides more details on which crate is the resolution for. * Make `Resolution::print` a pub fn * Refactor: Extract new fn `ResolutionFetch::install` * Refactor: Extract new async fn `ResolutionSource::install` * Optimize `ResolutionSource::install` avoiding `OsStr::to_string_lossy`. * Add new dep command-group v2.0.0 to binstalk with feat with-tokio * Fix `ResolutionSource::install`: Use `AsyncCommandGroup::group_spawn` instead of `tokio::process::Command::spawn` to ensure all the processes spanwed by the `cargo` process can be terminated with one signal sent to the `cargo` process. * Fix printing resolution: Make sure they are printed without interleaving * Refactor `entry::install_crates` * Improve dry-run output for `ResolutionSource::install` * Refactor: Extract new fn `ResolutionFetch::print` * Refactor: Extract new fn `ResolutionSource::print` * Optimize `Resolution`: Box unit variant `Fetch` * Improve formatting of `tokio::process::Command` Prints out sth like `cargo install ...` instead of the `Debug::fmt`. * Improve dry-run output Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
parent
611485de52
commit
6bdb26930e
7 changed files with 323 additions and 289 deletions
|
@ -111,90 +111,98 @@ pub async fn install_crates(args: Args, jobserver_client: LazyJobserverClient) -
|
|||
let no_confirm = args.no_confirm;
|
||||
let no_cleanup = args.no_cleanup;
|
||||
|
||||
let tasks: Vec<_> = if !dry_run && !no_confirm {
|
||||
// Resolve crates
|
||||
let tasks: Vec<_> = crate_names
|
||||
.map(|(crate_name, current_version)| {
|
||||
AutoAbortJoinHandle::spawn(ops::resolve::resolve(
|
||||
binstall_opts.clone(),
|
||||
crate_name,
|
||||
current_version,
|
||||
))
|
||||
})
|
||||
.collect();
|
||||
// Resolve crates
|
||||
let tasks: Vec<_> = crate_names
|
||||
.map(|(crate_name, current_version)| {
|
||||
AutoAbortJoinHandle::spawn(ops::resolve::resolve(
|
||||
binstall_opts.clone(),
|
||||
crate_name,
|
||||
current_version,
|
||||
))
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Confirm
|
||||
let mut resolutions = Vec::with_capacity(tasks.len());
|
||||
for task in tasks {
|
||||
match task.await?? {
|
||||
Resolution::AlreadyUpToDate => {}
|
||||
res => resolutions.push(res),
|
||||
}
|
||||
}
|
||||
// Collect results
|
||||
let mut resolution_fetchs = Vec::new();
|
||||
let mut resolution_sources = Vec::new();
|
||||
|
||||
if resolutions.is_empty() {
|
||||
debug!("Nothing to do");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
confirm().await?;
|
||||
|
||||
// Install
|
||||
resolutions
|
||||
.into_iter()
|
||||
.map(|resolution| {
|
||||
AutoAbortJoinHandle::spawn(ops::install::install(resolution, binstall_opts.clone()))
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
// Resolve crates and install without confirmation
|
||||
crate_names
|
||||
.map(|(crate_name, current_version)| {
|
||||
let opts = binstall_opts.clone();
|
||||
|
||||
AutoAbortJoinHandle::spawn(async move {
|
||||
let resolution =
|
||||
ops::resolve::resolve(opts.clone(), crate_name, current_version).await?;
|
||||
|
||||
ops::install::install(resolution, opts).await
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
|
||||
let mut metadata_vec = Vec::with_capacity(tasks.len());
|
||||
for task in tasks {
|
||||
if let Some(metadata) = task.await?? {
|
||||
metadata_vec.push(metadata);
|
||||
match task.await?? {
|
||||
Resolution::AlreadyUpToDate => {}
|
||||
Resolution::Fetch(fetch) => {
|
||||
fetch.print(&binstall_opts);
|
||||
resolution_fetchs.push(fetch)
|
||||
}
|
||||
Resolution::InstallFromSource(source) => {
|
||||
source.print();
|
||||
resolution_sources.push(source)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
block_in_place(|| {
|
||||
if let Some((mut cargo_binstall_metadata, _)) = metadata {
|
||||
// The cargo manifest path is already created when loading
|
||||
// metadata.
|
||||
if resolution_fetchs.is_empty() && resolution_sources.is_empty() {
|
||||
debug!("Nothing to do");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
debug!("Writing .crates.toml");
|
||||
CratesToml::append_to_path(cargo_roots.join(".crates.toml"), metadata_vec.iter())?;
|
||||
// Confirm
|
||||
if !dry_run && !no_confirm {
|
||||
confirm().await?;
|
||||
}
|
||||
|
||||
debug!("Writing binstall/crates-v1.json");
|
||||
for metadata in metadata_vec {
|
||||
cargo_binstall_metadata.replace(metadata);
|
||||
}
|
||||
cargo_binstall_metadata.overwrite()?;
|
||||
}
|
||||
|
||||
if no_cleanup {
|
||||
// Consume temp_dir without removing it from fs.
|
||||
temp_dir.into_path();
|
||||
if !resolution_fetchs.is_empty() {
|
||||
if dry_run {
|
||||
info!("Dry-run: Not proceeding to install fetched binaries");
|
||||
} else {
|
||||
temp_dir.close().unwrap_or_else(|err| {
|
||||
warn!("Failed to clean up some resources: {err}");
|
||||
});
|
||||
}
|
||||
let f = || -> Result<()> {
|
||||
let metadata_vec = resolution_fetchs
|
||||
.into_iter()
|
||||
.map(|fetch| fetch.install(&binstall_opts))
|
||||
.collect::<Result<Vec<_>, BinstallError>>()?;
|
||||
|
||||
Ok(())
|
||||
})
|
||||
if let Some((mut cargo_binstall_metadata, _)) = metadata {
|
||||
// The cargo manifest path is already created when loading
|
||||
// metadata.
|
||||
|
||||
debug!("Writing .crates.toml");
|
||||
CratesToml::append_to_path(
|
||||
cargo_roots.join(".crates.toml"),
|
||||
metadata_vec.iter(),
|
||||
)?;
|
||||
|
||||
debug!("Writing binstall/crates-v1.json");
|
||||
for metadata in metadata_vec {
|
||||
cargo_binstall_metadata.replace(metadata);
|
||||
}
|
||||
cargo_binstall_metadata.overwrite()?;
|
||||
}
|
||||
|
||||
if no_cleanup {
|
||||
// Consume temp_dir without removing it from fs.
|
||||
temp_dir.into_path();
|
||||
} else {
|
||||
temp_dir.close().unwrap_or_else(|err| {
|
||||
warn!("Failed to clean up some resources: {err}");
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
};
|
||||
|
||||
block_in_place(f)?;
|
||||
}
|
||||
}
|
||||
|
||||
let tasks: Vec<_> = resolution_sources
|
||||
.into_iter()
|
||||
.map(|source| AutoAbortJoinHandle::spawn(source.install(binstall_opts.clone())))
|
||||
.collect();
|
||||
|
||||
for task in tasks {
|
||||
task.await??;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
type Metadata = (BinstallCratesV1Records, BTreeMap<CompactString, Version>);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue