Repository navigation
[flutter_tools] Add ExtensionPackageConfig manifest model and Isolate.spawnUri support - #194590
auto-submit[bot] merged 17 commits into
Conversation
…tion, and safe mode Introduce `ProjectExtensionFinder` (via `package:extension_discovery` and `extension/flutter_tools/config.yaml`), `ExtensionPackageConfig`, `ExtensionKernelCompiler` (`.dill` compilation with atomic writes and lockfiles), `--[no-]extensions` / `FLUTTER_NO_EXTENSIONS` safe mode, lazy capability filtering, and in-place `flutter create . --platforms=<custom>` support.
…onfig validation - Acquire an exclusive lockfile (.dill.lock) via FileSystemLocking.runLocked and atomically rename temporary .dill.tmp and .d.tmp outputs in ExtensionKernelCompiler.compile. - Ensure --extensions does not bypass FLUTTER_NO_EXTENSIONS=1 or enable tool extensions when the feature flag is disabled. - Validate ExtensionPackageConfig.entrypoint against path traversal and filter platform template queries by requested custom platforms. - Make FeatureFlags required on ExtensionManager and Artifacts required on ExtensionKernelCompiler, and refresh ExtensionBuildManager.getBuildTargets when new extension connections initialize.
… Isolate.spawnUri support - Scope this branch to the ExtensionPackageConfig manifest model in flutter_tools_core, Isolate.spawnUri entrypoint support in flutter_tools_extension and flutter_tools_extension_linux_prototype, and ExtensionConnection.spawnUri in extension_discovery.dart. - Split safe mode, ProjectExtensionFinder / ExtensionKernelCompiler, and dynamic discovery wiring into separate stacked PRs.
… Isolate.spawnUri
…-project-discovery
…ty, and remove handshake timeout
…roject-discovery # Conflicts: # packages/flutter_tools/lib/src/experimental/extension_discovery.dart # packages/flutter_tools/packages/flutter_tools_core/lib/flutter_tools_core.dart # packages/flutter_tools/packages/flutter_tools_extension/lib/src/protocol_base/provider.dart
… ExtensionConnection - Mark `ExtensionConnection.spawn` as `@visibleForTesting` and suppress the transitional use in `ExtensionManager.initialize()` until flutter#194774. - Add `ExtensionJsonParsing.stringSet` for parsing sets of unique strings, optionally trimming and rejecting empty entries. - Require a non-empty `services` list in `ExtensionPackageConfig`, use `stringSet` for all list fields, accept `Map<String, Object?>` in `fromMap`, and document string identifier conventions. Part of flutter#190755
… clean up ignore comment - Use a comma instead of a second `//` in the transitional suppression in `ExtensionManager.initialize()`: `// ignore: invalid_use_of_visible_for_testing_member, transitional until flutter#194774.` - Drop `protocol_version` from `ExtensionPackageConfig`, its schema documentation, and the Linux prototype `config.yaml`. Protocol compatibility is governed by `package:flutter_tools_extension` dependency versions and no runtime protocol negotiation is performed. Part of flutter#190755
There was a problem hiding this comment.
Code Review
This pull request introduces dynamic extension discovery and spawning capabilities in Flutter tools. It adds ExtensionConnection.spawnUri to dynamically spawn extension isolates from a URI, introduces the ExtensionPackageConfig class to parse static metadata from an extension's config.yaml, and provides a prototype extension for Linux. Feedback on the changes suggests removing redundant type annotations on initializing formal parameters in ExtensionConnection._ and trimming string list inputs in the ExtensionPackageConfig constructor to ensure consistency and prevent whitespace-related bugs.
…nd trim config string lists - Remove redundant `Isolate` type on initializing formal `this._isolate`. - Trim `supportedPlatforms`, `services`, `buildTargets`, and `templates` in `ExtensionPackageConfig` constructor. Part of flutter#190755
…mode (flutter#194771) Add the global `--[no-]extensions` CLI flag and `FLUTTER_NO_EXTENSIONS=1` environment variable to bypass tool extension discovery and isolate spawning, and require `FeatureFlags` on `ExtensionManager`. ### Stack - **PR 1A (parallel off `master`)**: flutter#194590 (`ft-ext-phase01-03-project-discovery`) - **PR 1B (this PR)**: flutter#194771 (`ft-ext-phase01b-safe-mode`) - **PR 1C (stacked on 1A)**: flutter#194772 (`ft-ext-phase01c-finder-and-compiler`) - **PR 1D (stacked on 1B + 1C)**: flutter#194774 (`ft-ext-phase01d-dynamic-discovery-wiring`) Part of flutter#190755 ## 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] All existing and new tests are passing.
…mode (flutter#194771) Add the global `--[no-]extensions` CLI flag and `FLUTTER_NO_EXTENSIONS=1` environment variable to bypass tool extension discovery and isolate spawning, and require `FeatureFlags` on `ExtensionManager`. ### Stack - **PR 1A (parallel off `master`)**: flutter#194590 (`ft-ext-phase01-03-project-discovery`) - **PR 1B (this PR)**: flutter#194771 (`ft-ext-phase01b-safe-mode`) - **PR 1C (stacked on 1A)**: flutter#194772 (`ft-ext-phase01c-finder-and-compiler`) - **PR 1D (stacked on 1B + 1C)**: flutter#194774 (`ft-ext-phase01d-dynamic-discovery-wiring`) Part of flutter#190755 ## 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] All existing and new tests are passing.
| static Future<ExtensionConnection> spawnUri( | ||
| Uri entrypointUri, { | ||
| required Logger logger, | ||
| required Uri packageConfigUri, |
There was a problem hiding this comment.
Is this required? If entrypoint is pointing to a dill file?
There was a problem hiding this comment.
Not strictly required by the VM for a dill, but spawnUri also runs .dart scripts directly and we want to ensure the isolate doesn't inherit the tool's own package config if it does any runtime package resolution.
…-project-discovery # Conflicts: # packages/flutter_tools/packages/flutter_tools_core/lib/flutter_tools_core.dart # packages/flutter_tools/packages/flutter_tools_core/lib/src/json_utils.dart # packages/flutter_tools/packages/flutter_tools_core/test/json_utils_test.dart
| return Set<String>.unmodifiable(<String>{ | ||
| for (final String item in items) | ||
| if (item.trim().isNotEmpty) | ||
| item.trim() |
There was a problem hiding this comment.
It's not obvious from the call site that rejectEmpty: true also trims values.
There was a problem hiding this comment.
Split trim out into its own parameter.
| if (services.isEmpty) { | ||
| throw const FormatException( | ||
| 'Extension config.yaml must specify a non-empty list of services for "$servicesKey".', | ||
| ); |
There was a problem hiding this comment.
Is this too harsh? Imagine I'm creating a new extension and before I'd like to check that the tool accepts my new extension before I add my first service.
There was a problem hiding this comment.
Fair enough. Made services optional and able to accept an empty list :)
loic-sharma
left a comment
There was a problem hiding this comment.
LGTM, comments are only nits
…-project-discovery # Conflicts: # packages/flutter_tools/lib/src/experimental/extension_discovery.dart # packages/flutter_tools/test/general.shard/extension_protocol/extension_discovery_test.dart
… ToolExtensionEntryPoint
…xtension_discovery_test.dart Use `package:flutter_tools/src/base/file_system.dart` and `LocalFileSystem.test(signals: LocalSignals.instance)` in `extension_discovery_test.dart` so `forbidden_imports_test.dart` passes on CI.
…mode (flutter#194771) Add the global `--[no-]extensions` CLI flag and `FLUTTER_NO_EXTENSIONS=1` environment variable to bypass tool extension discovery and isolate spawning, and require `FeatureFlags` on `ExtensionManager`. ### Stack - **PR 1A (parallel off `master`)**: flutter#194590 (`ft-ext-phase01-03-project-discovery`) - **PR 1B (this PR)**: flutter#194771 (`ft-ext-phase01b-safe-mode`) - **PR 1C (stacked on 1A)**: flutter#194772 (`ft-ext-phase01c-finder-and-compiler`) - **PR 1D (stacked on 1B + 1C)**: flutter#194774 (`ft-ext-phase01d-dynamic-discovery-wiring`) Part of flutter#190755 ## 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] All existing and new tests are passing.
…fact-service Adds the `artifact` service to the Linux prototype's `config.yaml` and to the `extension_discovery_test.dart` fixture as required by the manifest services check from flutter#194590, and fixes the `'artifacts'` namespace in the `ExtensionPackageConfig` docs.
Introduce
ExtensionPackageConfiginpackage:flutter_tools_corefor parsingextension/flutter_tools/config.yamlmanifests,Isolate.spawnUrientrypoint support inToolExtensionEntryPoint.runandpackage:flutter_tools_extension_linux_prototype, andExtensionConnection.spawnUri(withexpectedConfigcapability validation) influtter_tools.Stack
ft-ext-phase01-03-project-discovery)ft-ext-phase01b-safe-mode)ft-ext-phase01c-finder-and-compiler)ft-ext-phase01d-dynamic-discovery-wiring)Part of #190755
Pre-launch Checklist
///).