diff --git a/src/lib.rs b/src/lib.rs index affde0ca..c81a2406 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -970,14 +970,8 @@ fn componentize( })? .validate(true); - let mut producers = wasm_metadata::Producers::empty(); - producers.add( - "processed-by", - env!("CARGO_PKG_NAME"), - option_env!("CARGO_VERSION_INFO").unwrap_or(env!("CARGO_PKG_VERSION")), - ); - - let component = producers.add_to_wasm(&encoder.encode()?).with_context(|| { + let package = &cargo_metadata[&artifact.package_id]; + let component = add_component_metadata(&package, &encoder.encode()?).with_context(|| { format!( "failed to add metadata to output component `{path}`", path = path.display() @@ -1026,8 +1020,46 @@ pub struct PublishOptions<'a> { pub dry_run: bool, } -fn add_registry_metadata(_package: &Package, bytes: &[u8], _path: &Path) -> Result> { - Ok(bytes.to_owned()) +/// Read metadata from `Cargo.toml` and add it to the component +fn add_component_metadata(package: &Package, wasm: &[u8]) -> Result> { + let metadata = wasm_metadata::AddMetadata { + name: Some(package.name.clone()), + language: vec![("Rust".to_string(), "".to_string())], + processed_by: vec![( + env!("CARGO_PKG_NAME").to_string(), + option_env!("CARGO_VERSION_INFO") + .unwrap_or(env!("CARGO_PKG_VERSION")) + .to_string(), + )], + sdk: vec![], + authors: match package.authors.len() { + 0 => None, + _ => Some(wasm_metadata::Authors::new(package.authors.join(","))), + }, + description: package + .description + .as_ref() + .map(|d| wasm_metadata::Description::new(d.clone())), + licenses: package + .license + .as_ref() + .map(|s| wasm_metadata::Licenses::new(&s)) + .transpose()?, + source: package + .repository + .as_ref() + .map(|s| wasm_metadata::Source::new(s.to_string().as_str())) + .transpose()?, + homepage: package + .homepage + .as_ref() + .map(|s| wasm_metadata::Homepage::new(s.to_string().as_str())) + .transpose()?, + // TODO: get the git commit hash + revision: None, + version: Some(wasm_metadata::Version::new(package.version.to_string())), + }; + metadata.to_wasm(wasm) } /// Publish a component for the given workspace and publish options. @@ -1050,8 +1082,6 @@ pub async fn publish( ) })?; - let bytes = add_registry_metadata(options.package, &bytes, options.path)?; - config.terminal().status( "Publishing", format!("component {path}", path = options.path.display()), diff --git a/tests/build.rs b/tests/build.rs index b4c5400b..42ebaf2f 100644 --- a/tests/build.rs +++ b/tests/build.rs @@ -128,36 +128,6 @@ fn it_supports_wit_keywords() -> Result<()> { Ok(()) } -#[test] -fn it_adds_a_producers_field() -> Result<()> { - let project = Project::new("foo", true)?; - - project - .cargo_component(["build", "--release"]) - .assert() - .stderr(contains("Finished `release` profile [optimized] target(s)")) - .success(); - - let path = project.release_wasm("foo"); - - validate_component(&path)?; - - let wasm = fs::read(&path) - .with_context(|| format!("failed to read wasm file `{path}`", path = path.display()))?; - let section = wasm_metadata::Producers::from_wasm(&wasm)?.expect("missing producers section"); - - assert_eq!( - section - .get("processed-by") - .expect("missing processed-by field") - .get(env!("CARGO_PKG_NAME")) - .expect("missing cargo-component field"), - option_env!("CARGO_VERSION_INFO").unwrap_or(env!("CARGO_PKG_VERSION")) - ); - - Ok(()) -} - #[test] fn it_builds_wasm32_unknown_unknown_from_cli() -> Result<()> { let project = Project::new("foo", true)?; @@ -1008,3 +978,132 @@ edition = "2021" Ok(()) } + +#[test] +fn it_adds_a_producers_field() -> Result<()> { + let project = Project::new("foo", true)?; + + project + .cargo_component(["build", "--release"]) + .assert() + .stderr(contains("Finished `release` profile [optimized] target(s)")) + .success(); + + let path = project.release_wasm("foo"); + + validate_component(&path)?; + + let wasm = fs::read(&path) + .with_context(|| format!("failed to read wasm file `{path}`", path = path.display()))?; + let section = wasm_metadata::Producers::from_wasm(&wasm)?.expect("missing producers section"); + + assert_eq!( + section + .get("processed-by") + .expect("missing processed-by field") + .get(env!("CARGO_PKG_NAME")) + .expect("missing cargo-component field"), + option_env!("CARGO_VERSION_INFO").unwrap_or(env!("CARGO_PKG_VERSION")) + ); + + Ok(()) +} + +#[test] +fn it_adds_metadata_from_cargo_toml() -> Result<()> { + let name = "foo"; + let authors = "Jane Doe "; + let description = "A test package"; + let license = "Apache-2.0"; + let version = "1.0.0"; + let documentation = "https://example.com/docs"; + let homepage = "https://example.com/home"; + let repository = "https://example.com/repo"; + + let project = Project::new(name, true)?; + project.update_manifest(|mut doc| { + let package = &mut doc["package"]; + package["name"] = value(name); + package["version"] = value(version); + package["authors"] = value(Array::from_iter([authors])); + package["description"] = value(description); + package["license"] = value(license); + package["documentation"] = value(documentation); + package["homepage"] = value(homepage); + package["repository"] = value(repository); + Ok(doc) + })?; + + project + .cargo_component(["build", "--release"]) + .assert() + .stderr(contains("Finished `release` profile [optimized] target(s)")) + .success(); + + let path = project.release_wasm("foo"); + + validate_component(&path)?; + + let wasm = fs::read(&path) + .with_context(|| format!("failed to read wasm file `{path}`", path = path.display()))?; + + let metadata = match wasm_metadata::Payload::from_binary(&wasm)? { + wasm_metadata::Payload::Component { metadata, .. } => metadata, + wasm_metadata::Payload::Module(_) => unreachable!("found a wasm module"), + }; + + assert_eq!( + &metadata.name.as_ref().expect("missing name").to_string(), + name + ); + assert_eq!( + &metadata + .authors + .as_ref() + .expect("missing authors") + .to_string(), + authors + ); + assert_eq!( + &metadata + .description + .as_ref() + .expect("missing description") + .to_string(), + description + ); + assert_eq!( + &metadata + .licenses + .as_ref() + .expect("missing licenses") + .to_string(), + license + ); + assert_eq!( + &metadata + .source + .as_ref() + .expect("missing source") + .to_string(), + repository + ); + assert_eq!( + &metadata + .homepage + .as_ref() + .expect("missing homepage") + .to_string(), + homepage + ); + assert_eq!( + &metadata + .version + .as_ref() + .expect("missing version") + .to_string(), + version + ); + + Ok(()) +}