mirror of
https://github.com/cargo-bins/cargo-binstall.git
synced 2025-04-21 13:08:42 +00:00
![dependabot[bot]](/assets/img/avatar_default.png)
* Bump cargo_toml from 0.13.0 to 0.14.0 Bumps [cargo_toml](https://gitlab.com/crates.rs/cargo_toml) from 0.13.0 to 0.14.0. - [Release notes](https://gitlab.com/crates.rs/cargo_toml/tags) - [Commits](https://gitlab.com/crates.rs/cargo_toml/commits/main) --- updated-dependencies: - dependency-name: cargo_toml dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * Fix use of `Manifest::complete_from_abstract_filesystem` Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com> Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jiahao XU <Jiahao_XU@outlook.com>
91 lines
2.6 KiB
Rust
91 lines
2.6 KiB
Rust
use std::{
|
|
io,
|
|
path::{Path, PathBuf},
|
|
};
|
|
|
|
use cargo_toml::{Manifest, Value};
|
|
use normalize_path::NormalizePath;
|
|
use tokio::io::AsyncReadExt;
|
|
use tracing::debug;
|
|
|
|
use super::vfs::Vfs;
|
|
use crate::{
|
|
errors::BinstallError,
|
|
helpers::download::{DownloadError, TarEntriesVisitor, TarEntry},
|
|
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(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[async_trait::async_trait]
|
|
impl TarEntriesVisitor for ManifestVisitor {
|
|
type Target = Manifest<Meta>;
|
|
|
|
async fn visit(&mut self, entry: &mut dyn TarEntry) -> Result<(), DownloadError> {
|
|
let path = entry.path()?;
|
|
let path = path.normalize();
|
|
|
|
let path = if let Ok(path) = path.strip_prefix(&self.manifest_dir_path) {
|
|
path
|
|
} else {
|
|
// The path is outside of the curr dir (manifest dir),
|
|
// ignore it.
|
|
return Ok(());
|
|
};
|
|
|
|
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();
|
|
self.cargo_toml_content
|
|
.reserve_exact(entry.size()?.try_into().unwrap_or(usize::MAX));
|
|
entry.read_to_end(&mut self.cargo_toml_content).await?;
|
|
}
|
|
|
|
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::<Value, _>(vfs, None)?;
|
|
|
|
// Return metadata
|
|
Ok(manifest)
|
|
}
|