From 4ed2cc4ec92dd55d43a8ccb56127d9ddcd914ec5 Mon Sep 17 00:00:00 2001 From: Justin Gaffney Date: Sat, 22 Mar 2025 12:18:42 +1000 Subject: [PATCH 1/2] Add Git commit hash to the revision field of component metadata --- Cargo.lock | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 ++ src/git.rs | 43 ++++++++++++++++++++++++++ src/lib.rs | 10 +++--- 4 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 src/git.rs diff --git a/Cargo.lock b/Cargo.lock index b9e6d869..04dec5b0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -531,6 +531,7 @@ dependencies = [ "cargo_metadata", "clap", "futures", + "git2", "heck 0.5.0", "indexmap 2.7.0", "libc", @@ -642,6 +643,8 @@ version = "1.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7" dependencies = [ + "jobserver", + "libc", "shlex", ] @@ -1445,6 +1448,21 @@ version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" +[[package]] +name = "git2" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5220b8ba44c68a9a7f7a7659e864dd73692e417ef0211bea133c7b74e031eeb9" +dependencies = [ + "bitflags", + "libc", + "libgit2-sys", + "log", + "openssl-probe", + "openssl-sys", + "url", +] + [[package]] name = "group" version = "0.13.0" @@ -1953,6 +1971,15 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +[[package]] +name = "jobserver" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.76" @@ -2045,6 +2072,20 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libgit2-sys" +version = "0.18.1+1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1dcb20f84ffcdd825c7a311ae347cce604a6f084a767dec4a4929829645290e" +dependencies = [ + "cc", + "libc", + "libssh2-sys", + "libz-sys", + "openssl-sys", + "pkg-config", +] + [[package]] name = "libredox" version = "0.1.3" @@ -2055,6 +2096,32 @@ dependencies = [ "libc", ] +[[package]] +name = "libssh2-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "220e4f05ad4a218192533b300327f5150e809b54c4ec83b5a1d91833601811b9" +dependencies = [ + "cc", + "libc", + "libz-sys", + "openssl-sys", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b70e7a7df205e92a1a4cd9aaae7898dac0aa555503cc0a649494d0d60e7651d" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linux-keyutils" version = "0.2.4" @@ -2439,6 +2506,24 @@ version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + [[package]] name = "option-ext" version = "0.2.0" @@ -4254,6 +4339,12 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + [[package]] name = "version_check" version = "0.9.5" diff --git a/Cargo.toml b/Cargo.toml index 211fd5a5..1536c0ac 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ bytes = { workspace = true } cargo_metadata = { workspace = true } cargo-component-core = { workspace = true } cargo-config2 = { workspace = true } +git2 = { workspace = true } clap = { workspace = true } futures = { workspace = true } heck = { workspace = true } @@ -74,6 +75,7 @@ bytes = "1.6.0" cargo_metadata = "0.19.1" cargo-component-core = { path = "crates/core", version = "0.21.1" } cargo-config2 = "0.1.24" +git2 = "0.20.1" clap = { version = "4.5.4", features = ["derive", "env"] } dirs = "5" futures = "0.3.30" diff --git a/src/git.rs b/src/git.rs new file mode 100644 index 00000000..190ef89b --- /dev/null +++ b/src/git.rs @@ -0,0 +1,43 @@ +use anyhow::Result; +use cargo_metadata::Package; +use git2::{Repository, ErrorClass, ErrorCode}; + +#[derive(Debug)] +pub struct GitMetadata { + commit: String, +} + +impl GitMetadata { + /// Creates a new Git metadata for the given cargo package. + pub fn from_package(package: &Package) -> Result> { + log::debug!( + "searching for git metadata from manifest `{path}`", + path = package.manifest_path + ); + + let repository = match Repository::discover(package.manifest_path.clone()) { + Ok(repository) => Ok(repository), + Err(ref e) if e.class() == ErrorClass::Repository && e.code() == ErrorCode::NotFound => return Ok(None), + Err(e) => Err(e) + }?; + + let head = match repository.head() { + Ok(head) => Ok(head), + Err(ref e) if e.class() == ErrorClass::Reference && e.code() == ErrorCode::UnbornBranch => return Ok(None), + Err(error) => Err(error) + }?; + + let commit = head.peel_to_commit()?; + let commit_id = commit.id(); + + let metadata = Self { + commit: commit_id.to_string() + }; + + Ok(Some(metadata)) + } + + pub fn commit(&self) -> &str { + &self.commit + } +} \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index c81a2406..082606c1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,6 +39,7 @@ use config::{CargoArguments, CargoPackageSpec, Config}; use lock::{acquire_lock_file_ro, acquire_lock_file_rw}; use metadata::ComponentMetadata; use registry::{PackageDependencyResolution, PackageResolutionMap}; +use git::GitMetadata; mod bindings; pub mod commands; @@ -48,6 +49,7 @@ mod lock; mod metadata; mod registry; mod target; +mod git; fn is_wasm_target(target: &str) -> bool { target == "wasm32-wasi" || target == "wasm32-wasip1" || target == "wasm32-unknown-unknown" @@ -971,7 +973,8 @@ fn componentize( .validate(true); let package = &cargo_metadata[&artifact.package_id]; - let component = add_component_metadata(&package, &encoder.encode()?).with_context(|| { + let git = GitMetadata::from_package(package)?; + let component = add_component_metadata(package, git.as_ref(), &encoder.encode()?).with_context(|| { format!( "failed to add metadata to output component `{path}`", path = path.display() @@ -1021,7 +1024,7 @@ pub struct PublishOptions<'a> { } /// Read metadata from `Cargo.toml` and add it to the component -fn add_component_metadata(package: &Package, wasm: &[u8]) -> Result> { +fn add_component_metadata(package: &Package, git: Option<&GitMetadata>, wasm: &[u8]) -> Result> { let metadata = wasm_metadata::AddMetadata { name: Some(package.name.clone()), language: vec![("Rust".to_string(), "".to_string())], @@ -1055,8 +1058,7 @@ fn add_component_metadata(package: &Package, wasm: &[u8]) -> Result> { .as_ref() .map(|s| wasm_metadata::Homepage::new(s.to_string().as_str())) .transpose()?, - // TODO: get the git commit hash - revision: None, + revision: git.map(|git| wasm_metadata::Revision::new(git.commit().to_string())), version: Some(wasm_metadata::Version::new(package.version.to_string())), }; metadata.to_wasm(wasm) From 5f13c343f1a2865bd317c5ce907a2fa6ee6454d4 Mon Sep 17 00:00:00 2001 From: Justin Gaffney Date: Sat, 22 Mar 2025 12:25:58 +1000 Subject: [PATCH 2/2] Run `cargo fmt` --- src/git.rs | 22 +++++++++++++++------- src/lib.rs | 23 ++++++++++++++--------- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/git.rs b/src/git.rs index 190ef89b..105e2670 100644 --- a/src/git.rs +++ b/src/git.rs @@ -1,6 +1,6 @@ use anyhow::Result; use cargo_metadata::Package; -use git2::{Repository, ErrorClass, ErrorCode}; +use git2::{ErrorClass, ErrorCode, Repository}; #[derive(Debug)] pub struct GitMetadata { @@ -17,21 +17,29 @@ impl GitMetadata { let repository = match Repository::discover(package.manifest_path.clone()) { Ok(repository) => Ok(repository), - Err(ref e) if e.class() == ErrorClass::Repository && e.code() == ErrorCode::NotFound => return Ok(None), - Err(e) => Err(e) + Err(ref e) + if e.class() == ErrorClass::Repository && e.code() == ErrorCode::NotFound => + { + return Ok(None) + } + Err(e) => Err(e), }?; let head = match repository.head() { Ok(head) => Ok(head), - Err(ref e) if e.class() == ErrorClass::Reference && e.code() == ErrorCode::UnbornBranch => return Ok(None), - Err(error) => Err(error) + Err(ref e) + if e.class() == ErrorClass::Reference && e.code() == ErrorCode::UnbornBranch => + { + return Ok(None) + } + Err(error) => Err(error), }?; let commit = head.peel_to_commit()?; let commit_id = commit.id(); let metadata = Self { - commit: commit_id.to_string() + commit: commit_id.to_string(), }; Ok(Some(metadata)) @@ -40,4 +48,4 @@ impl GitMetadata { pub fn commit(&self) -> &str { &self.commit } -} \ No newline at end of file +} diff --git a/src/lib.rs b/src/lib.rs index 082606c1..fba400c4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -36,20 +36,20 @@ use wit_component::ComponentEncoder; use crate::target::install_wasm32_wasip1; use config::{CargoArguments, CargoPackageSpec, Config}; +use git::GitMetadata; use lock::{acquire_lock_file_ro, acquire_lock_file_rw}; use metadata::ComponentMetadata; use registry::{PackageDependencyResolution, PackageResolutionMap}; -use git::GitMetadata; mod bindings; pub mod commands; pub mod config; mod generator; +mod git; mod lock; mod metadata; mod registry; mod target; -mod git; fn is_wasm_target(target: &str) -> bool { target == "wasm32-wasi" || target == "wasm32-wasip1" || target == "wasm32-unknown-unknown" @@ -974,12 +974,13 @@ fn componentize( let package = &cargo_metadata[&artifact.package_id]; let git = GitMetadata::from_package(package)?; - let component = add_component_metadata(package, git.as_ref(), &encoder.encode()?).with_context(|| { - format!( - "failed to add metadata to output component `{path}`", - path = path.display() - ) - })?; + let component = add_component_metadata(package, git.as_ref(), &encoder.encode()?) + .with_context(|| { + format!( + "failed to add metadata to output component `{path}`", + path = path.display() + ) + })?; // To make the write atomic, first write to a temp file and then rename the file let temp_dir = cargo_metadata.target_directory.join("tmp"); @@ -1024,7 +1025,11 @@ pub struct PublishOptions<'a> { } /// Read metadata from `Cargo.toml` and add it to the component -fn add_component_metadata(package: &Package, git: Option<&GitMetadata>, wasm: &[u8]) -> Result> { +fn add_component_metadata( + package: &Package, + git: Option<&GitMetadata>, + wasm: &[u8], +) -> Result> { let metadata = wasm_metadata::AddMetadata { name: Some(package.name.clone()), language: vec![("Rust".to_string(), "".to_string())],