wasmer_wasix/runtime/resolver/
filesystem_source.rs

1use anyhow::Context;
2use wasmer_config::package::{PackageHash, PackageId, PackageSource};
3use wasmer_package::utils::from_disk;
4
5use crate::runtime::resolver::{
6    DistributionInfo, PackageInfo, PackageSummary, QueryError, Source, WebcHash,
7};
8
9/// A [`Source`] that knows how to query files on the filesystem.
10#[derive(Debug, Default, Clone, PartialEq, Eq)]
11pub struct FileSystemSource {}
12
13impl FileSystemSource {
14    async fn load_path(path: &std::path::Path) -> Result<Vec<PackageSummary>, anyhow::Error> {
15        let webc_sha256 = crate::block_in_place(|| WebcHash::for_file(path))
16            .with_context(|| format!("Unable to hash \"{}\"", path.display()))?;
17        let container = crate::block_in_place(|| from_disk(path))
18            .with_context(|| format!("Unable to parse \"{}\"", path.display()))?;
19
20        let url = crate::runtime::resolver::utils::url_from_file_path(path)
21            .ok_or_else(|| anyhow::anyhow!("Unable to turn \"{}\" into a URL", path.display()))?;
22
23        let id = PackageInfo::package_id_from_manifest(container.manifest())
24            .context("Unable to determine the package's ID")?
25            .unwrap_or_else(|| PackageId::from(PackageHash::from_sha256_bytes(webc_sha256.0)));
26
27        let pkg = PackageInfo::from_manifest(id, container.manifest(), container.version())
28            .context("Unable to determine the package's metadata")?;
29        let summary = PackageSummary {
30            pkg,
31            dist: DistributionInfo {
32                webc: url,
33                webc_sha256,
34            },
35        };
36
37        Ok(vec![summary])
38    }
39}
40
41#[async_trait::async_trait]
42impl Source for FileSystemSource {
43    #[tracing::instrument(level = "debug", skip_all, fields(%package))]
44    async fn query(&self, package: &PackageSource) -> Result<Vec<PackageSummary>, QueryError> {
45        let path = match package {
46            PackageSource::Path(path) => {
47                let path = std::path::PathBuf::from(path);
48                path.canonicalize()
49                    .with_context(|| {
50                        format!(
51                            "Unable to get the canonical form for \"{}\"",
52                            path.display()
53                        )
54                    })
55                    .map_err(|error| QueryError::new_other(error, package))?
56            }
57            _ => {
58                return Err(QueryError::Unsupported {
59                    query: package.clone(),
60                });
61            }
62        };
63
64        Self::load_path(&path)
65            .await
66            .map_err(|error| QueryError::new_other(error, package))
67    }
68}