mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-05-03 02:30:02 +00:00

* Optimization: Rm `debug!` in `find_version` printing all version iterated obviously doesn't help much in debugging in the problem but rather just confusing. Also this makes it hard for the compiler to optimize the iterators. * Use let-else in `ManifestVisitor` * Optimize `BinFile::preview_{bin, link}` for zero-copy Return `impl Display` that lazily format instead of allocating a `String` * Optimize `infer_bin_dir_template`: Generate dir lazily * Optimize `find_version`: Lazily clone `version_req` only on err * Refactor `find_version`: Use `bool::then_some` * Add dep either v1.8.0 to binstalk * Optimize `GhCrateMeta::find`: Avoid cloning and `Vec` creation by using `Either` * Optimize `ops::install::install_from_package`: Make it a regular fn instead of async fn since it does not `.await` on any async fn. * Optimize `QuickInstall`: Rm field `target` since `Arc<Data>` already contains that field. * Optimize `Fetcher`s: Extract new struct `TargetData` so that `Data` can be shared by all fetchers, regardless of the target. * Optimize `QuickInstall`: Rm unused field `data` * Optimize `Resolution::print`: Replace branching with conditional move Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
89 lines
2.6 KiB
Rust
89 lines
2.6 KiB
Rust
use std::{
|
|
io::{self, Read},
|
|
path::{Path, PathBuf},
|
|
};
|
|
|
|
use cargo_toml::Manifest;
|
|
use normalize_path::NormalizePath;
|
|
use tracing::debug;
|
|
|
|
use super::vfs::Vfs;
|
|
use crate::{
|
|
errors::BinstallError,
|
|
helpers::download::{DownloadError, Entries, TarEntriesVisitor},
|
|
manifests::cargo_toml_binstall::Meta,
|
|
};
|
|
|
|
#[derive(Debug)]
|
|
pub(super) struct ManifestVisitor {
|
|
cargo_toml_content: Vec<u8>,
|
|
/// manifest_dir_path is treated as the current dir.
|
|
manifest_dir_path: PathBuf,
|
|
|
|
vfs: Vfs,
|
|
}
|
|
|
|
impl ManifestVisitor {
|
|
pub(super) fn new(manifest_dir_path: PathBuf) -> Self {
|
|
Self {
|
|
// Cargo.toml is quite large usually.
|
|
cargo_toml_content: Vec::with_capacity(2000),
|
|
manifest_dir_path,
|
|
vfs: Vfs::default(),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TarEntriesVisitor for ManifestVisitor {
|
|
type Target = Manifest<Meta>;
|
|
|
|
fn visit<R: Read>(&mut self, entries: Entries<'_, R>) -> Result<(), DownloadError> {
|
|
for res in entries {
|
|
let mut entry = res?;
|
|
let path = entry.path()?;
|
|
let path = path.normalize();
|
|
|
|
let Ok(path) = path.strip_prefix(&self.manifest_dir_path)
|
|
else {
|
|
// The path is outside of the curr dir (manifest dir),
|
|
// ignore it.
|
|
continue;
|
|
};
|
|
|
|
if path == Path::new("Cargo.toml")
|
|
|| path == Path::new("src/main.rs")
|
|
|| path.starts_with("src/bin")
|
|
{
|
|
self.vfs.add_path(path);
|
|
}
|
|
|
|
if path == Path::new("Cargo.toml") {
|
|
// Since it is possible for the same Cargo.toml to appear
|
|
// multiple times using `tar --keep-old-files`, here we
|
|
// clear the buffer first before reading into it.
|
|
self.cargo_toml_content.clear();
|
|
entry.read_to_end(&mut self.cargo_toml_content)?;
|
|
}
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// Load binstall metadata using the extracted information stored in memory.
|
|
fn finish(self) -> Result<Self::Target, DownloadError> {
|
|
Ok(load_manifest(&self.cargo_toml_content, &self.vfs).map_err(io::Error::from)?)
|
|
}
|
|
}
|
|
|
|
fn load_manifest(slice: &[u8], vfs: &Vfs) -> Result<Manifest<Meta>, BinstallError> {
|
|
debug!("Loading manifest directly from extracted file");
|
|
|
|
// Load and parse manifest
|
|
let mut manifest = Manifest::from_slice_with_metadata(slice)?;
|
|
|
|
// Checks vfs for binary output names
|
|
manifest.complete_from_abstract_filesystem(vfs)?;
|
|
|
|
// Return metadata
|
|
Ok(manifest)
|
|
}
|