Repository navigation
[flutter_tools] Reload widget-preview when data assets change - #193437
Conversation
d677123 to
98f1001
Compare
…mpty (flutter#193434) When `flutterManifest.isEmpty` (for example, a `pubspec.yaml` without a `flutter:` section), `ManifestAssetBundle.build` previously returned early with an empty `AssetManifest.bin`, ignoring any data assets produced by build/link hooks (`flutterHookResult.dataAssets`). Bug: * flutter#146264 ### Changes - Only short-circuit with an empty manifest in `ManifestAssetBundle.build` when both `flutterManifest.isEmpty` and `flutterHookResult?.dataAssets.isEmpty ?? true`. - Skip `computeTransitiveDependencies` when `flutterManifest.isEmpty`. - Add a unit test in `asset_bundle_test.dart` verifying that data assets from hooks are bundled when `pubspec.yaml` is empty. ### PR Stack | # | PR | Branch | Commit | | :-: | :--- | :--- | :--- | | **1** | **👉 flutter#193434 (this PR)** | `data-assets-empty-pubspec` | flutter@62199c4 | | 2 | flutter#193435 | `data-assets-flutter-test` | flutter@25be1ab | | 3 | flutter#193436 | `data-assets-dev-dependencies-release-test` | flutter@79abad9 | | 4 | flutter#193437 | `data-assets-widget-preview` | flutter@98f1001 | ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [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 in-code documentation (doc comments with `///`). - [x] If this PR introduces a new feature or capability, I created and linked a website documentation issue or PR in [flutter/website] (or verified none is needed). - [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.
54b2687 to
8d7fa09
Compare
…r#193435) Previously, `flutter test` ran native assets hooks via `TestCompilerNativeAssetsBuilder.build(buildInfo)`, which only returned the `NativeAssetsManifest.json` URI and discarded the `FlutterHookResult` containing hook-generated data assets. Bug: * flutter#146264 ### Changes - Add `buildWithHookResult` to `TestCompilerNativeAssetsBuilder` returning both `nativeAssetsManifest` and `flutterHookResult`. - Pass `flutterHookResult` to `_buildTestAsset` / `assetBundle.build` in `TestCommand`. - Update `TestCommand._needsRebuild` to check if bundled asset files exist on disk, guard `pub.existsSync()`, and check `flutterHookResult.dependencies` modification timestamps. - Add a hermetic test in `test_test.dart` verifying that `flutter test` bundles data assets from hooks into `build/unit_test_assets`. ### PR Stack | # | PR | Branch | Commit | | :-: | :--- | :--- | :--- | | 1 | flutter#193434 | `data-assets-empty-pubspec` | flutter@62199c4 | | **2** | **👉 flutter#193435 (this PR)** | `data-assets-flutter-test` | flutter@390c757 | | 3 | flutter#193436 | `data-assets-dev-dependencies-release-test` | flutter@cca04e9 | | 4 | flutter#193437 | `data-assets-widget-preview` | flutter@0a5a8e9 | > **Note:** This PR is stacked on flutter#193434. To review only this PR's diff before the base PR lands, view commit flutter@390c757. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [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 in-code documentation (doc comments with `///`). - [x] If this PR introduces a new feature or capability, I created and linked a website documentation issue or PR in [flutter/website] (or verified none is needed). - [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.
7ffc4e8 to
bd246d9
Compare
…n tests (flutter#193436) When running release-mode tests (such as `flutter test integration_test --release`), `createFlutterNativeAssetsBuildRunner` previously set `includeDevDependencies = !buildMode.isRelease`, which excluded hooks from `dev_dependencies`. Bug: * flutter#146264 ### Changes - Check `_isTestTarget(environment)` (whether `kTargetFile` is under `integration_test/`, `test_driver/`, or `test/`) so `includeDevDependencies` is `true` for test targets even in release mode. - Add a unit test in `native_assets_test.dart` verifying `includeDevDependencies` is `false` for `lib/main.dart` in release mode and `true` for `integration_test/app_test.dart`, `test_driver/app.dart`, and `test/app_test.dart`. ### PR Stack | # | PR | Branch | Commit | | :-: | :--- | :--- | :--- | | 1 | flutter#193434 | `data-assets-empty-pubspec` | flutter@ab37f42 | | 2 | flutter#193435 | `data-assets-flutter-test` | flutter@4956c97 | | **3** | **👉 flutter#193436 (this PR)** | `data-assets-dev-dependencies-release-test` | flutter@596124d | | 4 | flutter#193437 | `data-assets-widget-preview` | flutter@bd246d9 | ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [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 in-code documentation (doc comments with `///`). - [x] If this PR introduces a new feature or capability, I created and linked a website documentation issue or PR in [flutter/website] (or verified none is needed). - [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.
bd246d9 to
cdc64dd
Compare
There was a problem hiding this comment.
Code Review
This pull request adds support for triggering widget preview reloads when non-Dart files are modified by introducing an onNonDartFileChangeDetected callback to PreviewDetector and LspPreviewDetector. Review feedback recommends wrapping the asynchronous restart() call in unawaited to satisfy lint rules, and highlights a discrepancy where LspPreviewDetector fails to trigger the callback for Dart files outside the analysis context, such as hook scripts.
| if (!filePath.isDartFile) { | ||
| onNonDartFileChangeDetected?.call(filePath); | ||
| return; | ||
| } |
There was a problem hiding this comment.
In LspPreviewDetector, Dart files that are outside the analysis context (such as hook scripts) will bypass the !filePath.isDartFile check and will not trigger onNonDartFileChangeDetected. This is a discrepancy from PreviewDetector (which catches them via StateError on _collection.contextFor(eventPath)). As a result, modifications to hook scripts won't trigger a rebuild/restart when using the LSP preview detector.
There was a problem hiding this comment.
AI response: In LspPreviewDetector._fileAddedOrUpdated, all .dart file changes (including hook scripts) proceed to waitForAnalysis(), fetch dtd.getFlutterWidgetPreviews(), and invoke onChangeDetected(result), which triggers _triggerReload(.hotReload) and rebuilds the asset bundle when assetBundle.needsBuild() is true. PreviewDetector only needed onNonDartFileChangeDetected in its on StateError catch block because _collection.contextFor(eventPath) returns early before onChangeDetected for excluded Dart files.
cdc64dd to
431b96e
Compare
flutter/flutter@426be96...5c7e45a 2026-10-15 [email protected] [web_paragraph] Honor TextHeightBehavior.leadingDistribution and default to proportional (flutter/flutter#193736) 2026-10-15 [email protected] Roll Skia from 79a00d7c4898 to d131b7789482 (2 revisions) (flutter/flutter#194446) 2026-10-15 [email protected] Roll Dart SDK from b8ffa9233096 to 84686ea04815 (1 revision) (flutter/flutter#194442) 2026-10-15 [email protected] Roll Dart SDK from e81af2dac9d1 to b8ffa9233096 (1 revision) (flutter/flutter#194432) 2026-10-15 [email protected] Roll Skia from ef24b8f87a2a to 79a00d7c4898 (4 revisions) (flutter/flutter#194431) 2026-10-15 [email protected] Roll Skia from 48c51004ee4e to ef24b8f87a2a (1 revision) (flutter/flutter#194427) 2026-10-15 [email protected] Roll Dart SDK from 6b50116630d0 to e81af2dac9d1 (5 revisions) (flutter/flutter#194422) 2026-10-15 [email protected] Roll Skia from b1be97266d3a to 48c51004ee4e (10 revisions) (flutter/flutter#194421) 2026-10-15 [email protected] RawAutocomplete: Fix focusNode listener mismatch in didUpdateWidget/dispose (flutter/flutter#190686) 2026-10-14 [email protected] [flutter_tools] Wait for iOS simulator log stream before launch (flutter/flutter#193142) 2026-10-14 [email protected] Move Material/Cupertino PRs from design triage to framework triage (flutter/flutter#194244) 2026-10-14 [email protected] refactor(flutter_tools): share FlutterCommand options and OptionBundles (flutter/flutter#194356) 2026-10-14 [email protected] Roll pub packages (flutter/flutter#194413) 2026-10-14 [email protected] Add ContextMenuButtonKind (flutter/flutter#193528) 2026-10-14 [email protected] Split SwiftPM plugin into multiple products (flutter/flutter#193521) 2026-10-14 [email protected] Roll Skia from 43d707a3be0e to b1be97266d3a (8 revisions) (flutter/flutter#194392) 2026-10-14 [email protected] Roll pub packages (flutter/flutter#194398) 2026-10-14 [email protected] [flutter_tools] Migrate AndroidSdk and AndroidStudio away from globals (flutter/flutter#193650) 2026-10-14 [email protected] [flutter_tools] Reload widget-preview when data assets change (flutter/flutter#193437) 2026-10-14 [email protected] [flutter tool] suppress sub-tool analytics during first run (flutter/flutter#194320) 2026-10-14 [email protected] Roll Skia from acde3755d2e2 to 43d707a3be0e (1 revision) (flutter/flutter#194385) If this roll has caused a breakage, revert this CL and set the roller to dry run mode using the controls here: https://autoroll.skia.org/r/flutter-packages Please CC [email protected],[email protected] on the revert to ensure that a human is aware of the problem. To file a bug in Packages: https://github.com/flutter/flutter/issues/new/choose To report a problem with the AutoRoller itself, please file a bug: https://issues.skia.org/issues/new?component=1389291&template=1850622 Documentation for the AutoRoller is here: https://skia.googlesource.com/buildbot/+doc/main/autoroll/README.md
…r#193435) Previously, `flutter test` ran native assets hooks via `TestCompilerNativeAssetsBuilder.build(buildInfo)`, which only returned the `NativeAssetsManifest.json` URI and discarded the `FlutterHookResult` containing hook-generated data assets. Bug: * flutter#146264 ### Changes - Add `buildWithHookResult` to `TestCompilerNativeAssetsBuilder` returning both `nativeAssetsManifest` and `flutterHookResult`. - Pass `flutterHookResult` to `_buildTestAsset` / `assetBundle.build` in `TestCommand`. - Update `TestCommand._needsRebuild` to check if bundled asset files exist on disk, guard `pub.existsSync()`, and check `flutterHookResult.dependencies` modification timestamps. - Add a hermetic test in `test_test.dart` verifying that `flutter test` bundles data assets from hooks into `build/unit_test_assets`. ### PR Stack | # | PR | Branch | Commit | | :-: | :--- | :--- | :--- | | 1 | flutter#193434 | `data-assets-empty-pubspec` | flutter@62199c4 | | **2** | **👉 flutter#193435 (this PR)** | `data-assets-flutter-test` | flutter@390c757 | | 3 | flutter#193436 | `data-assets-dev-dependencies-release-test` | flutter@cca04e9 | | 4 | flutter#193437 | `data-assets-widget-preview` | flutter@0a5a8e9 | > **Note:** This PR is stacked on flutter#193434. To review only this PR's diff before the base PR lands, view commit flutter@390c757. ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [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 in-code documentation (doc comments with `///`). - [x] If this PR introduces a new feature or capability, I created and linked a website documentation issue or PR in [flutter/website] (or verified none is needed). - [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.
…n tests (flutter#193436) When running release-mode tests (such as `flutter test integration_test --release`), `createFlutterNativeAssetsBuildRunner` previously set `includeDevDependencies = !buildMode.isRelease`, which excluded hooks from `dev_dependencies`. Bug: * flutter#146264 ### Changes - Check `_isTestTarget(environment)` (whether `kTargetFile` is under `integration_test/`, `test_driver/`, or `test/`) so `includeDevDependencies` is `true` for test targets even in release mode. - Add a unit test in `native_assets_test.dart` verifying `includeDevDependencies` is `false` for `lib/main.dart` in release mode and `true` for `integration_test/app_test.dart`, `test_driver/app.dart`, and `test/app_test.dart`. ### PR Stack | # | PR | Branch | Commit | | :-: | :--- | :--- | :--- | | 1 | flutter#193434 | `data-assets-empty-pubspec` | flutter@ab37f42 | | 2 | flutter#193435 | `data-assets-flutter-test` | flutter@4956c97 | | **3** | **👉 flutter#193436 (this PR)** | `data-assets-dev-dependencies-release-test` | flutter@596124d | | 4 | flutter#193437 | `data-assets-widget-preview` | flutter@bd246d9 | ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [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 in-code documentation (doc comments with `///`). - [x] If this PR introduces a new feature or capability, I created and linked a website documentation issue or PR in [flutter/website] (or verified none is needed). - [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.
…r#193437) Previously, `PreviewDetector` and `LspPreviewDetector` ignored modifications to non-Dart files (and Dart files outside the analysis context, such as hook scripts), and `FlutterHookResult._wasAnyFileModifiedSince` did not treat deleted files (`FileSystemEntityType.notFound`) as modified. Bug: * flutter#146264 ### Changes - Add `onNonDartFileChangeDetected` callback to `PreviewDetector` and `LspPreviewDetector`, wired up in `WidgetPreviewStartCommand` to trigger a preview app restart when `assetBundle.needsBuild()` is `true`. - Treat `FileSystemEntityType.notFound` as modified in `FlutterHookResult._wasAnyFileModifiedSince`. - Update `lsp_preview_detector_test.dart` and `asset_bundle_test.dart`. ### PR Stack | # | PR | Branch | Commit | | :-: | :--- | :--- | :--- | | 1 | flutter#193434 | `data-assets-empty-pubspec` | flutter@ab37f42 | | 2 | flutter#193435 | `data-assets-flutter-test` | flutter@4956c97 | | 3 | flutter#193436 | `data-assets-dev-dependencies-release-test` | flutter@416d09a | | **4** | **👉 flutter#193437 (this PR)** | `data-assets-widget-preview` | flutter@431b96e | ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [AI contribution guidelines] and understand my responsibilities, or I am not using AI tools. - [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 in-code documentation (doc comments with `///`). - [x] If this PR introduces a new feature or capability, I created and linked a website documentation issue or PR in [flutter/website] (or verified none is needed). - [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.
Previously,
PreviewDetectorandLspPreviewDetectorignored modifications to non-Dart files (and Dart files outside the analysis context, such as hook scripts), andFlutterHookResult._wasAnyFileModifiedSincedid not treat deleted files (FileSystemEntityType.notFound) as modified.Bug:
hook/build.dartData assets support #146264Changes
onNonDartFileChangeDetectedcallback toPreviewDetectorandLspPreviewDetector, wired up inWidgetPreviewStartCommandto trigger a preview app restart whenassetBundle.needsBuild()istrue.FileSystemEntityType.notFoundas modified inFlutterHookResult._wasAnyFileModifiedSince.lsp_preview_detector_test.dartandasset_bundle_test.dart.PR Stack
data-assets-empty-pubspecdata-assets-flutter-testdata-assets-dev-dependencies-release-testdata-assets-widget-previewPre-launch Checklist
///).