From db8b6ca9c7f1e072e3341044bf05b34cd6bb37f7 Mon Sep 17 00:00:00 2001 From: subotac <73706465+subotac@users.noreply.github.com> Date: Thu, 30 Jul 2026 20:51:02 +0300 Subject: [PATCH 1/2] fix(wkg): respect member manifests during fetch --- crates/wkg/src/wit.rs | 7 ++++++- crates/wkg/tests/e2e.rs | 19 +++++++++++++++++++ .../member/wit/wkg.toml | 1 + .../member/wit/world.wit | 3 +++ .../fixtures/fetch-workspace-member/wkg.toml | 2 ++ 5 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 crates/wkg/tests/fixtures/fetch-workspace-member/member/wit/wkg.toml create mode 100644 crates/wkg/tests/fixtures/fetch-workspace-member/member/wit/world.wit create mode 100644 crates/wkg/tests/fixtures/fetch-workspace-member/wkg.toml diff --git a/crates/wkg/src/wit.rs b/crates/wkg/src/wit.rs index 38c7cdc..f0ba6be 100644 --- a/crates/wkg/src/wit.rs +++ b/crates/wkg/src/wit.rs @@ -155,7 +155,12 @@ pub async fn temp_wit_file(package: &PackageRef, bytes: &[u8]) -> anyhow::Result impl FetchArgs { pub async fn run(self) -> anyhow::Result<()> { let cwd = std::env::current_dir()?; - let root = Manifest::load_root_workspace(&cwd).await?; + let mut root = Manifest::load_root_workspace(&cwd).await?; + if root.as_ref().is_some_and(|root| root.root_dir() != cwd) + && tokio::fs::try_exists(cwd.join(MANIFEST_FILE_NAME)).await? + { + root = None; + } let dirs = if let Some(dir) = self.dir.clone() { vec![dir] diff --git a/crates/wkg/tests/e2e.rs b/crates/wkg/tests/e2e.rs index 29858d1..7389ed7 100644 --- a/crates/wkg/tests/e2e.rs +++ b/crates/wkg/tests/e2e.rs @@ -250,6 +250,25 @@ async fn fetch_workspace_packages() { } } +#[tokio::test] +async fn fetch_from_member_manifest_uses_member_context() { + let fixture = common::load_fixture("fetch-workspace-member").await; + let member = fixture.fixture_path.join("member/wit"); + let mut command = fixture.command(); + command.current_dir(&member).args(["fetch", "."]); + + let status = command.status().await.expect("spawn wkg fetch"); + assert!(status.success(), "member fetch should succeed"); + assert!( + member.join("wkg.lock").exists(), + "member fetch should create a member lock file" + ); + assert!( + !fixture.fixture_path.join("wkg.lock").exists(), + "member fetch should not create a workspace lock file" + ); +} + #[tokio::test] pub async fn check() { // Use an explicit config that maps `wasi` to `wasi.dev`. diff --git a/crates/wkg/tests/fixtures/fetch-workspace-member/member/wit/wkg.toml b/crates/wkg/tests/fixtures/fetch-workspace-member/member/wit/wkg.toml new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/crates/wkg/tests/fixtures/fetch-workspace-member/member/wit/wkg.toml @@ -0,0 +1 @@ + diff --git a/crates/wkg/tests/fixtures/fetch-workspace-member/member/wit/world.wit b/crates/wkg/tests/fixtures/fetch-workspace-member/member/wit/world.wit new file mode 100644 index 0000000..c8aef2a --- /dev/null +++ b/crates/wkg/tests/fixtures/fetch-workspace-member/member/wit/world.wit @@ -0,0 +1,3 @@ +package test:member; + +world member {} diff --git a/crates/wkg/tests/fixtures/fetch-workspace-member/wkg.toml b/crates/wkg/tests/fixtures/fetch-workspace-member/wkg.toml new file mode 100644 index 0000000..c03ae07 --- /dev/null +++ b/crates/wkg/tests/fixtures/fetch-workspace-member/wkg.toml @@ -0,0 +1,2 @@ +[workspace] +members = ["member/wit"] From 04205289b0cae5f28a81da0a0696836c5d4542f0 Mon Sep 17 00:00:00 2001 From: subotac <73706465+subotac@users.noreply.github.com> Date: Sun, 2 Aug 2026 19:49:40 +0300 Subject: [PATCH 2/2] fix(wkg): find member manifests from subdirectories --- crates/wasm-pkg-core/src/manifest.rs | 4 ++- crates/wasm-pkg-core/src/manifest/paths.rs | 2 +- crates/wkg/src/wit.rs | 31 ++++++++++++++----- crates/wkg/tests/e2e.rs | 5 +-- .../member/wit/subdir/world.wit | 3 ++ 5 files changed, 34 insertions(+), 11 deletions(-) create mode 100644 crates/wkg/tests/fixtures/fetch-workspace-member/member/wit/subdir/world.wit diff --git a/crates/wasm-pkg-core/src/manifest.rs b/crates/wasm-pkg-core/src/manifest.rs index 7e1924a..78dd347 100644 --- a/crates/wasm-pkg-core/src/manifest.rs +++ b/crates/wasm-pkg-core/src/manifest.rs @@ -13,7 +13,9 @@ pub mod workspace; use workspace::*; -use crate::manifest::paths::{find_root_iter, find_root_manifest_for_wd}; +use crate::manifest::paths::find_root_iter; + +pub use crate::manifest::paths::find_root_manifest_for_wd; /// The default name of the manifest file. pub const MANIFEST_FILE_NAME: &str = "wkg.toml"; diff --git a/crates/wasm-pkg-core/src/manifest/paths.rs b/crates/wasm-pkg-core/src/manifest/paths.rs index 6bcf8d0..e178833 100644 --- a/crates/wasm-pkg-core/src/manifest/paths.rs +++ b/crates/wasm-pkg-core/src/manifest/paths.rs @@ -4,7 +4,7 @@ use std::path::{Component, Path, PathBuf}; use crate::manifest::MANIFEST_FILE_NAME; /// Find the first ancestor [`super::Manifest`] path for current working directory. -pub(crate) fn find_root_manifest_for_wd(cwd: impl AsRef) -> Option { +pub fn find_root_manifest_for_wd(cwd: impl AsRef) -> Option { for current in cwd.as_ref().ancestors() { let manifest = current.join(MANIFEST_FILE_NAME); if manifest.exists() { diff --git a/crates/wkg/src/wit.rs b/crates/wkg/src/wit.rs index f0ba6be..76cb811 100644 --- a/crates/wkg/src/wit.rs +++ b/crates/wkg/src/wit.rs @@ -11,7 +11,9 @@ use wasm_pkg_common::package::{PackageRef, Version}; use wasm_pkg_core::wit::WIT_DEPS_DIR; use wasm_pkg_core::{ lock::{LOCK_FILE_NAME, LockFile, LockedPackage}, - manifest::{MANIFEST_FILE_NAME, Manifest, workspace::WorkspaceRootConfig}, + manifest::{ + MANIFEST_FILE_NAME, Manifest, find_root_manifest_for_wd, workspace::WorkspaceRootConfig, + }, resolver::DependencyResolutionMap, wit::{self, OutputType}, }; @@ -156,9 +158,13 @@ impl FetchArgs { pub async fn run(self) -> anyhow::Result<()> { let cwd = std::env::current_dir()?; let mut root = Manifest::load_root_workspace(&cwd).await?; - if root.as_ref().is_some_and(|root| root.root_dir() != cwd) - && tokio::fs::try_exists(cwd.join(MANIFEST_FILE_NAME)).await? - { + let manifest_path = find_root_manifest_for_wd(&cwd); + if root.as_ref().is_some_and(|root| { + manifest_path + .as_deref() + .and_then(Path::parent) + .is_some_and(|manifest_dir| manifest_dir != root.root_dir()) + }) { root = None; } @@ -174,7 +180,10 @@ impl FetchArgs { let manifest_path = root.root_dir().join(MANIFEST_FILE_NAME); Manifest::load_from_path(manifest_path).await? } - None => Manifest::load().await?, + None => match manifest_path.as_ref() { + Some(path) => Manifest::load_from_path(path).await?, + None => Manifest::default(), + }, }; let output = self.output_type.unwrap_or_default(); @@ -187,7 +196,14 @@ impl FetchArgs { self.run_workspace_fetch(&dirs, output, &manifest, root) .await } - None => self.fetch_into_lock(&dirs, &manifest, output).await, + None => { + let lock_dir = manifest_path + .as_deref() + .and_then(Path::parent) + .unwrap_or(&cwd); + self.fetch_into_lock(&dirs, &manifest, output, lock_dir.join(LOCK_FILE_NAME)) + .await + } } } @@ -261,9 +277,10 @@ impl FetchArgs { dirs: &[PathBuf], manifest: &Manifest, output: OutputType, + lock_path: PathBuf, ) -> anyhow::Result<()> { let client = self.common.get_client().await?; - let mut lock_file = LockFile::load(false).await?; + let mut lock_file = load_or_create_lock(&lock_path).await?; let mut union: BTreeSet = BTreeSet::new(); merge_locked_packages(&mut union, std::mem::take(&mut lock_file.packages)); diff --git a/crates/wkg/tests/e2e.rs b/crates/wkg/tests/e2e.rs index 7389ed7..0b9b30d 100644 --- a/crates/wkg/tests/e2e.rs +++ b/crates/wkg/tests/e2e.rs @@ -251,11 +251,12 @@ async fn fetch_workspace_packages() { } #[tokio::test] -async fn fetch_from_member_manifest_uses_member_context() { +async fn fetch_from_member_subdirectory_uses_member_context() { let fixture = common::load_fixture("fetch-workspace-member").await; let member = fixture.fixture_path.join("member/wit"); + let subdir = member.join("subdir"); let mut command = fixture.command(); - command.current_dir(&member).args(["fetch", "."]); + command.current_dir(&subdir).args(["fetch", "."]); let status = command.status().await.expect("spawn wkg fetch"); assert!(status.success(), "member fetch should succeed"); diff --git a/crates/wkg/tests/fixtures/fetch-workspace-member/member/wit/subdir/world.wit b/crates/wkg/tests/fixtures/fetch-workspace-member/member/wit/subdir/world.wit new file mode 100644 index 0000000..dba860d --- /dev/null +++ b/crates/wkg/tests/fixtures/fetch-workspace-member/member/wit/subdir/world.wit @@ -0,0 +1,3 @@ +package test:subdir; + +world subdir {}