Repository navigation
[tool] Migrate ResidentRunner, HotRunner, and ColdRunner to modular dependency injection - #192831
Conversation
There was a problem hiding this comment.
Code Review
This pull request refactors the Flutter tools codebase by replacing references to global variables with dependency injection across multiple commands, runners, and test files to improve modularity. Feedback on the changes includes resolving a correctness bug in ResidentRunner where multiple distinct MemoryFileSystem instances are instantiated when fileSystem is null, and a recommendation to eliminate redundant instantiations of OperatingSystemUtils in AppDomain.
…utterDevice.create
…ependency injection
5e29d66 to
ea53f23
Compare
…ap in runner.dart
# Conflicts: # packages/flutter_tools/lib/src/resident_runner.dart
# Conflicts: # packages/flutter_tools/test/general.shard/cold_test.dart # packages/flutter_tools/test/general.shard/hot_test.dart
# Conflicts: # packages/flutter_tools/lib/src/commands/run.dart # packages/flutter_tools/lib/src/resident_runner.dart
…gToolContext in runner tests
…rDriverFactory, and Daemon
|
autosubmit label was removed for flutter/flutter/192831, because - The status or check suite Google testing has failed. Please fix the issues identified (or deflake) before re-applying this label. |
|
autosubmit label was removed for flutter/flutter/192831, because Pull request flutter/flutter/192831 is not in a mergeable state. |
# Conflicts: # packages/flutter_tools/lib/src/resident_runner.dart
…eview and trigger hot restart (flutter#193968) Reverts: [[flutter_tools] Intercept prohibited hot reloads in widget preview and trigger hot restart](flutter#193447) Initiated by: @bkonyi Reason for reverting: conflicting changes with flutter#192831 are causing failures due to concurrent merge Original PR Author: @bkonyi Reviewed By: @srawlins The original PR description is provided below: When hot reload fails due to unsupported changes (such as class hierarchy modifications, global initializer changes, or file additions/deletions) in `flutter widget-preview`, automatically fall back to a hot restart instead of leaving the previewer in a failed reload state. ### Changes - **`ResidentWebRunner`**: Attach `updateFSReport` to the failed `OperationResult` when `_updateDevFS` fails so callers can inspect `UpdateFSReport.hotReloadRejected`. - **`WidgetPreviewStartCommand`**: Introduce `handleReload()` (invoked inside `_triggerReload` for `.hotReload` requests so the fallback remains serialized with other reload and restart requests, and add a `@visibleForTesting` `widgetPreviewApp` setter), which checks if `restart()` returned an `OperationResult` with `UpdateFSReport(hotReloadRejected: true)`. When rejected, log a status message (`kHotReloadRejectedMessage`) and invoke `restart(fullRestart: true)`. Fixes flutter#192697 ## 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. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…ependency injection (flutter#192831) ## Summary Part 22b of the modular dependency injection migration. * Migrates `ResidentRunner`, `HotRunner`, `ColdRunner`, and `ResidentWebRunner` to modular constructor dependency injection. * Injects `BuildSystem`, `BuildTargets`, and `Xcode` through `DaemonCommand`, `Daemon`, `AppDomain`, `AttachCommand`, `RunCommand.createRunner`, `WebDriverService.start`, and `WidgetPreviewStartCommand`. * Makes `toolContext` non-nullable with `const DelegatingToolContext()` default in `createHotRunner`, `createColdRunner`, and `setUpResidentRunner` test helpers, and migrates unit tests in `attach_test.dart`, `daemon_test.dart`, `cold_test.dart`, `hot_test.dart`, `resident_runner_test.dart`, and `resident_web_runner_test.dart`. Fork diff: bkonyi/flutter@master...di/22b-resident-runner Part of flutter#188471
…eview and trigger hot restart (flutter#193968) Reverts: [[flutter_tools] Intercept prohibited hot reloads in widget preview and trigger hot restart](flutter#193447) Initiated by: @bkonyi Reason for reverting: conflicting changes with flutter#192831 are causing failures due to concurrent merge Original PR Author: @bkonyi Reviewed By: @srawlins The original PR description is provided below: When hot reload fails due to unsupported changes (such as class hierarchy modifications, global initializer changes, or file additions/deletions) in `flutter widget-preview`, automatically fall back to a hot restart instead of leaving the previewer in a failed reload state. ### Changes - **`ResidentWebRunner`**: Attach `updateFSReport` to the failed `OperationResult` when `_updateDevFS` fails so callers can inspect `UpdateFSReport.hotReloadRejected`. - **`WidgetPreviewStartCommand`**: Introduce `handleReload()` (invoked inside `_triggerReload` for `.hotReload` requests so the fallback remains serialized with other reload and restart requests, and add a `@visibleForTesting` `widgetPreviewApp` setter), which checks if `restart()` returned an `OperationResult` with `UpdateFSReport(hotReloadRejected: true)`. When rejected, log a status message (`kHotReloadRejectedMessage`) and invoke `restart(fullRestart: true)`. Fixes flutter#192697 ## 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. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
…sts that run the real pub The hermetic commands shard had left out nine files and the permeable half entirely: their tests resolve a project of their own with the real pub (the widget_preview tests' scaffold, `flutter create`'s projects, `flutter pub get` on plugins), and pub wants a Flutter SDK -- not just the Dart SDK and engine stamps the general shard's facsimile under bin/cache already had. This lays the rest of pub's view of an SDK in the runfiles tree, and a pub cache of what the projects reach, so no test downloads a package: * `pub_cache(name, roots, dev_roots, without)` (dart/pub.bzl): the hosted packages of a closure, laid as a pub cache (`hosted/pub.dev/<name>-<version>/` plus the `hosted-hashes` sha256 pub checks) from the pinned sources `@pub` already fetches. dart_test's new `pub_cache` attribute symlinks it under the runfiles `.pub-cache` and the launcher exports PUB_CACHE. pub still asks pub.dev which versions exist unless it runs `--offline` (the tests do not), so such a shard has the network; it downloads nothing it finds in the cache (one package -- webview_flutter_web, outside the workspace's lock -- it does fetch). * `bin/cache/flutter.version.json` (bin/internal: `flutter_version_json`): pub's Flutter SDK source reads `flutterVersion` from it and checks it against the packages' `flutter:` constraints (leak_tracker_flutter_testing wants >=3.18); the tool parses `frameworkVersion` as a git tag. Fixed words again: 999.0.0-0.0.pre, the version every constraint allows. * The SDK packages under FLUTTER_ROOT/packages (flutter, flutter_test, flutter_localizations, flutter_driver, integration_test, fuchsia_remote_debug_protocol and a new BUILD for flutter_web_plugins), the workspace's pubspec.yaml and pubspec.lock (`flutter create` reads the SDK's lock), and the engine's sky_engine package under `bin/cache/pkg/sky_engine` (the analyzer resolves dart:ui from it): `assembled_directory(contents, prefix)` in local_engine.bzl is the `install`/`local_engine` assembly as a rule of its own, and `//engine/src/flutter/sky/packages/sky_engine:package` (a converter appendix) lays dart_pkg's directory and the copied libraries as GN's `gen/dart-pkg/sky_engine`. * `<dart-sdk>/version` in the SDK overlay's `dart` filegroup: the analyzer (`AnalysisContextCollection` with `sdkPath`) reads it; six widget_preview tests needed only this. * `@gradle_wrapper` (flutter_sdk_cache.bzl, from bin/internal's pin): `flutter create` copies `bin/cache/artifacts/gradle_wrapper` into an Android project. * `dart_tests(large = [...])`, as flutter_tests has it: preview_detector_test, preview_detector_workspace_test and preview_code_generator_test take minutes on a loaded machine (the first timed out at 300 s). * //bin:BUILD.bazel exports the Windows entrypoint scripts as text (script_test reads them for what they must not do); the Unix ones stay out on purpose -- a test that finds bin/flutter spawns it, and the script bootstraps the tool from the network. integration_test's `sources` gain its Android embedding: the package is a plugin, and the tool reads the main class when a project that depends on it resolves. `//packages/flutter_tools:commands_shard_hermetic` is now the whole directory (67 files, up from 58); `commands_shard_permeable` is new (8 of 11: create_test analyzes, resolves and tests the projects it creates with bin/cache/flutter_tools.snapshot and icon_tree_shaker_test spawns bin/flutter -- the built tool, which a later change can lay in the facsimile from Bazel's own compile; widget_preview_test does not compile at this checkout, flutter#192831 and flutter#193447 crossed and upstream reverted the latter in flutter#193968). Both are in `//:tool_tests`. The README's tests section describes the facsimile. Measured: bazel test //packages/flutter_tools:commands_shard_hermetic \ //packages/flutter_tools:commands_shard_permeable 75 of 75 targets pass; 1,140 cases passed, 6 skipped dart test (FLUTTER_ROOT set, -j 4) over the same 75 files: 1,140 + 6 bazel test //:tool_tests //:dart_tests: 406 of 406 targets pass gn_to_bazel --check clean; converter tests 231, bazel_tools tests 43.
Summary
Part 22b of the modular dependency injection migration.
ResidentRunner,HotRunner,ColdRunner, andResidentWebRunnerto modular constructor dependency injection.BuildSystem,BuildTargets, andXcodethroughDaemonCommand,Daemon,AppDomain,AttachCommand,RunCommand.createRunner,WebDriverService.start, andWidgetPreviewStartCommand.toolContextnon-nullable withconst DelegatingToolContext()default increateHotRunner,createColdRunner, andsetUpResidentRunnertest helpers, and migrates unit tests inattach_test.dart,daemon_test.dart,cold_test.dart,hot_test.dart,resident_runner_test.dart, andresident_web_runner_test.dart.Fork diff: bkonyi/flutter@master...di/22b-resident-runner
Part of #188471