diff --git a/Cargo.lock b/Cargo.lock index aecbcefcb47..963c662fe46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5723,7 +5723,7 @@ dependencies = [ "wasmer-emscripten", "wasmer-object", "wasmer-registry 5.6.0", - "wasmer-toml 0.6.0", + "wasmer-toml 0.8.0", "wasmer-types", "wasmer-vm", "wasmer-wasix", @@ -6056,7 +6056,7 @@ dependencies = [ "tokio", "toml 0.5.11", "url", - "wasmer-toml 0.6.0", + "wasmer-toml 0.8.0", "wasmer-wasm-interface 4.2.0", "wasmparser 0.51.4", "whoami", @@ -6136,9 +6136,9 @@ dependencies = [ [[package]] name = "wasmer-toml" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d79d9e87af8aea672134da379ccef76e659b7bc316a10b7e51d30177515c0199" +checksum = "e2d9ad139e1b613770613cf5952e95185e28b108120ddee14d88b4a004c7c94f" dependencies = [ "anyhow", "derive_builder", @@ -6572,9 +6572,9 @@ dependencies = [ [[package]] name = "webc" -version = "5.3.0" +version = "5.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5c35d27cb4c7898571b5f25036ead587736ffb371261f9e928a28edee7abf9d" +checksum = "4b56acc943f6b80cc2842231f34f99a02cd406896a23f3c6dacd8130c24ab3d1" dependencies = [ "anyhow", "base64", @@ -6599,7 +6599,7 @@ dependencies = [ "toml 0.7.8", "url", "walkdir", - "wasmer-toml 0.7.0", + "wasmer-toml 0.8.0", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c622b3d6c25..5d92a7c1694 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -84,8 +84,8 @@ rust-version = "1.70" version = "4.2.0" [workspace.dependencies] -webc = { version = "5.2.0", default-features = false, features = ["package"] } -wasmer-toml = "0.6.0" +webc = { version = "5.5.1", default-features = false, features = ["package"] } +wasmer-toml = "0.8.0" [build-dependencies] test-generator = { path = "tests/lib/test-generator" } diff --git a/lib/cli/src/commands/init.rs b/lib/cli/src/commands/init.rs index 393554833b4..ec6fc7f365b 100644 --- a/lib/cli/src/commands/init.rs +++ b/lib/cli/src/commands/init.rs @@ -7,6 +7,7 @@ use anyhow::Context; use cargo_metadata::{CargoOpt, MetadataCommand}; use clap::Parser; use indexmap::IndexMap; +use semver::VersionReq; use wasmer_registry::wasmer_env::WasmerEnv; static NOTE: &str = "# See more keys and definitions at https://docs.wasmer.io/registry/manifest"; @@ -152,21 +153,40 @@ impl Init { Self::write_wasmer_toml(&target_file, &constructed_manifest) } - /// Writes the metadata to a wasmer.toml file + /// Writes the metadata to a wasmer.toml file, making sure we include the + /// [`NOTE`] so people get a link to the registry docs. fn write_wasmer_toml( path: &PathBuf, toml: &wasmer_toml::Manifest, ) -> Result<(), anyhow::Error> { - let toml_string = toml::to_string_pretty(&toml)? - .replace( - "[dependencies]", - &format!("{NOTE}{NEWLINE}{NEWLINE}[dependencies]"), - ) - .lines() - .collect::>() - .join(NEWLINE); + let toml_string = toml::to_string_pretty(&toml)?; + + let mut resulting_string = String::new(); + let mut note_inserted = false; + + for line in toml_string.lines() { + resulting_string.push_str(line); + + if !note_inserted && line.is_empty() { + // We've found an empty line after the initial [package] + // section. Let's add our note here. + resulting_string.push_str(NEWLINE); + resulting_string.push_str(NOTE); + resulting_string.push_str(NEWLINE); + note_inserted = true; + } + resulting_string.push_str(NEWLINE); + } + + if !note_inserted { + // Make sure the note still ends up at the end of the file. + resulting_string.push_str(NEWLINE); + resulting_string.push_str(NOTE); + resulting_string.push_str(NEWLINE); + resulting_string.push_str(NEWLINE); + } - std::fs::write(path, toml_string) + std::fs::write(path, resulting_string) .with_context(|| format!("Unable to write to \"{}\"", path.display()))?; Ok(()) @@ -210,60 +230,58 @@ impl Init { } } - fn get_filesystem_mapping(include: &[String]) -> Option> { + fn get_filesystem_mapping(include: &[String]) -> IndexMap { if include.is_empty() { - return None; + return IndexMap::new(); } - Some( - include - .iter() - .map(|path| { - if path == "." || path == "/" { - return ("/".to_string(), Path::new("/").to_path_buf()); - } + include + .iter() + .map(|path| { + if path == "." || path == "/" { + return ("/".to_string(), Path::new("/").to_path_buf()); + } - let key = format!("./{path}"); - let value = PathBuf::from(format!("/{path}")); + let key = format!("./{path}"); + let value = PathBuf::from(format!("/{path}")); - (key, value) - }) - .collect(), - ) + (key, value) + }) + .collect() } fn get_command( modules: &[wasmer_toml::Module], bin_or_lib: BinOrLib, - ) -> Option> { + ) -> Vec { match bin_or_lib { - BinOrLib::Bin => Some( - modules - .iter() - .map(|m| { - wasmer_toml::Command::V1(wasmer_toml::CommandV1 { - name: m.name.clone(), + BinOrLib::Bin => modules + .iter() + .map(|m| { + wasmer_toml::Command::V1(wasmer_toml::CommandV1 { + name: m.name.clone(), + module: wasmer_toml::ModuleReference::CurrentPackage { module: m.name.clone(), - main_args: None, - package: None, - }) + }, + main_args: None, + package: None, }) - .collect(), - ), - BinOrLib::Lib | BinOrLib::Empty => None, + }) + .collect(), + BinOrLib::Lib | BinOrLib::Empty => Vec::new(), } } /// Returns the dependencies based on the `--template` flag - fn get_dependencies(template: Option<&Template>) -> HashMap { + fn get_dependencies(template: Option<&Template>) -> HashMap { let mut map = HashMap::default(); match template { Some(Template::Js) => { - map.insert("quickjs".to_string(), "quickjs/quickjs@latest".to_string()); + map.insert("quickjs/quickjs".to_string(), VersionReq::STAR); } Some(Template::Python) => { - map.insert("python".to_string(), "python/python@latest".to_string()); + map.insert("python/python".to_string(), VersionReq::STAR); } _ => {} } @@ -466,36 +484,47 @@ fn construct_manifest( }), }]; - Ok(wasmer_toml::Manifest { - package: wasmer_toml::Package { - name: if let Some(s) = namespace { - format!("{s}/{package_name}") - } else { - package_name.to_string() - }, - version, - description, - license, - license_file, - readme, - repository, - homepage, - wasmer_extra_flags: None, - disable_command_rename: false, - rename_commands_to_raw_command_name: false, - }, - dependencies: Some(Init::get_dependencies(template)), - command: Init::get_command(&modules, bin_or_lib), - module: match bin_or_lib { - BinOrLib::Empty => None, - _ => Some(modules), + let mut pkg = wasmer_toml::Package::builder( + if let Some(s) = namespace { + format!("{s}/{package_name}") + } else { + package_name.to_string() }, - fs: Init::get_filesystem_mapping(include_fs), - base_directory_path: target_file - .parent() - .map(|o| o.to_path_buf()) - .unwrap_or_else(|| target_file.to_path_buf()), - }) + version, + description, + ); + + if let Some(license) = license { + pkg.license(license); + } + if let Some(license_file) = license_file { + pkg.license_file(license_file); + } + if let Some(readme) = readme { + pkg.readme(readme); + } + if let Some(repository) = repository { + pkg.repository(repository); + } + if let Some(homepage) = homepage { + pkg.homepage(homepage); + } + let pkg = pkg.build()?; + + let mut manifest = wasmer_toml::Manifest::builder(pkg); + manifest + .dependencies(Init::get_dependencies(template)) + .commands(Init::get_command(&modules, bin_or_lib)) + .fs(Init::get_filesystem_mapping(include_fs)); + match bin_or_lib { + BinOrLib::Bin | BinOrLib::Lib => { + manifest.modules(modules); + } + BinOrLib::Empty => {} + } + let manifest = manifest.build()?; + + Ok(manifest) } fn parse_cargo_toml(manifest_path: &PathBuf) -> Result { let mut metadata = MetadataCommand::new(); diff --git a/lib/registry/Cargo.toml b/lib/registry/Cargo.toml index 83dfaa9bfb8..0900bb9a374 100644 --- a/lib/registry/Cargo.toml +++ b/lib/registry/Cargo.toml @@ -43,7 +43,7 @@ tldextract = "0.6.0" tokio = "1.24.0" toml = "0.5.9" url = "2.3.1" -wasmer-toml = "0.6.0" +wasmer-toml = { workspace = true } wasmer-wasm-interface = { version = "4.2.0", path = "../wasm-interface", optional = true } wasmparser = { version = "0.51.4", optional = true } whoami = "1.2.3" diff --git a/lib/registry/src/lib.rs b/lib/registry/src/lib.rs index 9015a320431..b40869285d0 100644 --- a/lib/registry/src/lib.rs +++ b/lib/registry/src/lib.rs @@ -180,8 +180,7 @@ pub fn query_package_from_registry( manifest: v.manifest.clone(), commands: manifest - .command - .unwrap_or_default() + .commands .iter() .map(|s| s.get_name()) .collect::>() diff --git a/lib/registry/src/package/builder.rs b/lib/registry/src/package/builder.rs index c9fbc84bab0..5b6a1c8fa63 100644 --- a/lib/registry/src/package/builder.rs +++ b/lib/registry/src/package/builder.rs @@ -106,7 +106,6 @@ impl Publish { .parent() .context("could not determine manifest parent directory")? .to_owned(); - manifest.base_directory_path = manifest_dir.to_owned(); if let Some(package_name) = self.package_name.as_ref() { manifest.package.name = package_name.to_string(); @@ -208,15 +207,14 @@ fn construct_tar_gz( let manifest_string = toml::to_string(&manifest)?; let package = &manifest.package; - let modules = manifest.module.as_deref().unwrap_or_default(); + let modules = &manifest.modules; let readme = match package.readme.as_ref() { None => None, Some(s) => { - let path = append_path_to_tar_gz(&mut builder, &manifest.base_directory_path, s) - .map_err(|(p, e)| { - PackageBuildError::ErrorBuildingPackage(format!("{}", p.display()), e) - })?; + let path = append_path_to_tar_gz(&mut builder, manifest_dir, s).map_err(|(p, e)| { + PackageBuildError::ErrorBuildingPackage(format!("{}", p.display()), e) + })?; Some(std::fs::read_to_string(path)?) } }; @@ -224,24 +222,24 @@ fn construct_tar_gz( let license = match package.license_file.as_ref() { None => None, Some(s) => { - let path = append_path_to_tar_gz(&mut builder, &manifest.base_directory_path, s) - .map_err(|(p, e)| { - PackageBuildError::ErrorBuildingPackage(format!("{}", p.display()), e) - })?; + let path = append_path_to_tar_gz(&mut builder, manifest_dir, s).map_err(|(p, e)| { + PackageBuildError::ErrorBuildingPackage(format!("{}", p.display()), e) + })?; Some(std::fs::read_to_string(path)?) } }; for module in modules { - append_path_to_tar_gz(&mut builder, &manifest.base_directory_path, &module.source) - .map_err(|(normalized_path, _)| PackageBuildError::SourceMustBeFile { + append_path_to_tar_gz(&mut builder, manifest_dir, &module.source).map_err( + |(normalized_path, _)| PackageBuildError::SourceMustBeFile { module: module.name.clone(), path: normalized_path, - })?; + }, + )?; if let Some(bindings) = &module.bindings { - for path in bindings.referenced_files(&manifest.base_directory_path)? { - append_path_to_tar_gz(&mut builder, &manifest.base_directory_path, &path).map_err( + for path in bindings.referenced_files(manifest_dir)? { + append_path_to_tar_gz(&mut builder, manifest_dir, &path).map_err( |(normalized_path, _)| PackageBuildError::MissingBindings { module: module.name.clone(), path: normalized_path, @@ -252,8 +250,7 @@ fn construct_tar_gz( } // bundle the package filesystem - let default = indexmap::IndexMap::default(); - for (_alias, path) in manifest.fs.as_ref().unwrap_or(&default).iter() { + for (_alias, path) in &manifest.fs { let normalized_path = normalize_path(manifest_dir, path); let path_metadata = normalized_path.metadata().map_err(|_| { PackageBuildError::MissingManifestFsPath(normalized_path.to_string_lossy().to_string()) @@ -459,7 +456,7 @@ pub struct PersonalKey { fn get_active_personal_key(conn: &Connection) -> anyhow::Result { let mut stmt = conn.prepare( - "SELECT active, public_key_value, private_key_location, date_added, key_type_identifier, public_key_id FROM personal_keys + "SELECT active, public_key_value, private_key_location, date_added, key_type_identifier, public_key_id FROM personal_keys where active = 1", )?; @@ -585,78 +582,70 @@ mod validate { pkg_path: PathBuf, ) -> anyhow::Result<()> { // validate as dir - if let Some(modules) = manifest.module.as_ref() { - for module in modules.iter() { - let source_path = if module.source.is_relative() { - manifest.base_directory_path.join(&module.source) - } else { - module.source.clone() - }; - let source_path_string = source_path.to_string_lossy().to_string(); - let mut wasm_file = - fs::File::open(&source_path).map_err(|_| ValidationError::MissingFile { - file: source_path_string.clone(), - })?; - let mut wasm_buffer = Vec::new(); - wasm_file.read_to_end(&mut wasm_buffer).map_err(|err| { - ValidationError::MiscCannotRead { - file: source_path_string.clone(), - error: format!("{}", err), - } + for module in manifest.modules.iter() { + let source_path = if module.source.is_relative() { + pkg_path.join(&module.source) + } else { + module.source.clone() + }; + let source_path_string = source_path.to_string_lossy().to_string(); + let mut wasm_file = + fs::File::open(&source_path).map_err(|_| ValidationError::MissingFile { + file: source_path_string.clone(), })?; - - if let Some(bindings) = &module.bindings { - validate_bindings(bindings, &manifest.base_directory_path)?; + let mut wasm_buffer = Vec::new(); + wasm_file.read_to_end(&mut wasm_buffer).map_err(|err| { + ValidationError::MiscCannotRead { + file: source_path_string.clone(), + error: format!("{}", err), } + })?; - // hack, short circuit if no interface for now - if module.interfaces.is_none() { - return validate_wasm_and_report_errors_old( - &wasm_buffer[..], - source_path_string, - ); - } + if let Some(bindings) = &module.bindings { + validate_bindings(bindings, &pkg_path)?; + } - let mut conn = super::open_db()?; - let mut interface: Interface = Default::default(); - for (interface_name, interface_version) in - module.interfaces.clone().unwrap_or_default().into_iter() - { - if !interfaces::interface_exists( - &mut conn, - &interface_name, - &interface_version, - )? { - // download interface and store it if we don't have it locally - let interface_data_from_server = InterfaceFromServer::get( - registry, - interface_name.clone(), - interface_version.clone(), - )?; - interfaces::import_interface( - &mut conn, - &interface_name, - &interface_version, - &interface_data_from_server.content, - )?; - } - let sub_interface = interfaces::load_interface_from_db( + // hack, short circuit if no interface for now + if module.interfaces.is_none() { + return validate_wasm_and_report_errors_old(&wasm_buffer[..], source_path_string); + } + + let mut conn = super::open_db()?; + let mut interface: Interface = Default::default(); + for (interface_name, interface_version) in + module.interfaces.clone().unwrap_or_default().into_iter() + { + if !interfaces::interface_exists(&mut conn, &interface_name, &interface_version)? { + // download interface and store it if we don't have it locally + let interface_data_from_server = InterfaceFromServer::get( + registry, + interface_name.clone(), + interface_version.clone(), + )?; + interfaces::import_interface( &mut conn, &interface_name, &interface_version, + &interface_data_from_server.content, )?; - interface = interface.merge(sub_interface).map_err(|e| { - anyhow!("Failed to merge interface {}: {}", &interface_name, e) - })?; } - validate::validate_wasm_and_report_errors(&wasm_buffer, &interface).map_err( - |e| ValidationError::InvalidWasm { - file: source_path_string, - error: format!("{:?}", e), - }, + let sub_interface = interfaces::load_interface_from_db( + &mut conn, + &interface_name, + &interface_version, )?; + interface = interface + .merge(sub_interface) + .map_err(|e| anyhow!("Failed to merge interface {}: {}", &interface_name, e))?; } + validate::validate_wasm_and_report_errors(&wasm_buffer, &interface).map_err(|e| { + ValidationError::InvalidWasm { + file: source_path_string, + error: format!("{:?}", e), + } + })?; } + log::debug!("package at path {:#?} validated", &pkg_path); Ok(()) @@ -753,8 +742,7 @@ runner = "https://webc.org/runner/wcgi" std::fs::write(&manifest_path, manifest_str).unwrap(); std::fs::write(mp.join("module.wasm"), "()").unwrap(); - let mut manifest = wasmer_toml::Manifest::parse(&manifest_str).unwrap(); - manifest.base_directory_path = manifest_dir.path().to_owned(); + let manifest = wasmer_toml::Manifest::parse(&manifest_str).unwrap(); let meta = construct_tar_gz(&archive_dir.path(), &manifest, &manifest_path).unwrap(); diff --git a/lib/wasi-web/Cargo.lock b/lib/wasi-web/Cargo.lock index 65019adefea..dd020953054 100644 --- a/lib/wasi-web/Cargo.lock +++ b/lib/wasi-web/Cargo.lock @@ -2500,9 +2500,9 @@ dependencies = [ [[package]] name = "wasmer-toml" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d79d9e87af8aea672134da379ccef76e659b7bc316a10b7e51d30177515c0199" +checksum = "e2d9ad139e1b613770613cf5952e95185e28b108120ddee14d88b4a004c7c94f" dependencies = [ "anyhow", "derive_builder", @@ -2727,9 +2727,9 @@ dependencies = [ [[package]] name = "webc" -version = "5.3.0" +version = "5.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5c35d27cb4c7898571b5f25036ead587736ffb371261f9e928a28edee7abf9d" +checksum = "4b56acc943f6b80cc2842231f34f99a02cd406896a23f3c6dacd8130c24ab3d1" dependencies = [ "anyhow", "base64 0.21.4", diff --git a/lib/wasix/src/runtime/package_loader/load_package_tree.rs b/lib/wasix/src/runtime/package_loader/load_package_tree.rs index 969461e0a4d..b92337c8845 100644 --- a/lib/wasix/src/runtime/package_loader/load_package_tree.rs +++ b/lib/wasix/src/runtime/package_loader/load_package_tree.rs @@ -8,8 +8,12 @@ use std::{ use anyhow::{Context, Error}; use futures::{future::BoxFuture, StreamExt, TryStreamExt}; use once_cell::sync::OnceCell; +use petgraph::visit::EdgeRef; use virtual_fs::{FileSystem, OverlayFileSystem, WebcVolumeFileSystem}; -use webc::compat::{Container, Volume}; +use webc::{ + compat::{Container, Volume}, + metadata::annotations::Atom as AtomAnnotation, +}; use crate::{ bin_factory::{BinaryPackage, BinaryPackageCommand}, @@ -37,7 +41,8 @@ pub async fn load_package_tree( let fs = filesystem(&containers, &resolution.package)?; let root = &resolution.package.root_package; - let commands: Vec = commands(&resolution.package.commands, &containers)?; + let commands: Vec = + commands(&resolution.package.commands, &containers, resolution)?; let file_system_memory_footprint = count_file_system(&fs, Path::new("/")); let atoms_in_use: HashSet<_> = commands.iter().map(|cmd| cmd.atom()).collect(); @@ -69,6 +74,7 @@ pub async fn load_package_tree( fn commands( commands: &BTreeMap, containers: &HashMap, + resolution: &Resolution, ) -> Result, Error> { let mut pkg_commands = Vec::new(); @@ -84,7 +90,9 @@ fn commands( let manifest = webc.manifest(); let command_metadata = &manifest.commands[original_name]; - if let Some(cmd) = load_binary_command(webc, name, command_metadata)? { + if let Some(cmd) = + load_binary_command(package, name, command_metadata, containers, resolution)? + { pkg_commands.push(cmd); } } @@ -92,16 +100,24 @@ fn commands( Ok(pkg_commands) } +/// Given a [`webc::metadata::Command`], figure out which atom it uses and load +/// that atom into a [`BinaryPackageCommand`]. fn load_binary_command( - webc: &Container, - name: &str, + package_id: &PackageId, + command_name: &str, cmd: &webc::metadata::Command, + containers: &HashMap, + resolution: &Resolution, ) -> Result, anyhow::Error> { - let atom_name = match atom_name_for_command(name, cmd)? { + let AtomAnnotation { + name: atom_name, + dependency, + .. + } = match atom_name_for_command(command_name, cmd)? { Some(name) => name, None => { tracing::warn!( - cmd.name=name, + cmd.name=command_name, cmd.runner=%cmd.runner, "Skipping unsupported command", ); @@ -109,16 +125,41 @@ fn load_binary_command( } }; + let package = &containers[package_id]; + + let webc = match dependency { + Some(dep) => { + let ix = resolution + .graph + .packages() + .get(package_id) + .copied() + .unwrap(); + let graph = resolution.graph.graph(); + let edge_reference = graph + .edges_directed(ix, petgraph::Direction::Outgoing) + .find(|edge| edge.weight().alias == dep) + .with_context(|| format!("Unable to find the \"{dep}\" dependency for the \"{command_name}\" command in \"{package_id}\""))?; + + let other_package = graph.node_weight(edge_reference.target()).unwrap(); + &containers[&other_package.id] + } + None => package, + }; + let atom = webc.get_atom(&atom_name); if atom.is_none() && cmd.annotations.is_empty() { - return Ok(legacy_atom_hack(webc, name, cmd)); + return Ok(legacy_atom_hack(webc, command_name, cmd)); } - let atom = atom - .with_context(|| format!("The '{name}' command uses the '{atom_name}' atom, but it isn't present in the WEBC file"))?; + let atom = atom.with_context(|| { + format!( + "The '{command_name}' command uses the '{atom_name}' atom, but it isn't present in the WEBC file" + ) + })?; - let cmd = BinaryPackageCommand::new(name.to_string(), cmd.clone(), atom); + let cmd = BinaryPackageCommand::new(command_name.to_string(), cmd.clone(), atom); Ok(Some(cmd)) } @@ -126,28 +167,12 @@ fn load_binary_command( fn atom_name_for_command( command_name: &str, cmd: &webc::metadata::Command, -) -> Result, anyhow::Error> { - use webc::metadata::annotations::{ - Emscripten, Wasi, EMSCRIPTEN_RUNNER_URI, WASI_RUNNER_URI, WCGI_RUNNER_URI, - }; - - // FIXME: command metadata should include an "atom: Option" field - // because it's so common, rather than relying on each runner to include - // annotations where "atom" just so happens to contain the atom's name - // (like in Wasi and Emscripten) - - if let Some(Wasi { atom, .. }) = cmd - .annotation("wasi") - .context("Unable to deserialize 'wasi' annotations")? - { - return Ok(Some(atom)); - } +) -> Result, anyhow::Error> { + use webc::metadata::annotations::{EMSCRIPTEN_RUNNER_URI, WASI_RUNNER_URI, WCGI_RUNNER_URI}; - if let Some(Emscripten { - atom: Some(atom), .. - }) = cmd - .annotation("emscripten") - .context("Unable to deserialize 'emscripten' annotations")? + if let Some(atom) = cmd + .atom() + .context("Unable to deserialize atom annotations")? { return Ok(Some(atom)); } @@ -163,7 +188,7 @@ fn atom_name_for_command( command = command_name, "No annotations specifying the atom name found. Falling back to the command name" ); - return Ok(Some(command_name.to_string())); + return Ok(Some(AtomAnnotation::new(command_name, None))); } Ok(None) diff --git a/tests/integration/cli/tests/fixtures/init1.toml b/tests/integration/cli/tests/fixtures/init1.toml index a9bade5da3c..517a1201f9a 100644 --- a/tests/integration/cli/tests/fixtures/init1.toml +++ b/tests/integration/cli/tests/fixtures/init1.toml @@ -5,8 +5,6 @@ description = 'Description for package testfirstproject' # See more keys and definitions at https://docs.wasmer.io/registry/manifest -[dependencies] - [[module]] name = 'testfirstproject' source = 'testfirstproject.wasm' @@ -17,4 +15,4 @@ wasi = '0.1.0-unstable' [[command]] name = 'testfirstproject' -module = 'testfirstproject' \ No newline at end of file +module = 'testfirstproject' diff --git a/tests/integration/cli/tests/fixtures/init4.toml b/tests/integration/cli/tests/fixtures/init4.toml index 8bcc40fe294..a3e5cb93bc8 100644 --- a/tests/integration/cli/tests/fixtures/init4.toml +++ b/tests/integration/cli/tests/fixtures/init4.toml @@ -5,8 +5,6 @@ description = 'Description for package wasmer' # See more keys and definitions at https://docs.wasmer.io/registry/manifest -[dependencies] - [[module]] name = 'wasmer' source = 'target/wasm32-wasi/release/wasmer.wasm' @@ -17,4 +15,4 @@ wasi = '0.1.0-unstable' [[command]] name = 'wasmer' -module = 'wasmer' \ No newline at end of file +module = 'wasmer' diff --git a/tests/integration/cli/tests/init.rs b/tests/integration/cli/tests/init.rs index 3413f5b998d..eb9c14b407b 100644 --- a/tests/integration/cli/tests/init.rs +++ b/tests/integration/cli/tests/init.rs @@ -9,37 +9,15 @@ use wasmer_integration_tests_cli::get_wasmer_path; // Test that wasmer init without arguments works #[test] -fn wasmer_init_works_1() -> anyhow::Result<()> { - let wasmer_dir = TempDir::new()?; - let tempdir = tempfile::tempdir()?; +fn wasmer_init_works_1() { + let wasmer_dir = TempDir::new().unwrap(); + let tempdir = tempfile::tempdir().unwrap(); let path = tempdir.path().join("testfirstproject"); - std::fs::create_dir_all(&path)?; - - if std::env::var("GITHUB_TOKEN").is_err() { - return Ok(()); - } - - let wapm_dev_token = std::env::var("WAPM_DEV_TOKEN").ok(); - println!("wapm dev token ok..."); - - if let Some(token) = wapm_dev_token { - // Special case: GitHub secrets aren't visible to outside collaborators - if token.is_empty() { - return Ok(()); - } - Command::new(get_wasmer_path()) - .arg("login") - .arg("--registry=wapm.dev") - .arg(token) - .env("WASMER_DIR", wasmer_dir.path()) - .assert() - .success(); - } - - println!("wasmer login ok!"); + std::fs::create_dir_all(&path).unwrap(); Command::new(get_wasmer_path()) .arg("init") + .arg("--namespace=ciuser") .current_dir(&path) .env("WASMER_DIR", wasmer_dir.path()) .assert() @@ -49,47 +27,25 @@ fn wasmer_init_works_1() -> anyhow::Result<()> { std::fs::read_to_string(path.join("wasmer.toml")).unwrap(), include_str!("./fixtures/init1.toml"), ); - - Ok(()) } #[test] -fn wasmer_init_works_2() -> anyhow::Result<()> { - let tempdir = tempfile::tempdir()?; +fn wasmer_init_works_2() { + let tempdir = tempfile::tempdir().unwrap(); let path = tempdir.path(); let path = path.join("testfirstproject"); - std::fs::create_dir_all(&path)?; + std::fs::create_dir_all(&path).unwrap(); std::fs::write( path.join("Cargo.toml"), include_bytes!("./fixtures/init2.toml"), - )?; - std::fs::create_dir_all(path.join("src"))?; - std::fs::write(path.join("src").join("main.rs"), b"fn main() { }")?; - - if std::env::var("GITHUB_TOKEN").is_err() { - return Ok(()); - } - - let wapm_dev_token = std::env::var("WAPM_DEV_TOKEN").ok(); - println!("wapm dev token ok..."); - - if let Some(token) = wapm_dev_token.as_ref() { - // Special case: GitHub secrets aren't visible to outside collaborators - if token.is_empty() { - return Ok(()); - } - Command::new(get_wasmer_path()) - .arg("login") - .arg("--registry=wapm.dev") - .arg(token) - .assert() - .success(); - } - - println!("wasmer login ok!"); + ) + .unwrap(); + std::fs::create_dir_all(path.join("src")).unwrap(); + std::fs::write(path.join("src").join("main.rs"), b"fn main() { }").unwrap(); Command::new(get_wasmer_path()) .arg("init") + .arg("--namespace=ciuser") .current_dir(&path) .assert() .success(); @@ -98,13 +54,8 @@ fn wasmer_init_works_2() -> anyhow::Result<()> { std::fs::read_to_string(path.join("Cargo.toml")).unwrap(), include_str!("./fixtures/init2.toml") ); - - println!("ok 1"); - assert_eq!( std::fs::read_to_string(path.join("wasmer.toml")).unwrap(), include_str!("./fixtures/init4.toml") ); - - Ok(()) } diff --git a/tests/integration/cli/tests/packages/js-script/src/index.js b/tests/integration/cli/tests/packages/js-script/src/index.js new file mode 100644 index 00000000000..184dfcc9987 --- /dev/null +++ b/tests/integration/cli/tests/packages/js-script/src/index.js @@ -0,0 +1 @@ +console.log("Hello, World!"); diff --git a/tests/integration/cli/tests/packages/js-script/wasmer.toml b/tests/integration/cli/tests/packages/js-script/wasmer.toml new file mode 100644 index 00000000000..4aa82757b89 --- /dev/null +++ b/tests/integration/cli/tests/packages/js-script/wasmer.toml @@ -0,0 +1,18 @@ +[package] +name = "wasmer/js-script" +version = "0.0.0" +description = "A package which uses quickjs to run a JavaScript program" + +[dependencies] +"saghul/quickjs" = "0.0.3" + +[[command]] +name = "main" +module = "saghul/quickjs:quickjs" +runner = "wasi" + +[command.annotations.wasi] +main-args = ["/src/index.js"] + +[fs] +"/src" = "./src" diff --git a/tests/integration/cli/tests/run.rs b/tests/integration/cli/tests/run.rs index 616c32af455..63762b095dc 100644 --- a/tests/integration/cli/tests/run.rs +++ b/tests/integration/cli/tests/run.rs @@ -885,6 +885,33 @@ fn run_bash_using_coreutils() { assert.success().stdout(contains(some_expected_binaries)); } +#[test] +fn run_a_package_that_uses_an_atom_from_a_dependency() { + let js_script_dir = project_root() + .join("tests") + .join("integration") + .join("cli") + .join("tests") + .join("packages") + .join("js-script"); + + let assert = Command::new(get_wasmer_path()) + .arg("run") + .arg(&js_script_dir) + .arg("--registry=wasmer.io") + .env("RUST_LOG", &*RUST_LOG) + .assert(); + + assert.success().stdout(contains("Hello, World!")); +} + +fn project_root() -> &'static Path { + Path::new(env!("CARGO_MANIFEST_DIR")) + .ancestors() + .nth(3) + .unwrap() +} + /// A helper that wraps [`Child`] to make sure it gets terminated /// when it is no longer needed. struct JoinableChild {