Impl new type `ManifestVisitor

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
Jiahao XU 2022-06-12 16:31:47 +10:00
parent 44d43113f4
commit f3d3c488e3
No known key found for this signature in database
GPG key ID: 591C0B03040416D6
2 changed files with 83 additions and 0 deletions

View file

@ -10,6 +10,9 @@ use version::find_version;
mod vfs;
mod visitor;
pub use visitor::*;
/// Fetch a crate by name and version from github
/// TODO: implement this
pub async fn fetch_crate_gh_releases(

80
src/drivers/visitor.rs Normal file
View file

@ -0,0 +1,80 @@
use std::io::Read;
use std::path::{Path, PathBuf};
use cargo_toml::Manifest;
use log::debug;
use tar::Entries;
use super::vfs::Vfs;
use crate::{
helpers::{PathExt, TarEntriesVisitor},
BinstallError, Meta,
};
#[derive(Debug)]
pub 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::new(),
}
}
/// Load binstall metadata using the extracted information stored in memory.
pub fn load_manifest(&self) -> Result<Manifest<Meta>, BinstallError> {
debug!("Loading manifest directly from extracted file");
// Load and parse manifest
let mut manifest = Manifest::<Meta>::from_slice_with_metadata(&self.cargo_toml_content)?;
// Checks vfs for binary output names
manifest.complete_from_abstract_filesystem(&self.vfs)?;
// Return metadata
Ok(manifest)
}
}
impl TarEntriesVisitor for ManifestVisitor {
fn visit<R: Read>(&mut self, entries: Entries<'_, R>) -> Result<(), BinstallError> {
for res in entries {
let mut entry = res?;
let path = entry.path()?.normalize_path();
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.
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(())
}
}