use anyhow::Context;
use wasmer_config::package::{PackageHash, PackageId, PackageSource};
use wasmer_package::utils::from_disk;
use crate::runtime::resolver::{
DistributionInfo, PackageInfo, PackageSummary, QueryError, Source, WebcHash,
};
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct FileSystemSource {}
impl FileSystemSource {
async fn load_path(path: &std::path::Path) -> Result<Vec<PackageSummary>, anyhow::Error> {
let webc_sha256 = crate::block_in_place(|| WebcHash::for_file(path))
.with_context(|| format!("Unable to hash \"{}\"", path.display()))?;
let container = crate::block_in_place(|| from_disk(path))
.with_context(|| format!("Unable to parse \"{}\"", path.display()))?;
let url = crate::runtime::resolver::utils::url_from_file_path(path)
.ok_or_else(|| anyhow::anyhow!("Unable to turn \"{}\" into a URL", path.display()))?;
let id = PackageInfo::package_id_from_manifest(container.manifest())
.context("Unable to determine the package's ID")?
.unwrap_or_else(|| PackageId::from(PackageHash::from_sha256_bytes(webc_sha256.0)));
let pkg = PackageInfo::from_manifest(id, container.manifest(), container.version())
.context("Unable to determine the package's metadata")?;
let summary = PackageSummary {
pkg,
dist: DistributionInfo {
webc: url,
webc_sha256,
},
};
Ok(vec![summary])
}
}
#[async_trait::async_trait]
impl Source for FileSystemSource {
#[tracing::instrument(level = "debug", skip_all, fields(%package))]
async fn query(&self, package: &PackageSource) -> Result<Vec<PackageSummary>, QueryError> {
let path = match package {
PackageSource::Path(path) => {
let path = std::path::PathBuf::from(path);
path.canonicalize()
.with_context(|| {
format!(
"Unable to get the canonical form for \"{}\"",
path.display()
)
})
.map_err(|error| QueryError::new_other(error, package))?
}
_ => {
return Err(QueryError::Unsupported {
query: package.clone(),
})
}
};
Self::load_path(&path)
.await
.map_err(|error| QueryError::new_other(error, package))
}
}