diff --git a/Cargo.lock b/Cargo.lock index e4e5e2983..f3500ed5f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3858,6 +3858,7 @@ dependencies = [ "target-lexicon 0.12.4", "tempfile", "unix_mode", + "wapm-toml", "wasmer", "wasmer-cache", "wasmer-compiler", diff --git a/lib/cli/Cargo.toml b/lib/cli/Cargo.toml index 0f8ffc76a..b9da5c2e2 100644 --- a/lib/cli/Cargo.toml +++ b/lib/cli/Cargo.toml @@ -59,6 +59,7 @@ dirs = { version = "4.0", optional = true } serde_json = { version = "1.0", optional = true } target-lexicon = { version = "0.12", features = ["std"] } prettytable-rs = "0.9.0" +wapm-toml = "0.1.1" [build-dependencies] chrono = "0.4.22" diff --git a/lib/cli/src/cli.rs b/lib/cli/src/cli.rs index 014c69d58..255646e77 100644 --- a/lib/cli/src/cli.rs +++ b/lib/cli/src/cli.rs @@ -253,7 +253,7 @@ fn parse_cli_args() -> Result<(), anyhow::Error> { let mut args_without_package = args.clone(); args_without_package.remove(1); return RunWithoutFile::try_parse_from(args_without_package.iter())? - .into_run_args(package.path) + .into_run_args(package.path, Some(package.manifest.clone())) .execute(); } @@ -270,12 +270,12 @@ fn parse_cli_args() -> Result<(), anyhow::Error> { sp.close(); print!("\r\n"); match result { - Ok(o) => { + Ok((package, buf)) => { // Try auto-installing the remote package let mut args_without_package = args.clone(); args_without_package.remove(1); return RunWithoutFile::try_parse_from(args_without_package.iter())? - .into_run_args(o) + .into_run_args(buf, Some(package.manifest.clone())) .execute(); } Err(e) => { diff --git a/lib/cli/src/commands/run.rs b/lib/cli/src/commands/run.rs index 5ffabe9dc..8cb700dfc 100644 --- a/lib/cli/src/commands/run.rs +++ b/lib/cli/src/commands/run.rs @@ -75,7 +75,30 @@ pub struct RunWithoutFile { impl RunWithoutFile { /// Given a local path, returns the `Run` command (overriding the `--path` argument). - pub fn into_run_args(self, pathbuf: PathBuf) -> Run { + pub fn into_run_args(mut self, pathbuf: PathBuf, manifest: Option) -> Run { + + #[cfg(feature = "wasi")] + if let Some(fs) = manifest.as_ref().and_then(|m| m.fs.as_ref()) { + for (alias, real_dir) in fs.iter() { + let real_dir = if let Some(parent) = pathbuf.parent() { + parent.join(real_dir) + } else { + pathbuf.join(real_dir) + }; + if !real_dir.exists() { + println!("warning: cannot map {alias:?} to {}: directory does not exist", real_dir.display()); + continue; + } + println!("mapping {alias:?} -> {}", real_dir.display()); + self.wasi.map_dir(alias, real_dir.clone()); + + #[cfg(feature = "wasi")] { + println!("setting PYTHONHOME to /{}", real_dir.display()); + self.wasi.set_env("PYTHONHOME", &format!("{}", real_dir.display())); + } + } + } + Run { #[cfg(feature = "cache")] disable_cache: self.disable_cache, diff --git a/lib/cli/src/commands/run/wasi.rs b/lib/cli/src/commands/run/wasi.rs index 37c64473a..7fa3d0203 100644 --- a/lib/cli/src/commands/run/wasi.rs +++ b/lib/cli/src/commands/run/wasi.rs @@ -52,6 +52,16 @@ pub struct Wasi { #[allow(dead_code)] impl Wasi { + + pub fn map_dir(&mut self, alias: &str, target_on_disk: PathBuf) { + self.mapped_dirs.push((alias.to_string(), target_on_disk)); + self.pre_opened_directories.push(std::path::Path::new(alias).to_path_buf()); + } + + pub fn set_env(&mut self, key: &str, value: &str) { + self.env_vars.push((key.to_string(), value.to_string())); + } + /// Gets the WASI version (if any) for the provided module pub fn get_versions(module: &Module) -> Option> { // Get the wasi version in strict mode, so no other imports are diff --git a/lib/registry/src/lib.rs b/lib/registry/src/lib.rs index a2dc54665..d2c27d163 100644 --- a/lib/registry/src/lib.rs +++ b/lib/registry/src/lib.rs @@ -730,7 +730,7 @@ pub fn download_and_unpack_targz(url: &str, target_path: &Path) -> Result) -> Result { +pub fn install_package(name: &str, version: Option<&str>) -> Result<(LocalPackage, PathBuf), String> { let registries = get_all_available_registries()?; let mut url_of_package = None; let mut error_packages = Vec::new(); @@ -817,13 +817,13 @@ pub fn install_package(name: &str, version: Option<&str>) -> Result(&wapm_toml) .map_err(|e| format!("Could not parse toml for {name}@{version}: {e}"))?; - let commands = wapm_toml.command.unwrap_or_default(); + let commands = wapm_toml.command.clone().unwrap_or_default(); let entrypoint_module = commands.first().ok_or(format!( "Cannot run {name}@{version}: package has no commands" ))?; let module_name = entrypoint_module.get_module(); - let modules = wapm_toml.module.unwrap_or_default(); + let modules = wapm_toml.module.clone().unwrap_or_default(); let entrypoint_module = modules .iter() .filter(|m| m.name == module_name) @@ -832,7 +832,13 @@ pub fn install_package(name: &str, version: Option<&str>) -> Result Result {