cargo-binstall/crates/binstalk/src/drivers/crates_io/visitor.rs
dependabot[bot] 287ae03a51
Bump cargo_toml from 0.13.0 to 0.14.0 (#632)
* 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>
2022-12-28 04:16:24 +00:00

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)
}