Repository navigation
[flutter_tools] Fix StateError in testCompilerBuildNativeAssets when package root does not match projectUri - #192942
Conversation
…package root does not match projectUri Avoid throwing an unhandled StateError in testCompilerBuildNativeAssets when no package in buildInfo.packageConfig.packages has a root URI directly matching FlutterProject.current().directory.uri (such as in pub workspaces or symlinked directories). Instead, attempt canonicalized path matching, then fall back to the target package name from the project manifest or packageConfig, and return null gracefully if no package can be resolved. Fixes flutter#192933
…sets Add an optional FileSystem parameter to testCompilerBuildNativeAssets and TestCompilerNativeAssetsBuilderImpl to avoid repeated ambient globals.fs lookups. Decouple _findRunPackageName from FlutterProject by passing projectUri and manifestAppName directly, use fileSystem.path.fromUri instead of allocating a Directory, and add documentation comments.
…derImpl and isolate fallback tier tests
…rNativeAssetsBuilderImpl.build
…CompilerBuildNativeAssets
…d testCompilerBuildNativeAssets
…estCompilerBuildNativeAssets test and document fallback tests
…ativeAssets tests for Windows compatibility
…fine findRunPackageName Tier 3
There was a problem hiding this comment.
Code Review
This pull request introduces a robust fallback mechanism (findRunPackageName) for resolving the target package name during native assets builds for tests, handling direct URI matches, canonicalized paths (including symlinks), and project manifest app name fallbacks. It also adds comprehensive unit tests covering these resolution paths and error handling. Feedback suggests optimizing the path resolution logic by checking the manifestAppName first to avoid potentially slow synchronous I/O operations in a loop over all packages.
| final Package? pathMatch = packageConfig.packages.where((Package p) { | ||
| if (!p.root.isScheme(_fileScheme)) { | ||
| return false; | ||
| } | ||
| return _canonicalizeUriPath(fileSystem, p.root) == canonicalProjectDir; | ||
| }).firstOrNull; | ||
| if (pathMatch != null) { | ||
| return pathMatch.name; | ||
| } |
There was a problem hiding this comment.
To avoid performing synchronous I/O operations (existsSync and resolveSymbolicLinksSync) in a loop over all packages in packageConfig.packages (which can be slow in large projects), we can add a fast path that checks the package matching manifestAppName first. Since the root package name in package_config.json always matches the name in pubspec.yaml (manifestAppName), this will resolve the package directly in almost all cases without iterating through other packages.
if (manifestAppName.isNotEmpty) {
final Package? candidate = packageConfig[manifestAppName];
if (candidate != null &&
candidate.root.isScheme(_fileScheme) &&
_canonicalizeUriPath(fileSystem, candidate.root) == canonicalProjectDir) {
return candidate.name;
}
}
final Package? pathMatch = packageConfig.packages.where((Package p) {
if (!p.root.isScheme(_fileScheme)) {
return false;
}
return _canonicalizeUriPath(fileSystem, p.root) == canonicalProjectDir;
}).firstOrNull;
if (pathMatch != null) {
return pathMatch.name;
}References
- Suggest simplification and refactoring: Assess whether the code can be made simpler or refactored to enhance readability and maintainability. (link)
dcharkes
left a comment
There was a problem hiding this comment.
IIRC, there are more and older github issues that are related to tool crashes because there are entry points that are not part of the resolved package graph?
LGTM to a sane fallback behavior.
|
autosubmit label was removed for flutter/flutter/192942, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label. |
|
Failed to create CP due to merge conflicts. |
…package root does not match projectUri (flutter#192942) Fixes a `StateError (Bad state: No element)` crash in `testCompilerBuildNativeAssets` when running `flutter test` in a directory whose URI does not strictly match any package root in `package_config.json` (such as when working through symlinked project directories, monorepos/workspaces, or ancestor `package_config.json` files). Replaces the strict `firstWhere((Package p) => p.root == projectUri)` lookup with `findRunPackageName`, which resolves the target package name using the following fallback order: 1. Direct URI match against `projectUri`. 2. Canonicalized filesystem path match (resolving symlinks and trailing slashes). 3. Matching the project's `pubspec.yaml` `appName` in `packageConfig`. 4. Returning `null` if no package can be resolved, logging a warning and skipping native assets hooks gracefully instead of crashing. Fixes flutter#192933 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing.
…package root does not match projectUri (flutter#192942) Fixes a `StateError (Bad state: No element)` crash in `testCompilerBuildNativeAssets` when running `flutter test` in a directory whose URI does not strictly match any package root in `package_config.json` (such as when working through symlinked project directories, monorepos/workspaces, or ancestor `package_config.json` files). Replaces the strict `firstWhere((Package p) => p.root == projectUri)` lookup with `findRunPackageName`, which resolves the target package name using the following fallback order: 1. Direct URI match against `projectUri`. 2. Canonicalized filesystem path match (resolving symlinks and trailing slashes). 3. Matching the project's `pubspec.yaml` `appName` in `packageConfig`. 4. Returning `null` if no package can be resolved, logging a warning and skipping native assets hooks gracefully instead of crashing. Fixes flutter#192933 ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing.
Fixes a
StateError (Bad state: No element)crash intestCompilerBuildNativeAssetswhen runningflutter testin a directory whose URI does not strictly match any package root inpackage_config.json(such as when working through symlinked project directories, monorepos/workspaces, or ancestorpackage_config.jsonfiles).Replaces the strict
firstWhere((Package p) => p.root == projectUri)lookup withfindRunPackageName, which resolves the target package name using the following fallback order:projectUri.pubspec.yamlappNameinpackageConfig.nullif no package can be resolved, logging a warning and skipping native assets hooks gracefully instead of crashing.Fixes #192933
Pre-launch Checklist
///).