mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-21 13:08:42 +00:00
Refactor cargo-binstall
(#1302)
- Move implementation of `main` into the library part of `cargo-binstall` to speedup codegen. - Move `manifests.rs` into `binstalk-manifests` Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
parent
4e73d0095f
commit
43973d7e86
8 changed files with 120 additions and 103 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -530,7 +530,6 @@ dependencies = [
|
||||||
"dirs",
|
"dirs",
|
||||||
"embed-resource",
|
"embed-resource",
|
||||||
"file-format",
|
"file-format",
|
||||||
"fs-lock",
|
|
||||||
"gh-token",
|
"gh-token",
|
||||||
"home",
|
"home",
|
||||||
"log",
|
"log",
|
||||||
|
|
|
@ -28,7 +28,6 @@ clap = { version = "4.3.0", features = ["derive", "env"] }
|
||||||
compact_str = "0.7.0"
|
compact_str = "0.7.0"
|
||||||
dirs = "5.0.1"
|
dirs = "5.0.1"
|
||||||
file-format = { version = "0.18.0", default-features = false }
|
file-format = { version = "0.18.0", default-features = false }
|
||||||
fs-lock = { version = "0.1.0", path = "../fs-lock" }
|
|
||||||
gh-token = "0.1.2"
|
gh-token = "0.1.2"
|
||||||
home = "0.5.5"
|
home = "0.5.5"
|
||||||
log = { version = "0.4.18", features = ["std"] }
|
log = { version = "0.4.18", features = ["std"] }
|
||||||
|
|
|
@ -21,8 +21,9 @@ use binstalk::{
|
||||||
CargoTomlFetchOverride, Options, Resolver,
|
CargoTomlFetchOverride, Options, Resolver,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use binstalk_manifests::cargo_config::Config;
|
use binstalk_manifests::{
|
||||||
use binstalk_manifests::cargo_toml_binstall::PkgOverride;
|
cargo_config::Config, cargo_toml_binstall::PkgOverride, crates_manifests::Manifests,
|
||||||
|
};
|
||||||
use file_format::FileFormat;
|
use file_format::FileFormat;
|
||||||
use home::cargo_home;
|
use home::cargo_home;
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
|
@ -33,7 +34,6 @@ use tracing::{debug, error, info, warn};
|
||||||
use crate::{
|
use crate::{
|
||||||
args::{Args, Strategy},
|
args::{Args, Strategy},
|
||||||
install_path,
|
install_path,
|
||||||
manifests::Manifests,
|
|
||||||
ui::confirm,
|
ui::confirm,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||||
|
|
||||||
pub mod args;
|
mod args;
|
||||||
pub mod bin_util;
|
mod bin_util;
|
||||||
pub mod entry;
|
mod entry;
|
||||||
mod git_credentials;
|
mod git_credentials;
|
||||||
mod install_path;
|
mod install_path;
|
||||||
pub mod logging;
|
mod logging;
|
||||||
mod manifests;
|
mod main_impl;
|
||||||
mod signal;
|
mod signal;
|
||||||
mod ui;
|
mod ui;
|
||||||
|
|
||||||
|
pub use main_impl::do_main;
|
||||||
|
|
|
@ -1,68 +1,11 @@
|
||||||
use std::time::Instant;
|
use std::process::Termination;
|
||||||
|
|
||||||
use binstalk::{helpers::jobserver_client::LazyJobserverClient, TARGET};
|
use cargo_binstall::do_main;
|
||||||
use log::LevelFilter;
|
|
||||||
use tracing::debug;
|
|
||||||
|
|
||||||
use cargo_binstall::{
|
|
||||||
args,
|
|
||||||
bin_util::{run_tokio_main, MainExit},
|
|
||||||
entry,
|
|
||||||
logging::logging,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(feature = "mimalloc")]
|
#[cfg(feature = "mimalloc")]
|
||||||
#[global_allocator]
|
#[global_allocator]
|
||||||
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
|
||||||
|
|
||||||
fn main() -> MainExit {
|
fn main() -> impl Termination {
|
||||||
// This must be the very first thing to happen
|
do_main()
|
||||||
let jobserver_client = LazyJobserverClient::new();
|
|
||||||
|
|
||||||
let args = args::parse();
|
|
||||||
|
|
||||||
if args.version {
|
|
||||||
let cargo_binstall_version = env!("CARGO_PKG_VERSION");
|
|
||||||
if args.verbose {
|
|
||||||
let build_date = env!("VERGEN_BUILD_DATE");
|
|
||||||
|
|
||||||
let features = env!("VERGEN_CARGO_FEATURES");
|
|
||||||
|
|
||||||
let git_sha = option_env!("VERGEN_GIT_SHA").unwrap_or("UNKNOWN");
|
|
||||||
let git_commit_date = option_env!("VERGEN_GIT_COMMIT_DATE").unwrap_or("UNKNOWN");
|
|
||||||
|
|
||||||
let rustc_semver = env!("VERGEN_RUSTC_SEMVER");
|
|
||||||
let rustc_commit_hash = env!("VERGEN_RUSTC_COMMIT_HASH");
|
|
||||||
let rustc_llvm_version = env!("VERGEN_RUSTC_LLVM_VERSION");
|
|
||||||
|
|
||||||
println!(
|
|
||||||
r#"cargo-binstall: {cargo_binstall_version}
|
|
||||||
build-date: {build_date}
|
|
||||||
build-target: {TARGET}
|
|
||||||
build-features: {features}
|
|
||||||
build-commit-hash: {git_sha}
|
|
||||||
build-commit-date: {git_commit_date}
|
|
||||||
rustc-version: {rustc_semver}
|
|
||||||
rustc-commit-hash: {rustc_commit_hash}
|
|
||||||
rustc-llvm-version: {rustc_llvm_version}"#
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
println!("{cargo_binstall_version}");
|
|
||||||
}
|
|
||||||
MainExit::Success(None)
|
|
||||||
} else {
|
|
||||||
logging(
|
|
||||||
args.log_level.unwrap_or(LevelFilter::Info),
|
|
||||||
args.json_output,
|
|
||||||
);
|
|
||||||
|
|
||||||
let start = Instant::now();
|
|
||||||
|
|
||||||
let result = run_tokio_main(|| entry::install_crates(args, jobserver_client));
|
|
||||||
|
|
||||||
let done = start.elapsed();
|
|
||||||
debug!("run time: {done:?}");
|
|
||||||
|
|
||||||
MainExit::new(result, done)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
64
crates/bin/src/main_impl.rs
Normal file
64
crates/bin/src/main_impl.rs
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
use std::{process::Termination, time::Instant};
|
||||||
|
|
||||||
|
use binstalk::{helpers::jobserver_client::LazyJobserverClient, TARGET};
|
||||||
|
use log::LevelFilter;
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
args,
|
||||||
|
bin_util::{run_tokio_main, MainExit},
|
||||||
|
entry,
|
||||||
|
logging::logging,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn do_main() -> impl Termination {
|
||||||
|
// This must be the very first thing to happen
|
||||||
|
let jobserver_client = LazyJobserverClient::new();
|
||||||
|
|
||||||
|
let args = args::parse();
|
||||||
|
|
||||||
|
if args.version {
|
||||||
|
let cargo_binstall_version = env!("CARGO_PKG_VERSION");
|
||||||
|
if args.verbose {
|
||||||
|
let build_date = env!("VERGEN_BUILD_DATE");
|
||||||
|
|
||||||
|
let features = env!("VERGEN_CARGO_FEATURES");
|
||||||
|
|
||||||
|
let git_sha = option_env!("VERGEN_GIT_SHA").unwrap_or("UNKNOWN");
|
||||||
|
let git_commit_date = option_env!("VERGEN_GIT_COMMIT_DATE").unwrap_or("UNKNOWN");
|
||||||
|
|
||||||
|
let rustc_semver = env!("VERGEN_RUSTC_SEMVER");
|
||||||
|
let rustc_commit_hash = env!("VERGEN_RUSTC_COMMIT_HASH");
|
||||||
|
let rustc_llvm_version = env!("VERGEN_RUSTC_LLVM_VERSION");
|
||||||
|
|
||||||
|
println!(
|
||||||
|
r#"cargo-binstall: {cargo_binstall_version}
|
||||||
|
build-date: {build_date}
|
||||||
|
build-target: {TARGET}
|
||||||
|
build-features: {features}
|
||||||
|
build-commit-hash: {git_sha}
|
||||||
|
build-commit-date: {git_commit_date}
|
||||||
|
rustc-version: {rustc_semver}
|
||||||
|
rustc-commit-hash: {rustc_commit_hash}
|
||||||
|
rustc-llvm-version: {rustc_llvm_version}"#
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
println!("{cargo_binstall_version}");
|
||||||
|
}
|
||||||
|
MainExit::Success(None)
|
||||||
|
} else {
|
||||||
|
logging(
|
||||||
|
args.log_level.unwrap_or(LevelFilter::Info),
|
||||||
|
args.json_output,
|
||||||
|
);
|
||||||
|
|
||||||
|
let start = Instant::now();
|
||||||
|
|
||||||
|
let result = run_tokio_main(|| entry::install_crates(args, jobserver_client));
|
||||||
|
|
||||||
|
let done = start.elapsed();
|
||||||
|
debug!("run time: {done:?}");
|
||||||
|
|
||||||
|
MainExit::new(result, done)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,13 +1,35 @@
|
||||||
use std::{collections::BTreeMap, fs, io::Seek, path::Path};
|
use std::{
|
||||||
|
collections::BTreeMap,
|
||||||
use binstalk::errors::BinstallError;
|
fs,
|
||||||
use binstalk_manifests::{
|
io::{self, Seek},
|
||||||
binstall_crates_v1::Records as BinstallCratesV1Records, cargo_crates_v1::CratesToml,
|
path::Path,
|
||||||
crate_info::CrateInfo, CompactString, Version,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use fs_lock::FileLock;
|
use fs_lock::FileLock;
|
||||||
use miette::{Error, Result};
|
use miette::Diagnostic;
|
||||||
use tracing::debug;
|
use thiserror::Error as ThisError;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
binstall_crates_v1::{Error as BinstallCratesV1Error, Records as BinstallCratesV1Records},
|
||||||
|
cargo_crates_v1::{CratesToml, CratesTomlParseError},
|
||||||
|
crate_info::CrateInfo,
|
||||||
|
CompactString, Version,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Debug, Diagnostic, ThisError)]
|
||||||
|
#[non_exhaustive]
|
||||||
|
pub enum ManifestsError {
|
||||||
|
#[error("failed to parse binstall crates-v1 manifest: {0}")]
|
||||||
|
#[diagnostic(transparent)]
|
||||||
|
BinstallCratesV1(#[from] BinstallCratesV1Error),
|
||||||
|
|
||||||
|
#[error("failed to parse cargo v1 manifest: {0}")]
|
||||||
|
#[diagnostic(transparent)]
|
||||||
|
CargoManifestV1(#[from] CratesTomlParseError),
|
||||||
|
|
||||||
|
#[error("I/O error: {0}")]
|
||||||
|
Io(#[from] io::Error),
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Manifests {
|
pub struct Manifests {
|
||||||
binstall: BinstallCratesV1Records,
|
binstall: BinstallCratesV1Records,
|
||||||
|
@ -15,33 +37,22 @@ pub struct Manifests {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Manifests {
|
impl Manifests {
|
||||||
pub fn open_exclusive(cargo_roots: &Path) -> Result<Self> {
|
pub fn open_exclusive(cargo_roots: &Path) -> Result<Self, ManifestsError> {
|
||||||
// Read cargo_binstall_metadata
|
// Read cargo_binstall_metadata
|
||||||
let metadata_path = cargo_roots.join("binstall/crates-v1.json");
|
let metadata_path = cargo_roots.join("binstall/crates-v1.json");
|
||||||
fs::create_dir_all(metadata_path.parent().unwrap()).map_err(BinstallError::Io)?;
|
fs::create_dir_all(metadata_path.parent().unwrap())?;
|
||||||
|
|
||||||
debug!(
|
|
||||||
"Reading binstall metadata from {} and obtaining exclusive lock",
|
|
||||||
metadata_path.display()
|
|
||||||
);
|
|
||||||
|
|
||||||
let binstall = BinstallCratesV1Records::load_from_path(&metadata_path)?;
|
let binstall = BinstallCratesV1Records::load_from_path(&metadata_path)?;
|
||||||
|
|
||||||
// Read cargo_install_v1_metadata
|
// Read cargo_install_v1_metadata
|
||||||
let manifest_path = cargo_roots.join(".crates.toml");
|
let manifest_path = cargo_roots.join(".crates.toml");
|
||||||
|
|
||||||
debug!(
|
|
||||||
"Obtaining exclusive lock of cargo install v1 metadata in path {}",
|
|
||||||
manifest_path.display()
|
|
||||||
);
|
|
||||||
|
|
||||||
let cargo_crates_v1 = fs::File::options()
|
let cargo_crates_v1 = fs::File::options()
|
||||||
.read(true)
|
.read(true)
|
||||||
.write(true)
|
.write(true)
|
||||||
.create(true)
|
.create(true)
|
||||||
.open(manifest_path)
|
.open(manifest_path)
|
||||||
.and_then(FileLock::new_exclusive)
|
.and_then(FileLock::new_exclusive)?;
|
||||||
.map_err(BinstallError::Io)?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
binstall,
|
binstall,
|
||||||
|
@ -49,32 +60,29 @@ impl Manifests {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn rewind_cargo_crates_v1(&mut self) -> Result<()> {
|
fn rewind_cargo_crates_v1(&mut self) -> Result<(), ManifestsError> {
|
||||||
self.cargo_crates_v1
|
self.cargo_crates_v1.rewind().map_err(ManifestsError::from)
|
||||||
.rewind()
|
|
||||||
.map_err(BinstallError::Io)
|
|
||||||
.map_err(Error::from)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `cargo-uninstall` can be called to uninstall crates,
|
/// `cargo-uninstall` can be called to uninstall crates,
|
||||||
/// but it only updates .crates.toml.
|
/// but it only updates .crates.toml.
|
||||||
///
|
///
|
||||||
/// So here we will honour .crates.toml only.
|
/// So here we will honour .crates.toml only.
|
||||||
pub fn load_installed_crates(&mut self) -> Result<BTreeMap<CompactString, Version>> {
|
pub fn load_installed_crates(
|
||||||
|
&mut self,
|
||||||
|
) -> Result<BTreeMap<CompactString, Version>, ManifestsError> {
|
||||||
self.rewind_cargo_crates_v1()?;
|
self.rewind_cargo_crates_v1()?;
|
||||||
|
|
||||||
CratesToml::load_from_reader(&mut self.cargo_crates_v1)
|
CratesToml::load_from_reader(&mut self.cargo_crates_v1)
|
||||||
.and_then(CratesToml::collect_into_crates_versions)
|
.and_then(CratesToml::collect_into_crates_versions)
|
||||||
.map_err(Error::from)
|
.map_err(ManifestsError::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(mut self, metadata_vec: Vec<CrateInfo>) -> Result<()> {
|
pub fn update(mut self, metadata_vec: Vec<CrateInfo>) -> Result<(), ManifestsError> {
|
||||||
self.rewind_cargo_crates_v1()?;
|
self.rewind_cargo_crates_v1()?;
|
||||||
|
|
||||||
debug!("Writing .crates.toml");
|
|
||||||
CratesToml::append_to_file(&mut self.cargo_crates_v1, &metadata_vec)?;
|
CratesToml::append_to_file(&mut self.cargo_crates_v1, &metadata_vec)?;
|
||||||
|
|
||||||
debug!("Writing binstall/crates-v1.json");
|
|
||||||
for metadata in metadata_vec {
|
for metadata in metadata_vec {
|
||||||
self.binstall.replace(metadata);
|
self.binstall.replace(metadata);
|
||||||
}
|
}
|
|
@ -13,6 +13,8 @@ mod helpers;
|
||||||
pub mod binstall_crates_v1;
|
pub mod binstall_crates_v1;
|
||||||
pub mod cargo_config;
|
pub mod cargo_config;
|
||||||
pub mod cargo_crates_v1;
|
pub mod cargo_crates_v1;
|
||||||
|
/// Contains both [`binstall_crates_v1`] and [`cargo_crates_v1`].
|
||||||
|
pub mod crates_manifests;
|
||||||
|
|
||||||
pub use binstalk_types::{cargo_toml_binstall, crate_info};
|
pub use binstalk_types::{cargo_toml_binstall, crate_info};
|
||||||
pub use compact_str::CompactString;
|
pub use compact_str::CompactString;
|
||||||
|
|
Loading…
Add table
Reference in a new issue