[flutter_tools] Resolve workspace root when running widget preview from member package - #190952
[flutter_tools] Resolve workspace root when running widget preview from member package#190952bkonyi wants to merge 2 commits into
Conversation
…om member package When `flutter widget-preview start` is run from a member package in a pub workspace, redirect `getRootProject()` to the workspace root `FlutterProject`. This ensures that the widget preview scaffold is generated at the workspace root and has dependency overrides for all member packages in the workspace. Fixes flutter#190692
There was a problem hiding this comment.
Code Review
This pull request updates the widget preview command to run from the workspace root when executed within a member package of a workspace. It introduces a workspaceRoot getter on FlutterProject to locate the workspace root by traversing parent directories and matching against workspace glob patterns. Feedback suggests optimizing the workspace membership check in _findWorkspaceRoot by using Glob.matches on the relative path in-memory, avoiding expensive filesystem scanning and potential crashes from other invalid sibling packages.
| if (candidateProject.manifest.workspace.isNotEmpty) { | ||
| if (candidateProject.workspaceProjects.any( | ||
| (FlutterProject p) => fileSystem.path.equals( | ||
| fileSystem.path.normalize(p.directory.absolute.path), | ||
| normalizedPath, | ||
| ), | ||
| )) { | ||
| return candidateProject; | ||
| } | ||
| } |
There was a problem hiding this comment.
Using candidateProject.workspaceProjects to check membership is highly inefficient and fragile:
- Performance Bottleneck: Accessing
workspaceProjectstriggers eager filesystem scanning (listFileSystemSync) and instantiates aFlutterProjectfor every member package in the workspace. In large monorepos, this can be extremely slow. - Fragility: If any other sibling package in the workspace has a malformed
pubspec.yamlor is temporarily invalid, instantiating itsFlutterProjectwill throw an exception. This causes_findWorkspaceRootto catch the exception and fail to recognize the workspace root entirely, even if the current package is perfectly valid.
Solution:
Use Glob.matches on the relative path of the current project to determine membership in-memory. This avoids filesystem listing and instantiating other projects entirely.
| if (candidateProject.manifest.workspace.isNotEmpty) { | |
| if (candidateProject.workspaceProjects.any( | |
| (FlutterProject p) => fileSystem.path.equals( | |
| fileSystem.path.normalize(p.directory.absolute.path), | |
| normalizedPath, | |
| ), | |
| )) { | |
| return candidateProject; | |
| } | |
| } | |
| if (candidateProject.manifest.workspace.isNotEmpty) { | |
| final String relativePath = fileSystem.path.relative(normalizedPath, from: candidate.path); | |
| final bool isMember = candidateProject.manifest.workspace.any((String entry) { | |
| final Glob glob = Glob(entry, context: fileSystem.path); | |
| return glob.matches(relativePath); | |
| }); | |
| if (isMember) { | |
| return candidateProject; | |
| } | |
| } |
There was a problem hiding this comment.
Addressed in f86ddee. Updated _findWorkspaceRoot to use in-memory Glob.matches on the relative path and added test coverage for malformed sibling package resilience.
…rror resilience Use in-memory `Glob.matches` on the relative project path instead of eagerly instantiating and traversing all sibling `workspaceProjects`. Also guard child project instantiation in `_setManifest` against malformed sibling packages.
When
flutter widget-preview startis run from a member package in a pub workspace, redirectgetRootProject()to the workspace rootFlutterProject. This ensures that the widget preview scaffold is generated at the workspace root and has dependency overrides for all member packages in the workspace.Fixes #190692