Repository navigation
feat(flutter_tools): migrate Apple build commands to typed options - #192818
Conversation
…ions # Conflicts: # packages/flutter_tools/lib/src/runner/flutter_command.dart
There was a problem hiding this comment.
Code Review
This pull request refactors command-line option registration across several Apple-related build commands to use a structured, descriptor-based approach with OptionDescriptor and OptionBundle. A critical compilation issue was identified in DarwinAddToAppOptionsBundle.onRegister, where the non-existent methods enableUsesTargetOption and enableUsesPubOption are called on FlutterCommand instead of usesTargetOption and usesPubOption.
…ions # Conflicts: # packages/flutter_tools/lib/src/commands/build_ios.dart # packages/flutter_tools/lib/src/commands/build_macos.dart
|
@kevmoo some tests are failing: |
…ateTests
`BuildSwiftPackage.generateTests` previously checked `boolArg('ci', global: true)`,
which is only true when `--ci` is explicitly passed on the command line.
Using `usingCISystem` caused `generateTests` to return `true` whenever
`LUCI_CI=True` was set in the environment on LUCI bots (breaking
`swift_package_manager_add2app_test.dart` in `Mac tool_integration_tests_8`).
- Add `CommonOptions.ci` (`OptionScope.global`) for `--ci` and register it in `FlutterCommandRunner`.
- Update `FlutterCommand.usingCISystem` and `BuildSwiftPackage.generateTests` to read `getValue(CommonOptions.ci)`.
- Add hermetic regression test in `build_swift_package_test.dart`.
|
Thanks for flagging, @okorohelijah! Fixed in 45abce6. Root cause: We added a typed global descriptor |
…lutter#193323) Migrate `BuildLinuxCommand` (`build linux`) and `BuildWindowsCommand` (`build windows`) to typed `OptionDescriptor`s and `OptionBundle`s (following flutter#191018, flutter#191510, flutter#191760, flutter#192307, flutter#192455, flutter#192524, and flutter#192818): - Add `DesktopBuildOptionsBundle` in `common_options.dart`, encapsulating `CommonBuildOptionsBundle`, `BuildModeOptionsBundle`, `DartCompileOptionsBundle`, `BuildInfoOptions.flavor`, `splitDebugInfo`, `obfuscate`, `extraFrontEndOptions`, `extraGenSnapshotOptions`, `performanceMeasurementFile`, `analyzeSize`, `codeSizeDirectory`, `trackWidgetCreation`, and `configOnly`. - Migrate `BuildLinuxCommand` (`build_linux.dart`) to `DesktopBuildOptionsBundle`, `DefaultedEnumOptionDescriptor<TargetPlatform>` (`_targetPlatformOption`), and `DefaultedStringOptionDescriptor` (`_targetSysroot`), replacing untyped `boolArg('config-only')`, `stringArg('target-platform')!`, and `stringArg('target-sysroot')!` queries. - Migrate `BuildWindowsCommand` (`build_windows.dart`) to `DesktopBuildOptionsBundle` and `getValue(DesktopBuildOptionsBundle.configOnly)`. - Delete the obsolete `FlutterCommand.addCommonDesktopBuildOptions` helper method from `flutter_command.dart` (no remaining callers in `flutter_tools`). ## 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]. - [ ] 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.
…lutter#194017) ### Rationale `FlutterTestRunner.runTests` accepted 33 loose parameters (duplicating 23 of them on `runTestsBySpawningLightweightEngines` alongside duplicated `package:test` CLI argument lists), and `DriverService.startTest` accepted 12 loose parameters fed by untyped `boolArg` / `stringArg` / regex splitting in `TestCommand` and `DriveCommand`. Following flutter#191018, flutter#191510, flutter#191760, flutter#192307, flutter#192455, flutter#192524, flutter#192818, and flutter#193323, this change introduces immutable service-layer specification objects and migrates `TestCommand` and `DriveCommand` to typed `OptionDescriptor`s. ### Summary of Changes - Introduce `@immutable class TestFilterSpecification` and `@immutable class TestExecutionSpecification` (with `toPackageTestArgs()`) in `test/runner.dart`, shrinking `FlutterTestRunner.runTests` from 33 parameters to 3 (`testWrapper`, `testFiles`, `spec`) and `runTestsBySpawningLightweightEngines` from 25 parameters to 2 (`testFiles`, `spec`). - Migrate `TestCommand` (`commands/test.dart`) from inline `argParser` registrations and untyped `boolArg`/`stringArg`/`stringsArg` queries to private typed `OptionDescriptor` constants (`argParser.addDescriptors` + `getValue` / `wasParsed`), and update `bin/fuchsia_tester.dart`. - Introduce `@immutable class DriveTestSpecification` (with `parseBrowserDimension`) in `drive/drive_service.dart`, shrinking `DriverService.startTest` (and `FlutterDriverService` / `WebDriverService`) from 12 parameters to 2 (`testFile`, `spec`). - Migrate `DriveCommand` (`commands/drive.dart`) from inline registrations and ad-hoc string/int/enum parsing to private typed `OptionDescriptor` constants (`IntOptionDescriptor`, `DefaultedEnumOptionDescriptor<Browser>`, etc.) and `DriveTestSpecification`. - Update unit tests across `test_test.dart`, `drive_test.dart`, `drive_service_test.dart`, and `web_driver_service_test.dart`. ### Flow / Surface Delta ```mermaid flowchart LR A["TestCommand (OptionDescriptors)"] --> B["TestExecutionSpecification"] B --> C["FlutterTestRunner.runTests(spec)"] D["DriveCommand (OptionDescriptors)"] --> E["DriveTestSpecification"] E --> F["DriverService.startTest(spec)"] ``` ### Verification - Executed `dart analyze --fatal-infos` on `packages/flutter_tools` with 0 issues. - Executed `dart test` across `test_test.dart`, `drive_test.dart`, `drive_service_test.dart`, and `web_driver_service_test.dart` (`148/148` passing). ## 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]. - [ ] 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.
…fig to AndroidBuildInfo (flutter#194016) ### Rationale `BuildInfo` is the cross-platform build configuration passed across Android, iOS, Web, Desktop, and Fuchsia targets, yet it carried 6 loose Android/Gradle fields (`androidProjectArgs`, `androidGradleProjectCacheDir`, `androidGradleDaemon`, `androidSkipBuildDependencyValidation`, `androidEnableHcpp`, `explicitAndroidEnableHcpp`) and the Gradle `-P` flag serializer `toGradleConfig()`. Following flutter#191018, flutter#191510, flutter#191760, flutter#192307, flutter#192455, flutter#192524, flutter#192818, and flutter#193323, this change encapsulates those fields into `AndroidGradleConfig` and moves `toGradleConfig()` onto `AndroidBuildInfo` where all production callers already operate. ### Summary of Changes - Introduce `@immutable class AndroidGradleConfig` in `build_info.dart` and replace the 6 loose `android*` parameters on `BuildInfo` and `BuildInfo.copyWith` with `androidGradleConfig` (shrinking `BuildInfo`'s constructor from 28 to 23 parameters while preserving `AndroidDevice.startApp` forwarding during `flutter run`). - Move `toGradleConfig()` off `BuildInfo` onto `AndroidBuildInfo` (with zero `@deprecated` forwarders) and add `gradleDaemon` and `skipBuildDependencyValidation` convenience getters on `AndroidBuildInfo`. - Update `FlutterCommand.getBuildInfo()` in `flutter_command.dart` to construct `AndroidGradleConfig`. - Update `buildGradleApp`, `buildGradleAar`, and `_checkJavaAndGradleCompatibility` in `gradle.dart` to read Gradle configuration via `AndroidBuildInfo`. - Update unit tests across `build_info_test.dart`, `flutter_command_test.dart`, `android_gradle_builder_test.dart`, and `build_aar_test.dart`. ### Flow / Surface Delta ```mermaid flowchart LR A["FlutterCommand.getBuildInfo()"] --> B["BuildInfo(androidGradleConfig)"] B --> C["AndroidBuildInfo.toGradleConfig()"] C --> D["gradle.dart (-P flags)"] ``` ### Verification - Executed `dart analyze --fatal-infos` on `packages/flutter_tools` with 0 issues. - Executed `dart test` across `build_info_test.dart`, `flutter_command_test.dart`, `android_gradle_builder_test.dart`, and `build_aar_test.dart` (`160/160` passing). ## 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]. - [ ] 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.
…lutter#193323) Migrate `BuildLinuxCommand` (`build linux`) and `BuildWindowsCommand` (`build windows`) to typed `OptionDescriptor`s and `OptionBundle`s (following flutter#191018, flutter#191510, flutter#191760, flutter#192307, flutter#192455, flutter#192524, and flutter#192818): - Add `DesktopBuildOptionsBundle` in `common_options.dart`, encapsulating `CommonBuildOptionsBundle`, `BuildModeOptionsBundle`, `DartCompileOptionsBundle`, `BuildInfoOptions.flavor`, `splitDebugInfo`, `obfuscate`, `extraFrontEndOptions`, `extraGenSnapshotOptions`, `performanceMeasurementFile`, `analyzeSize`, `codeSizeDirectory`, `trackWidgetCreation`, and `configOnly`. - Migrate `BuildLinuxCommand` (`build_linux.dart`) to `DesktopBuildOptionsBundle`, `DefaultedEnumOptionDescriptor<TargetPlatform>` (`_targetPlatformOption`), and `DefaultedStringOptionDescriptor` (`_targetSysroot`), replacing untyped `boolArg('config-only')`, `stringArg('target-platform')!`, and `stringArg('target-sysroot')!` queries. - Migrate `BuildWindowsCommand` (`build_windows.dart`) to `DesktopBuildOptionsBundle` and `getValue(DesktopBuildOptionsBundle.configOnly)`. - Delete the obsolete `FlutterCommand.addCommonDesktopBuildOptions` helper method from `flutter_command.dart` (no remaining callers in `flutter_tools`). ## 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]. - [ ] 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.
…lutter#194017) ### Rationale `FlutterTestRunner.runTests` accepted 33 loose parameters (duplicating 23 of them on `runTestsBySpawningLightweightEngines` alongside duplicated `package:test` CLI argument lists), and `DriverService.startTest` accepted 12 loose parameters fed by untyped `boolArg` / `stringArg` / regex splitting in `TestCommand` and `DriveCommand`. Following flutter#191018, flutter#191510, flutter#191760, flutter#192307, flutter#192455, flutter#192524, flutter#192818, and flutter#193323, this change introduces immutable service-layer specification objects and migrates `TestCommand` and `DriveCommand` to typed `OptionDescriptor`s. ### Summary of Changes - Introduce `@immutable class TestFilterSpecification` and `@immutable class TestExecutionSpecification` (with `toPackageTestArgs()`) in `test/runner.dart`, shrinking `FlutterTestRunner.runTests` from 33 parameters to 3 (`testWrapper`, `testFiles`, `spec`) and `runTestsBySpawningLightweightEngines` from 25 parameters to 2 (`testFiles`, `spec`). - Migrate `TestCommand` (`commands/test.dart`) from inline `argParser` registrations and untyped `boolArg`/`stringArg`/`stringsArg` queries to private typed `OptionDescriptor` constants (`argParser.addDescriptors` + `getValue` / `wasParsed`), and update `bin/fuchsia_tester.dart`. - Introduce `@immutable class DriveTestSpecification` (with `parseBrowserDimension`) in `drive/drive_service.dart`, shrinking `DriverService.startTest` (and `FlutterDriverService` / `WebDriverService`) from 12 parameters to 2 (`testFile`, `spec`). - Migrate `DriveCommand` (`commands/drive.dart`) from inline registrations and ad-hoc string/int/enum parsing to private typed `OptionDescriptor` constants (`IntOptionDescriptor`, `DefaultedEnumOptionDescriptor<Browser>`, etc.) and `DriveTestSpecification`. - Update unit tests across `test_test.dart`, `drive_test.dart`, `drive_service_test.dart`, and `web_driver_service_test.dart`. ### Flow / Surface Delta ```mermaid flowchart LR A["TestCommand (OptionDescriptors)"] --> B["TestExecutionSpecification"] B --> C["FlutterTestRunner.runTests(spec)"] D["DriveCommand (OptionDescriptors)"] --> E["DriveTestSpecification"] E --> F["DriverService.startTest(spec)"] ``` ### Verification - Executed `dart analyze --fatal-infos` on `packages/flutter_tools` with 0 issues. - Executed `dart test` across `test_test.dart`, `drive_test.dart`, `drive_service_test.dart`, and `web_driver_service_test.dart` (`148/148` passing). ## 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]. - [ ] 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.
…fig to AndroidBuildInfo (flutter#194016) ### Rationale `BuildInfo` is the cross-platform build configuration passed across Android, iOS, Web, Desktop, and Fuchsia targets, yet it carried 6 loose Android/Gradle fields (`androidProjectArgs`, `androidGradleProjectCacheDir`, `androidGradleDaemon`, `androidSkipBuildDependencyValidation`, `androidEnableHcpp`, `explicitAndroidEnableHcpp`) and the Gradle `-P` flag serializer `toGradleConfig()`. Following flutter#191018, flutter#191510, flutter#191760, flutter#192307, flutter#192455, flutter#192524, flutter#192818, and flutter#193323, this change encapsulates those fields into `AndroidGradleConfig` and moves `toGradleConfig()` onto `AndroidBuildInfo` where all production callers already operate. ### Summary of Changes - Introduce `@immutable class AndroidGradleConfig` in `build_info.dart` and replace the 6 loose `android*` parameters on `BuildInfo` and `BuildInfo.copyWith` with `androidGradleConfig` (shrinking `BuildInfo`'s constructor from 28 to 23 parameters while preserving `AndroidDevice.startApp` forwarding during `flutter run`). - Move `toGradleConfig()` off `BuildInfo` onto `AndroidBuildInfo` (with zero `@deprecated` forwarders) and add `gradleDaemon` and `skipBuildDependencyValidation` convenience getters on `AndroidBuildInfo`. - Update `FlutterCommand.getBuildInfo()` in `flutter_command.dart` to construct `AndroidGradleConfig`. - Update `buildGradleApp`, `buildGradleAar`, and `_checkJavaAndGradleCompatibility` in `gradle.dart` to read Gradle configuration via `AndroidBuildInfo`. - Update unit tests across `build_info_test.dart`, `flutter_command_test.dart`, `android_gradle_builder_test.dart`, and `build_aar_test.dart`. ### Flow / Surface Delta ```mermaid flowchart LR A["FlutterCommand.getBuildInfo()"] --> B["BuildInfo(androidGradleConfig)"] B --> C["AndroidBuildInfo.toGradleConfig()"] C --> D["gradle.dart (-P flags)"] ``` ### Verification - Executed `dart analyze --fatal-infos` on `packages/flutter_tools` with 0 issues. - Executed `dart test` across `build_info_test.dart`, `flutter_command_test.dart`, `android_gradle_builder_test.dart`, and `build_aar_test.dart` (`160/160` passing). ## 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]. - [ ] 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.
…le (flutter#196078) Registers `BuildInfoOptions.trackWidgetCreation` in `AppleBuildOptionsBundle` so Apple build subcommands (`build ios`, `build ipa`, and `build macos`) register `--[no-]track-widget-creation` (defaulting to on). Note that `--profile` AOT builds for `build ios` and `build ipa` will also now compile with `--track-creation-locations` by default (unless `--no-track-widget-creation` is passed), matching `build macos`, `build apk`, `build appbundle`, and `flutter run --profile`. This regression was originally introduced in flutter#56094 (first shipped in Flutter 1.20.0). Prior to flutter#56094, `xcodeproj.dart` omitted `TRACK_WIDGET_CREATION` from `Generated.xcconfig` when `buildInfo.trackWidgetCreation` was `false`, and `KernelSnapshot` enabled widget creation tracking whenever `TrackWidgetCreation` was not `'false'`. flutter#56094 switched `xcodeproj.dart` to `buildInfo.toEnvironmentConfig()`, which unconditionally writes `TRACK_WIDGET_CREATION=${trackWidgetCreation}`. In flutter#101123 (fixing flutter#94681), `BuildInfo.debug` was updated to set `trackWidgetCreation: true`, which fixed `Generated.xcconfig` for projects built directly from Xcode after `flutter create` or `flutter pub get` (while `flutter run` already registered `--track-widget-creation`). However, `BuildIOSCommand` constructs its `BuildInfo` via `FlutterCommand.getBuildInfo()` and never registered `--track-widget-creation` (an omission later carried forward into `AppleBuildOptionsBundle` in flutter#192818), so running `flutter build ios --debug` overwrote `Generated.xcconfig` with `TRACK_WIDGET_CREATION=false` and caused the first hot reload after `flutter attach` to fail with `Lookup failed: _location`. Previous output: ``` +13: ios build debug config-only writes TRACK_WIDGET_CREATION=true to Generated.xcconfig by default Expected: contains 'TRACK_WIDGET_CREATION=true' Actual: '// This is a generated file; do not edit or check into version control.\n' 'FLUTTER_ROOT=/usr/local/google/home/bkonyi/.gemini/jetski/worktrees/flutter/issue-195792\n' 'FLUTTER_APPLICATION_PATH=/\n' 'FLUTTER_FRAMEWORK_SWIFT_PACKAGE_PATH=/ios/Flutter/ephemeral/Packages/.packages/FlutterFramework\n' 'COCOAPODS_PARALLEL_CODE_SIGN=true\n' 'FLUTTER_TARGET=lib/main.dart\n' 'FLUTTER_BUILD_DIR=build\n' 'FLUTTER_BUILD_NAME=1.0.0\n' 'FLUTTER_BUILD_NUMBER=1\n' 'EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386\n' 'EXCLUDED_ARCHS[sdk=iphoneos*]=armv7\n' 'DART_DEFINES=RkxVVFRFUl9WRVJTSU9OPTAuMC4w,RkxVVFRFUl9DSEFOTkVMPW1hc3Rlcg==,RkxVVFRFUl9HSVRfVVJMPWh0dHBzOi8vZ2l0aHViLmNvbS9mbHV0dGVyL2ZsdXR0ZXIuZ2l0,RkxVVFRFUl9GUkFNRVdPUktfUkVWSVNJT049MTExMTE=,RkxVVFRFUl9FTkdJTkVfUkVWSVNJT049YWJjZGU=,RkxVVFRFUl9EQVJUX1ZFUlNJT049MTI=\n' 'DART_OBFUSCATION=false\n' 'TRACK_WIDGET_CREATION=false\n' 'TREE_SHAKE_ICONS=false\n' 'PACKAGE_CONFIG=/.dart_tool/package_config.json\n' '' Which: does not contain 'TRACK_WIDGET_CREATION=true' ``` Current output: ``` 00:00 +0: loading /usr/local/google/home/bkonyi/.gemini/jetski/worktrees/flutter/issue-195792/packages/flutter_tools/test/commands.shard/hermetic/build_ios_test.dart 00:00 +0: (setUpAll) 00:00 +0: ios build debug config-only writes TRACK_WIDGET_CREATION=true to Generated.xcconfig by default 00:00 +1: (tearDownAll) 00:00 +1: All tests passed! ``` Fixes flutter#195792
Migrates Apple build subcommands (
build ios,build ipa,build macos,build ios-framework,build macos-framework, andbuild swift-package) to use typed option descriptors and option bundles.BuildInfoOptions.codesignIdentityandDebuggingOptionDescriptors.publishPortdescriptors.AppleBuildOptionsBundlefor common Apple compilation and build options (flavor,splitDebugInfo,obfuscate,extraFrontEndOptions,extraGenSnapshotOptions,performanceMeasurementFile,analyzeSize, andcodeSizeDirectory).DarwinCodeSignXCFrameworksOptionsBundlecomposingcodesignandcodesignIdentity.usesDarwinCodeSignXCFrameworksOptionhelper fromFlutterCommandas all callers (build ios-framework,build macos-framework,build swift-package) have migrated.FlutterCommand.addPublishPortandFlutterCommand.disablePortPublicationto useDebuggingOptionDescriptors.publishPort.registerOptionBundlesandargParser.addDescriptors.getValue(...)/wasParsed(...)viaSafeArgResults.AppleBuildOptionsBundleandDarwinCodeSignXCFrameworksOptionsBundleinoption_descriptor_test.dart.Pre-launch Checklist
///).