Repository navigation
[flutter_tools] Implement Device Service extension and flutter devices integration - #192126
Conversation
Implements the Templates extension service and integrates dynamic custom template support into `flutter create` and `package:flutter_tools_core`.
- `package:flutter_tools_core`:
- Adds `ProjectTemplate` and `ExtensionProjectTemplate` domain models with JSON serialization, hashing, and equality in `lib/src/templates.dart`.
- Exports template models from `lib/flutter_tools_core.dart`.
- `package:flutter_tools_extension`:
- Defines `TemplateService` RPC interface and handlers for `template.getAppTemplates`, `template.getPluginTemplates`, `template.getProjectTemplates`, and `template.generateTemplateParameters` in `lib/src/templates.dart`.
- `package:flutter_tools_extension_linux_prototype`:
- Implements `LinuxTemplateService` and `LinuxProjectTemplate` declaring custom template `'custom-linux-app'` with `templateDependencies: {'app'}`.
- Adds prototype template assets for `'custom-linux-app'`.
- `packages/flutter_tools`:
- Adds `ExtensionTemplateManager` in `lib/src/experimental/templates.dart` to discover custom templates over RPC, cache them, resolve directories, and delegate parameter generation.
- Updates `Template.fromDirectories` in `lib/src/template.dart` to merge directory sources with base template dependencies.
- Updates `CreateCommand` and `ExtensionArgParserMixin` to dynamically populate `--template` CLI options and help entries.
- Updates `FlutterProjectMetadata` and `ParsedFlutterTemplateType` to support `ExtensionProjectTemplateType`.
- Wires `ExtensionTemplateManager` through `executable.dart` into `CreateCommand`.
- Adds unit, hermetic usage, and integration test coverage across all layers.
… integration test
…plates-slice # Conflicts: # packages/flutter_tools/lib/src/experimental/extension_arg_parser.dart
…plates.dart Co-authored-by: Loïc Sharma <[email protected]>
…plates.dart Co-authored-by: Loïc Sharma <[email protected]>
…and CreateCommand
…move unused fallbackToCustom
…plates.dart Co-authored-by: Loïc Sharma <[email protected]>
…traneous newline in context_runner
…s integration Implement the Device Service and integrate it with device discovery and `flutter devices` CLI command to support dynamic custom devices from tool extensions. - Define `TargetDevice` core data structure in `package:flutter_tools_core`. - Define `DeviceService` extension service interface in `package:flutter_tools_extension`. - Implement `LinuxDeviceService` prototype in `package:flutter_tools_extension_linux_prototype`. - Implement `ExtensionDeviceDiscovery`, `ExtensionDeviceClient`, and `ExtensionBackedDevice` in `packages/flutter_tools/lib/src/experimental/extension_device_manager.dart`. - Inject `ExtensionDeviceDiscovery` into `FlutterDeviceManager`. - Add hermetic CLI integration tests in `tool_extensions_device_test.dart`.
There was a problem hiding this comment.
Code Review
This pull request introduces support for custom project templates and target devices provided dynamically by tool extensions. It adds ExtensionTemplateManager and ExtensionDeviceDiscovery to handle querying templates and discovering devices from active extensions, integrating these into the create and devices commands. It also defines core models and services in flutter_tools_core and flutter_tools_extension, along with a prototype implementation for Linux. Feedback on the changes includes fixing invalid Dart syntax in TargetDevice.toMap() where ? is used in a map literal, adding a null check for Cache.flutterRoot in ExtensionTemplateManager.resolveTemplateDirectory to prevent potential null pointer exceptions, and fully populating the allowed list with both static and dynamic templates when rebuilding the dynamic parser in CreateCommand to enable automatic CLI validation.
…ommand - Guard `Cache.flutterRoot` with an explicit null check in `ExtensionTemplateManager.resolveTemplateDirectory`. - Populate `allowed` option values for dynamic and static templates in `CreateCommand.buildDynamicArgParser`.
…ice-slice # Conflicts: # packages/flutter_tools/lib/src/commands/create.dart # packages/flutter_tools/lib/src/experimental/templates.dart # packages/flutter_tools/packages/flutter_tools_extension_linux_prototype/lib/flutter_tools_extension_linux_prototype.dart
|
/gemini review |
There was a problem hiding this comment.
Code Review
This pull request introduces support for tool extension-backed devices in flutter_tools by adding ExtensionDeviceDiscovery and ExtensionBackedDevice to discover and wrap devices registered by active extensions, and integrating them into FlutterDeviceManager and DevicesCommand. Feedback highlights a compilation error in TargetDevice.toMap() due to invalid Dart syntax (?sdkNameAndVersion and ?targetPlatform), and raises an architectural concern regarding the dynamic mutation of globals.deviceManager?.deviceDiscoverers inside DevicesCommand, suggesting global initialization instead.
…y and remove ad-hoc discoverer mutation
…ager in DevicesCommand
… simplify serialization
loic-sharma
left a comment
There was a problem hiding this comment.
Apologies for the very delayed review. Overall this looks good to me! My only real concern is the dependency injection.
…sionDevices - Wire `ExtensionManager` into `FlutterDeviceManager` via `executable.dart` and `context_runner.dart`, reverting `DevicesCommand` changes. - Make `ExtensionBackedDevice.connection` required and non-nullable. - Rename `ExtensionDeviceDiscovery` to `ExtensionDevices`. - Expand documentation on `TargetDevice.ephemeral`. - Pass `projectRoot` to `DeviceService.getDevices` so extensions can compute `isSupportedForProject`. - Move `Category` enum to `package:flutter_tools_core` and use `Category` on `TargetDevice`. - Remove `platformType` from `TargetDevice` and default `ExtensionBackedDevice.platformType` to `PlatformType.custom`.
…ILD export - Alias `Category` in `packages/flutter_tools/lib/src/device.dart` via `typedef Category = tools_core.Category;` instead of re-exporting from `package:flutter_tools_core`. - Hide `Category` from `package:flutter_tools_core` import in `doctor_test.dart`. - Use private initializing formals in `ExtensionDeviceClient` and `ExtensionDevices` constructors.
… and Category.other - Add `globals.extensionManager` getter and instantiate `ExtensionManager` directly in the `overrides` callback in `executable.dart`. - Use `globals.extensionManager` when constructing `FlutterDeviceManager` in `context_runner.dart`. - Add `Category.other` to `enum Category` in `package:flutter_tools_core`.
- Initialize `late final ExtensionManager extensionManager` in `executable.dart` using `ToolDependencies` and expose it in `overrides` via `ExtensionManager: () => extensionManager`. - Read `overrides?[ExtensionManager]?.call() as ExtensionManager?` in `context_runner.dart` instead of adding `globals.extensionManager` to `globals.dart`.
|
@bkonyi FYI, there are still some unaddressed questions above :) |
…oolDependencies - Merge `upstream/master` (flutter#193524) and pass `ExtensionManager` directly to `FlutterDeviceManager` inside `ToolDependencies.bootstrap`. - Forward `extensionEntryPoints` from `executable.dart` through `runner.run` into `ToolDependencies.bootstrap`. - Remove the `overrides[ExtensionManager]` workaround from `executable.dart` and `context_runner.dart`. - Fix formatting in `packages/flutter_tools_extension/lib/src/device.dart` and `packages/flutter_tools/lib/src/commands/devices.dart`.
…tstrap and generateCommands Removes the unused `ExtensionManager? extensionManager` parameter from `ToolDependencies.bootstrap` and `generateCommands`, reading `toolDependencies.extensionManager` directly inside `generateCommands`.
…isSupportedForProject FutureOr<bool>
Decouples project support checks from device discovery by adding a separate `device.isSupportedForProject` RPC method on `DeviceService` (`isSupportedForProject({required String deviceId, required Uri projectRoot})`), removing `isSupportedForProject` from `TargetDevice`, and updating `Device.isSupportedForProject` to return `FutureOr<bool>`.
|
autosubmit label was removed for flutter/flutter/192126, because - The status or check suite Dashboard Checks has failed. Please fix the issues identified (or deflake) before re-applying this label. |
…s integration (flutter#192126) Implement `DeviceService` and integrate it with `FlutterDeviceManager` to support dynamic custom devices from tool extensions. - Define `Category` (`web`, `desktop`, `mobile`, `other`) and `TargetDevice` in `package:flutter_tools_core`. - Define the `DeviceService` extension service interface (`device.getDevices` and `device.isSupportedForProject`) in `package:flutter_tools_extension`. - Implement `LinuxDeviceService` in `package:flutter_tools_extension_linux_prototype`. - Implement `ExtensionDevices`, `ExtensionDeviceClient`, and `ExtensionBackedDevice` in `packages/flutter_tools/lib/src/experimental/extension_device_manager.dart`, and update `Device.isSupportedForProject` to return `FutureOr<bool>`. - Bootstrap `ExtensionManager` in `ToolDependencies.bootstrap` and wire it into `FlutterDeviceManager`. - Add unit, hermetic, and integration test coverage across `flutter_tools_core`, `flutter_tools_extension_linux_prototype`, and `flutter_tools`. Part of flutter#190692 --------- Co-authored-by: Loïc Sharma <[email protected]>
Implement
DeviceServiceand integrate it withFlutterDeviceManagerto support dynamic custom devices from tool extensions.Category(web,desktop,mobile,other) andTargetDeviceinpackage:flutter_tools_core.DeviceServiceextension service interface (device.getDevicesanddevice.isSupportedForProject) inpackage:flutter_tools_extension.LinuxDeviceServiceinpackage:flutter_tools_extension_linux_prototype.ExtensionDevices,ExtensionDeviceClient, andExtensionBackedDeviceinpackages/flutter_tools/lib/src/experimental/extension_device_manager.dart, and updateDevice.isSupportedForProjectto returnFutureOr<bool>.ExtensionManagerinToolDependencies.bootstrapand wire it intoFlutterDeviceManager.flutter_tools_core,flutter_tools_extension_linux_prototype, andflutter_tools.Part of #190692