-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Optimize cargo locate-project --workspace #16423
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2059,10 +2059,50 @@ impl WorkspaceRootConfig { | |||||||||||||
| !explicit_member && excluded | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// Checks if the path is explicitly listed as a workspace member. | ||||||||||||||
| /// | ||||||||||||||
| /// Returns `true` ONLY if: | ||||||||||||||
| /// - The path is the workspace root manifest itself, or | ||||||||||||||
| /// - The path matches one of the explicit `members` patterns | ||||||||||||||
| /// | ||||||||||||||
| /// NOTE: This does NOT check for implicit path dependency membership. | ||||||||||||||
| /// A `false` return does NOT mean the package is definitely not a member - | ||||||||||||||
| /// it could still be a member via path dependencies. Callers should fallback | ||||||||||||||
| /// to full workspace loading when this returns `false`. | ||||||||||||||
| fn is_explicitly_listed_member(&self, manifest_path: &Path) -> bool { | ||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cargo/src/cargo/core/workspace.rs Lines 841 to 846 in 3861f60
I found this interesting comment. Wonder what would happen with the current implementation in these situations:
The new implementation should be aligned with the default
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I checked whether the manifest has a default member. If it does, I run the full check using |
||||||||||||||
| let root_manifest = self.root_dir.join("Cargo.toml"); | ||||||||||||||
| if manifest_path == root_manifest { | ||||||||||||||
| return true; | ||||||||||||||
| } | ||||||||||||||
| match self.members { | ||||||||||||||
| Some(ref members) => { | ||||||||||||||
| // Use members_paths to properly expand glob patterns | ||||||||||||||
| let Ok(expanded_members) = self.members_paths(members) else { | ||||||||||||||
| return false; | ||||||||||||||
| }; | ||||||||||||||
| // Normalize the manifest path for comparison | ||||||||||||||
| let normalized_manifest = paths::normalize_path(manifest_path); | ||||||||||||||
| expanded_members.iter().any(|(member_path, _)| { | ||||||||||||||
| // Normalize the member path as glob expansion may leave ".." components | ||||||||||||||
| let normalized_member = paths::normalize_path(member_path); | ||||||||||||||
| // Compare the manifest's parent directory with the member path exactly | ||||||||||||||
| // instead of using starts_with to avoid matching nested directories | ||||||||||||||
| normalized_manifest.parent() == Some(normalized_member.as_path()) | ||||||||||||||
| }) | ||||||||||||||
| } | ||||||||||||||
| None => false, | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| fn has_members_list(&self) -> bool { | ||||||||||||||
| self.members.is_some() | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// Returns true if this workspace config has default-members defined. | ||||||||||||||
| fn has_default_members(&self) -> bool { | ||||||||||||||
| self.default_members.is_some() | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// Returns expanded paths along with the glob that they were expanded from. | ||||||||||||||
| /// The glob is `None` if the path matched exactly. | ||||||||||||||
| #[tracing::instrument(skip_all)] | ||||||||||||||
|
|
@@ -2157,6 +2197,66 @@ pub fn find_workspace_root( | |||||||||||||
| }) | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// Finds the workspace root for a manifest, with minimal verification. | ||||||||||||||
| /// | ||||||||||||||
| /// This is similar to `find_workspace_root`, but additionally verifies that the | ||||||||||||||
| /// package and workspace agree on each other: | ||||||||||||||
| /// - If the package has an explicit `package.workspace` pointer, it is trusted | ||||||||||||||
| /// - Otherwise, the workspace must include the package in its `members` list | ||||||||||||||
| pub fn find_workspace_root_with_membership_check( | ||||||||||||||
| manifest_path: &Path, | ||||||||||||||
| gctx: &GlobalContext, | ||||||||||||||
| ) -> CargoResult<Option<PathBuf>> { | ||||||||||||||
| let source_id = SourceId::for_manifest_path(manifest_path)?; | ||||||||||||||
| let current_manifest = read_manifest(manifest_path, source_id, gctx)?; | ||||||||||||||
|
|
||||||||||||||
| match current_manifest.workspace_config() { | ||||||||||||||
| WorkspaceConfig::Root(root_config) => { | ||||||||||||||
| // This manifest is a workspace root itself | ||||||||||||||
| // If default-members are defined, fall back to full loading for proper validation | ||||||||||||||
| if root_config.has_default_members() { | ||||||||||||||
| Ok(None) | ||||||||||||||
| } else { | ||||||||||||||
| Ok(Some(manifest_path.to_path_buf())) | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| WorkspaceConfig::Member { | ||||||||||||||
| root: Some(path_to_root), | ||||||||||||||
| } => { | ||||||||||||||
| // Has explicit `package.workspace` pointer - verify the workspace agrees | ||||||||||||||
| let ws_manifest_path = read_root_pointer(manifest_path, path_to_root); | ||||||||||||||
| let ws_source_id = SourceId::for_manifest_path(&ws_manifest_path)?; | ||||||||||||||
| let ws_manifest = read_manifest(&ws_manifest_path, ws_source_id, gctx)?; | ||||||||||||||
|
|
||||||||||||||
| // Verify the workspace includes this package in its members | ||||||||||||||
| if let WorkspaceConfig::Root(ref root_config) = *ws_manifest.workspace_config() { | ||||||||||||||
| if root_config.is_explicitly_listed_member(manifest_path) | ||||||||||||||
| && !root_config.is_excluded(manifest_path) | ||||||||||||||
| { | ||||||||||||||
| return Ok(Some(ws_manifest_path)); | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| // Workspace doesn't agree with the pointer - not a valid workspace root | ||||||||||||||
| Ok(None) | ||||||||||||||
| } | ||||||||||||||
| WorkspaceConfig::Member { root: None } => { | ||||||||||||||
| // No explicit pointer, walk up with membership validation | ||||||||||||||
| find_workspace_root_with_loader(manifest_path, gctx, |candidate_manifest_path| { | ||||||||||||||
| let source_id = SourceId::for_manifest_path(candidate_manifest_path)?; | ||||||||||||||
| let manifest = read_manifest(candidate_manifest_path, source_id, gctx)?; | ||||||||||||||
| if let WorkspaceConfig::Root(ref root_config) = *manifest.workspace_config() { | ||||||||||||||
| if root_config.is_explicitly_listed_member(manifest_path) | ||||||||||||||
| && !root_config.is_excluded(manifest_path) | ||||||||||||||
| { | ||||||||||||||
| return Ok(Some(candidate_manifest_path.to_path_buf())); | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| Ok(None) | ||||||||||||||
| }) | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| /// Finds the path of the root of the workspace. | ||||||||||||||
| /// | ||||||||||||||
| /// This uses a callback to determine if the given path tells us what the | ||||||||||||||
|
|
||||||||||||||
Uh oh!
There was an error while loading. Please reload this page.