From 18c59cdb1cf5b42dc2f8ded6eba36a2ea4c26b20 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Wed, 5 Jan 2022 16:45:12 -0800 Subject: [PATCH] Migrate build commands to null safety (#95649) --- .../flutter_tools/lib/src/bundle_builder.dart | 2 +- .../flutter_tools/lib/src/commands/build.dart | 6 +- .../lib/src/commands/build_aar.dart | 20 +++-- .../lib/src/commands/build_apk.dart | 5 +- .../lib/src/commands/build_appbundle.dart | 16 ++-- .../lib/src/commands/build_bundle.dart | 18 ++--- .../lib/src/commands/build_fuchsia.dart | 10 +-- .../lib/src/commands/build_ios.dart | 78 ++++++++++--------- .../lib/src/commands/build_ios_framework.dart | 55 ++++++------- .../lib/src/commands/build_linux.dart | 10 +-- .../lib/src/commands/build_macos.dart | 6 +- .../lib/src/commands/build_web.dart | 19 ++--- .../lib/src/commands/build_windows.dart | 4 +- .../lib/src/commands/build_winuwp.dart | 4 +- packages/flutter_tools/lib/src/globals.dart | 2 +- .../lib/src/runner/flutter_command.dart | 2 +- .../flutter_tools/lib/src/web/compile.dart | 11 ++- .../hermetic/build_web_test.dart | 1 - .../permeable/build_bundle_test.dart | 21 ++--- 19 files changed, 118 insertions(+), 172 deletions(-) diff --git a/packages/flutter_tools/lib/src/bundle_builder.dart b/packages/flutter_tools/lib/src/bundle_builder.dart index f18a090c5fa..2ed5e99387d 100644 --- a/packages/flutter_tools/lib/src/bundle_builder.dart +++ b/packages/flutter_tools/lib/src/bundle_builder.dart @@ -70,7 +70,7 @@ class BundleBuilder { final Target target = buildInfo.mode == BuildMode.debug ? const CopyFlutterBundle() : const ReleaseCopyFlutterBundle(); - final BuildResult result = await buildSystem!.build(target, environment); + final BuildResult result = await buildSystem.build(target, environment); if (!result.success) { for (final ExceptionMeasurement measurement in result.exceptions.values) { diff --git a/packages/flutter_tools/lib/src/commands/build.dart b/packages/flutter_tools/lib/src/commands/build.dart index af0105097bf..5cfaa11c5dc 100644 --- a/packages/flutter_tools/lib/src/commands/build.dart +++ b/packages/flutter_tools/lib/src/commands/build.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:meta/meta.dart'; import '../build_info.dart'; @@ -61,11 +59,11 @@ class BuildCommand extends FlutterCommand { String get category => FlutterCommandCategory.project; @override - Future runCommand() async => null; + Future runCommand() async => FlutterCommandResult.fail(); } abstract class BuildSubCommand extends FlutterCommand { - BuildSubCommand({@required bool verboseHelp}) { + BuildSubCommand({required bool verboseHelp}) { requiresPubspecYaml(); usesFatalWarningsOption(verboseHelp: verboseHelp); } diff --git a/packages/flutter_tools/lib/src/commands/build_aar.dart b/packages/flutter_tools/lib/src/commands/build_aar.dart index 5f033810845..d4f8367237c 100644 --- a/packages/flutter_tools/lib/src/commands/build_aar.dart +++ b/packages/flutter_tools/lib/src/commands/build_aar.dart @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 -import 'package:meta/meta.dart'; - import '../android/android_builder.dart'; import '../android/gradle_utils.dart'; import '../base/common.dart'; @@ -20,7 +17,7 @@ import '../runner/flutter_command.dart' show FlutterCommandResult; import 'build.dart'; class BuildAarCommand extends BuildSubCommand { - BuildAarCommand({ @required bool verboseHelp }) : super(verboseHelp: verboseHelp) { + BuildAarCommand({ required bool verboseHelp }) : super(verboseHelp: verboseHelp) { argParser ..addFlag( 'debug', @@ -52,7 +49,6 @@ class BuildAarCommand extends BuildSubCommand { argParser ..addMultiOption( 'target-platform', - splitCommas: true, defaultsTo: ['android-arm', 'android-arm64', 'android-x64'], allowed: ['android-arm', 'android-arm64', 'android-x86', 'android-x64'], help: 'The target platform for which the project is compiled.', @@ -116,10 +112,11 @@ class BuildAarCommand extends BuildSubCommand { final Iterable targetArchitectures = stringsArg('target-platform').map(getAndroidArchForName); + final String? buildNumberArg = stringArg('build-number'); final String buildNumber = argParser.options.containsKey('build-number') - && stringArg('build-number') != null - && stringArg('build-number').isNotEmpty - ? stringArg('build-number') + && buildNumberArg != null + && buildNumberArg.isNotEmpty + ? buildNumberArg : '1.0'; final File targetFile = globals.fs.file(globals.fs.path.join('lib', 'main.dart')); @@ -141,7 +138,7 @@ class BuildAarCommand extends BuildSubCommand { } displayNullSafetyMode(androidBuildInfo.first.buildInfo); - await androidBuilder.buildAar( + await androidBuilder?.buildAar( project: _getProject(), target: targetFile.path, androidBuildInfo: androidBuildInfo, @@ -154,9 +151,10 @@ class BuildAarCommand extends BuildSubCommand { /// Returns the [FlutterProject] which is determined from the remaining command-line /// argument if any or the current working directory. FlutterProject _getProject() { - if (argResults.rest.isEmpty) { + final List remainingArguments = argResults!.rest; + if (remainingArguments.isEmpty) { return FlutterProject.current(); } - return FlutterProject.fromDirectory(globals.fs.directory(findProjectRoot(globals.fs, argResults.rest.first))); + return FlutterProject.fromDirectory(globals.fs.directory(findProjectRoot(globals.fs, remainingArguments.first))); } } diff --git a/packages/flutter_tools/lib/src/commands/build_apk.dart b/packages/flutter_tools/lib/src/commands/build_apk.dart index 7c90057b4f3..ac48a579a58 100644 --- a/packages/flutter_tools/lib/src/commands/build_apk.dart +++ b/packages/flutter_tools/lib/src/commands/build_apk.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import '../android/android_builder.dart'; import '../android/build_validation.dart'; import '../android/gradle_utils.dart'; @@ -44,7 +42,6 @@ class BuildApkCommand extends BuildSubCommand { 'To learn more, see: https://developer.android.com/studio/build/configure-apk-splits#configure-abi-split', ) ..addMultiOption('target-platform', - splitCommas: true, defaultsTo: ['android-arm', 'android-arm64', 'android-x64'], allowed: ['android-arm', 'android-arm64', 'android-x86', 'android-x64'], help: 'The target platform for which the app is compiled.', @@ -109,7 +106,7 @@ class BuildApkCommand extends BuildSubCommand { validateBuild(androidBuildInfo); displayNullSafetyMode(androidBuildInfo.buildInfo); globals.terminal.usesTerminalUi = true; - await androidBuilder.buildApk( + await androidBuilder?.buildApk( project: FlutterProject.current(), target: targetFile, androidBuildInfo: androidBuildInfo, diff --git a/packages/flutter_tools/lib/src/commands/build_appbundle.dart b/packages/flutter_tools/lib/src/commands/build_appbundle.dart index 40611f2a7ba..22dc06140f1 100644 --- a/packages/flutter_tools/lib/src/commands/build_appbundle.dart +++ b/packages/flutter_tools/lib/src/commands/build_appbundle.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import '../android/android_builder.dart'; import '../android/build_validation.dart'; import '../android/deferred_components_prebuild_validator.dart'; @@ -44,13 +42,11 @@ class BuildAppBundleCommand extends BuildSubCommand { addMultidexOption(); addIgnoreDeprecationOption(); argParser.addMultiOption('target-platform', - splitCommas: true, defaultsTo: ['android-arm', 'android-arm64', 'android-x64'], allowed: ['android-arm', 'android-arm64', 'android-x64'], help: 'The target platform for which the app is compiled.', ); argParser.addFlag('deferred-components', - negatable: true, defaultsTo: true, help: 'Setting to false disables building with deferred components. All deferred code ' 'will be compiled into the base app, and assets act as if they were defined under' @@ -58,7 +54,6 @@ class BuildAppBundleCommand extends BuildSubCommand { 'non-deferred components apps.', ); argParser.addFlag('validate-deferred-components', - negatable: true, defaultsTo: true, help: 'When enabled, deferred component apps will fail to build if setup problems are ' 'detected that would prevent deferred components from functioning properly. The ' @@ -121,7 +116,8 @@ class BuildAppBundleCommand extends BuildSubCommand { ); // Do all setup verification that doesn't involve loading units. Checks that // require generated loading units are done after gen_snapshot in assemble. - if (FlutterProject.current().manifest.deferredComponents != null && boolArg('deferred-components') && boolArg('validate-deferred-components') && !boolArg('debug')) { + final List? deferredComponents = FlutterProject.current().manifest.deferredComponents; + if (deferredComponents != null && boolArg('deferred-components') && boolArg('validate-deferred-components') && !boolArg('debug')) { final DeferredComponentsPrebuildValidator validator = DeferredComponentsPrebuildValidator( FlutterProject.current().directory, globals.logger, @@ -129,14 +125,14 @@ class BuildAppBundleCommand extends BuildSubCommand { title: 'Deferred components prebuild validation', ); validator.clearOutputDir(); - await validator.checkAndroidDynamicFeature(FlutterProject.current().manifest.deferredComponents); - validator.checkAndroidResourcesStrings(FlutterProject.current().manifest.deferredComponents); + await validator.checkAndroidDynamicFeature(deferredComponents); + validator.checkAndroidResourcesStrings(deferredComponents); validator.handleResults(); // Delete intermediates libs dir for components to resolve mismatching // abis supported by base and dynamic feature modules. - for (final DeferredComponent component in FlutterProject.current().manifest.deferredComponents) { + for (final DeferredComponent component in deferredComponents) { final Directory deferredLibsIntermediate = FlutterProject.current().directory .childDirectory('build') .childDirectory(component.name) @@ -153,7 +149,7 @@ class BuildAppBundleCommand extends BuildSubCommand { validateBuild(androidBuildInfo); displayNullSafetyMode(androidBuildInfo.buildInfo); globals.terminal.usesTerminalUi = true; - await androidBuilder.buildAab( + await androidBuilder?.buildAab( project: FlutterProject.current(), target: targetFile, androidBuildInfo: androidBuildInfo, diff --git a/packages/flutter_tools/lib/src/commands/build_bundle.dart b/packages/flutter_tools/lib/src/commands/build_bundle.dart index 56465a85358..f7f90453edc 100644 --- a/packages/flutter_tools/lib/src/commands/build_bundle.dart +++ b/packages/flutter_tools/lib/src/commands/build_bundle.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import '../base/common.dart'; import '../build_info.dart'; import '../bundle.dart'; @@ -18,8 +16,8 @@ import 'build.dart'; class BuildBundleCommand extends BuildSubCommand { BuildBundleCommand({ bool verboseHelp = false, - this.bundleBuilder, - }) : super(verboseHelp: verboseHelp) { + BundleBuilder? bundleBuilder, + }) : _bundleBuilder = bundleBuilder ?? BundleBuilder(), super(verboseHelp: verboseHelp) { usesTargetOption(); usesFilesystemOptions(hide: !verboseHelp); usesBuildNumberOption(); @@ -54,18 +52,14 @@ class BuildBundleCommand extends BuildSubCommand { ) ..addFlag( 'tree-shake-icons', - negatable: true, - defaultsTo: false, hide: !verboseHelp, help: '(deprecated) Icon font tree shaking is not supported by this command.', ); usesPubOption(); usesTrackWidgetCreation(verboseHelp: verboseHelp); - - bundleBuilder ??= BundleBuilder(); } - BundleBuilder bundleBuilder; + final BundleBuilder _bundleBuilder; @override final String name = 'bundle'; @@ -93,7 +87,7 @@ class BuildBundleCommand extends BuildSubCommand { @override Future validateCommand() async { - if (argResults['tree-shake-icons'] as bool) { + if (boolArg('tree-shake-icons')) { throwToolExit('The "--tree-shake-icons" flag is deprecated for "build bundle" and will be removed in a future version of Flutter.'); } return super.validateCommand(); @@ -101,7 +95,7 @@ class BuildBundleCommand extends BuildSubCommand { @override Future runCommand() async { - final String targetPlatform = stringArg('target-platform'); + final String targetPlatform = stringArg('target-platform')!; final TargetPlatform platform = getTargetPlatformForName(targetPlatform); if (platform == null) { throwToolExit('Unknown platform: $targetPlatform'); @@ -141,7 +135,7 @@ class BuildBundleCommand extends BuildSubCommand { final BuildInfo buildInfo = await getBuildInfo(); displayNullSafetyMode(buildInfo); - await bundleBuilder.build( + await _bundleBuilder.build( platform: platform, buildInfo: buildInfo, mainPath: targetFile, diff --git a/packages/flutter_tools/lib/src/commands/build_fuchsia.dart b/packages/flutter_tools/lib/src/commands/build_fuchsia.dart index 290339c1e37..5f751036abf 100644 --- a/packages/flutter_tools/lib/src/commands/build_fuchsia.dart +++ b/packages/flutter_tools/lib/src/commands/build_fuchsia.dart @@ -2,10 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - -import 'package:meta/meta.dart'; - import '../base/common.dart'; import '../build_info.dart'; import '../cache.dart'; @@ -20,7 +16,7 @@ import 'build.dart'; /// A command to build a Fuchsia target. class BuildFuchsiaCommand extends BuildSubCommand { BuildFuchsiaCommand({ - @required bool verboseHelp, + required bool verboseHelp, }) : super(verboseHelp: verboseHelp) { addTreeShakeIconsFlag(); usesTargetOption(); @@ -83,9 +79,9 @@ class BuildFuchsiaCommand extends BuildSubCommand { await buildFuchsia( fuchsiaProject: flutterProject.fuchsia, target: targetFile, - targetPlatform: getTargetPlatformForName(stringArg('target-platform')), + targetPlatform: getTargetPlatformForName(stringArg('target-platform')!), buildInfo: buildInfo, - runnerPackageSource: stringArg('runner-source'), + runnerPackageSource: stringArg('runner-source')!, ); return FlutterCommandResult.success(); } diff --git a/packages/flutter_tools/lib/src/commands/build_ios.dart b/packages/flutter_tools/lib/src/commands/build_ios.dart index b1ec5d429b4..8047bca1421 100644 --- a/packages/flutter_tools/lib/src/commands/build_ios.dart +++ b/packages/flutter_tools/lib/src/commands/build_ios.dart @@ -2,10 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:file/file.dart'; -import 'package:meta/meta.dart'; import '../base/analyze_size.dart'; import '../base/common.dart'; @@ -23,7 +20,7 @@ import 'build.dart'; /// Builds an .app for an iOS app to be used for local testing on an iOS device /// or simulator. Can only be run on a macOS host. class BuildIOSCommand extends _BuildIOSSubCommand { - BuildIOSCommand({ @required bool verboseHelp }) : super(verboseHelp: verboseHelp) { + BuildIOSCommand({ required bool verboseHelp }) : super(verboseHelp: verboseHelp) { argParser ..addFlag('config-only', help: 'Update the project configuration without performing a build. ' @@ -67,7 +64,7 @@ class BuildIOSCommand extends _BuildIOSSubCommand { /// /// Can only be run on a macOS host. class BuildIOSArchiveCommand extends _BuildIOSSubCommand { - BuildIOSArchiveCommand({@required bool verboseHelp}) + BuildIOSArchiveCommand({required bool verboseHelp}) : super(verboseHelp: verboseHelp) { argParser.addOption( 'export-options-plist', @@ -99,7 +96,7 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand { @override final bool shouldCodesign = true; - String get exportOptionsPlist => stringArg('export-options-plist'); + String? get exportOptionsPlist => stringArg('export-options-plist'); @override Directory _outputAppDirectory(String xcodeResultOutput) => globals.fs @@ -109,21 +106,22 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand { @override Future runCommand() async { - if (exportOptionsPlist != null) { - final FileSystemEntityType type = globals.fs.typeSync(exportOptionsPlist); + final String? exportOptions = exportOptionsPlist; + if (exportOptions != null) { + final FileSystemEntityType type = globals.fs.typeSync(exportOptions); if (type == FileSystemEntityType.notFound) { throwToolExit( - '"$exportOptionsPlist" property list does not exist.'); + '"$exportOptions" property list does not exist.'); } else if (type != FileSystemEntityType.file) { throwToolExit( - '"$exportOptionsPlist" is not a file. See "xcodebuild -h" for available keys.'); + '"$exportOptions" is not a file. See "xcodebuild -h" for available keys.'); } } final FlutterCommandResult xcarchiveResult = await super.runCommand(); final BuildInfo buildInfo = await getBuildInfo(); displayNullSafetyMode(buildInfo); - if (exportOptionsPlist == null) { + if (exportOptions == null) { return xcarchiveResult; } @@ -134,16 +132,16 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand { } // Build IPA from generated xcarchive. - final BuildableIOSApp app = await buildableIOSApp(buildInfo); - Status status; - RunResult result; + final BuildableIOSApp app = await buildableIOSApp; + Status? status; + RunResult? result; final String outputPath = globals.fs.path.absolute(app.ipaOutputPath); try { status = globals.logger.startProgress('Building IPA...'); result = await globals.processUtils.run( [ - ...globals.xcode.xcrunCommand(), + ...globals.xcode!.xcrunCommand(), 'xcodebuild', '-exportArchive', if (shouldCodesign) ...[ @@ -155,11 +153,11 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand { '-exportPath', outputPath, '-exportOptionsPlist', - globals.fs.path.absolute(exportOptionsPlist), + globals.fs.path.absolute(exportOptions), ], ); } finally { - status.stop(); + status?.stop(); } if (result.exitCode != 0) { @@ -184,7 +182,7 @@ class BuildIOSArchiveCommand extends _BuildIOSSubCommand { abstract class _BuildIOSSubCommand extends BuildSubCommand { _BuildIOSSubCommand({ - @required bool verboseHelp + required bool verboseHelp }) : super(verboseHelp: verboseHelp) { addTreeShakeIconsFlag(); addSplitDebugInfoOption(); @@ -214,15 +212,19 @@ abstract class _BuildIOSSubCommand extends BuildSubCommand { bool get configOnly; bool get shouldCodesign; - Future buildableIOSApp(BuildInfo buildInfo) async { - _buildableIOSApp ??= await applicationPackages.getPackageForPlatform( - TargetPlatform.ios, - buildInfo: buildInfo, - ) as BuildableIOSApp; - return _buildableIOSApp; - } + late final Future cachedBuildInfo = getBuildInfo(); - BuildableIOSApp _buildableIOSApp; + late final Future buildableIOSApp = () async { + final BuildableIOSApp? app = await applicationPackages?.getPackageForPlatform( + TargetPlatform.ios, + buildInfo: await cachedBuildInfo, + ) as BuildableIOSApp?; + + if (app == null) { + throwToolExit('Application not configured for iOS'); + } + return app; + }(); Directory _outputAppDirectory(String xcodeResultOutput); @@ -232,7 +234,7 @@ abstract class _BuildIOSSubCommand extends BuildSubCommand { @override Future runCommand() async { defaultBuildMode = environmentType == EnvironmentType.simulator ? BuildMode.debug : BuildMode.release; - final BuildInfo buildInfo = await getBuildInfo(); + final BuildInfo buildInfo = await cachedBuildInfo; if (!supported) { throwToolExit('Building for iOS is only supported on macOS.'); @@ -250,14 +252,10 @@ abstract class _BuildIOSSubCommand extends BuildSubCommand { ); } - final BuildableIOSApp app = await buildableIOSApp(buildInfo); - - if (app == null) { - throwToolExit('Application not configured for iOS'); - } + final BuildableIOSApp app = await buildableIOSApp; final String logTarget = environmentType == EnvironmentType.simulator ? 'simulator' : 'device'; - final String typeName = globals.artifacts.getEngineType(TargetPlatform.ios, buildInfo.mode); + final String typeName = globals.artifacts!.getEngineType(TargetPlatform.ios, buildInfo.mode); if (xcodeBuildAction == XcodeBuildAction.build) { globals.printStatus('Building $app for $logTarget ($typeName)...'); } else { @@ -293,20 +291,24 @@ abstract class _BuildIOSSubCommand extends BuildSubCommand { final File precompilerTrace = globals.fs.directory(buildInfo.codeSizeDirectory) .childFile('trace.$arch.json'); - final Directory outputAppDirectoryCandidate = _outputAppDirectory(result.output); + final String? resultOutput = result.output; + if (resultOutput == null) { + throwToolExit('Could not find app to analyze code size'); + } + final Directory outputAppDirectoryCandidate = _outputAppDirectory(resultOutput); - Directory appDirectory; + Directory? appDirectory; if (outputAppDirectoryCandidate.existsSync()) { appDirectory = outputAppDirectoryCandidate.listSync() .whereType() - .firstWhere((Directory directory) { + .where((Directory directory) { return globals.fs.path.extension(directory.path) == '.app'; - }, orElse: () => null); + }).first; } if (appDirectory == null) { throwToolExit('Could not find app to analyze code size in ${outputAppDirectoryCandidate.path}'); } - final Map output = await sizeAnalyzer.analyzeAotSnapshot( + final Map output = await sizeAnalyzer.analyzeAotSnapshot( aotSnapshot: aotSnapshot, precompilerTrace: precompilerTrace, outputDirectory: appDirectory, diff --git a/packages/flutter_tools/lib/src/commands/build_ios_framework.dart b/packages/flutter_tools/lib/src/commands/build_ios_framework.dart index 0132dc582bb..1af299a55e6 100644 --- a/packages/flutter_tools/lib/src/commands/build_ios_framework.dart +++ b/packages/flutter_tools/lib/src/commands/build_ios_framework.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:meta/meta.dart'; import '../artifacts.dart'; @@ -31,12 +29,13 @@ import 'build.dart'; /// managers. class BuildIOSFrameworkCommand extends BuildSubCommand { BuildIOSFrameworkCommand({ - FlutterVersion flutterVersion, // Instantiating FlutterVersion kicks off networking, so delay until it's needed, but allow test injection. - @required BuildSystem buildSystem, - @required bool verboseHelp, - Cache cache, - Platform platform - }) : _flutterVersion = flutterVersion, + // Instantiating FlutterVersion kicks off networking, so delay until it's needed, but allow test injection. + @visibleForTesting FlutterVersion? flutterVersion, + required BuildSystem buildSystem, + required bool verboseHelp, + Cache? cache, + Platform? platform + }) : _injectedFlutterVersion = flutterVersion, _buildSystem = buildSystem, _injectedCache = cache, _injectedPlatform = platform, @@ -54,26 +53,22 @@ class BuildIOSFrameworkCommand extends BuildSubCommand { argParser ..addFlag('debug', - negatable: true, defaultsTo: true, help: 'Whether to produce a framework for the debug build configuration. ' 'By default, all build configurations are built.' ) ..addFlag('profile', - negatable: true, defaultsTo: true, help: 'Whether to produce a framework for the profile build configuration. ' 'By default, all build configurations are built.' ) ..addFlag('release', - negatable: true, defaultsTo: true, help: 'Whether to produce a framework for the release build configuration. ' 'By default, all build configurations are built.' ) ..addFlag('universal', help: '(deprecated) Produce universal frameworks that include all valid architectures.', - negatable: true, hide: !verboseHelp, ) ..addFlag('xcframework', @@ -97,16 +92,18 @@ class BuildIOSFrameworkCommand extends BuildSubCommand { ); } - final BuildSystem _buildSystem; + final BuildSystem? _buildSystem; BuildSystem get buildSystem => _buildSystem ?? globals.buildSystem; Cache get _cache => _injectedCache ?? globals.cache; - final Cache _injectedCache; + final Cache? _injectedCache; Platform get _platform => _injectedPlatform ?? globals.platform; - final Platform _injectedPlatform; + final Platform? _injectedPlatform; - FlutterVersion _flutterVersion; + // FlutterVersion.instance kicks off git processing which can sometimes fail, so don't try it until needed. + FlutterVersion get _flutterVersion => _injectedFlutterVersion ?? globals.flutterVersion; + final FlutterVersion? _injectedFlutterVersion; @override bool get reportNullSafety => false; @@ -124,7 +121,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand { DevelopmentArtifact.iOS, }; - FlutterProject _project; + late final FlutterProject _project = FlutterProject.current(); Future> getBuildInfos() async { final List buildInfos = []; @@ -148,7 +145,6 @@ class BuildIOSFrameworkCommand extends BuildSubCommand { @override Future validateCommand() async { await super.validateCommand(); - _project = FlutterProject.current(); if (!supported) { throwToolExit('Building frameworks for iOS is only supported on the Mac.'); } @@ -178,7 +174,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand { final List buildInfos = await getBuildInfos(); displayNullSafetyMode(buildInfos.first); for (final BuildInfo buildInfo in buildInfos) { - final String productBundleIdentifier = await _project.ios.productBundleIdentifier(buildInfo); + final String? productBundleIdentifier = await _project.ios.productBundleIdentifier(buildInfo); globals.printStatus('Building frameworks for $productBundleIdentifier in ${getNameForBuildMode(buildInfo.mode)} mode...'); final String xcodeBuildConfiguration = sentenceCase(getNameForBuildMode(buildInfo.mode)); final Directory modeDirectory = outputDirectory.childDirectory(xcodeBuildConfiguration); @@ -188,8 +184,6 @@ class BuildIOSFrameworkCommand extends BuildSubCommand { } if (boolArg('cocoapods')) { - // FlutterVersion.instance kicks off git processing which can sometimes fail, so don't try it until needed. - _flutterVersion ??= globals.flutterVersion; produceFlutterPodspec(buildInfo.mode, modeDirectory, force: boolArg('force')); } else { // Copy Flutter.xcframework. @@ -263,7 +257,7 @@ class BuildIOSFrameworkCommand extends BuildSubCommand { // Fake out a semantic version with major.minor.(patch * 100) + hotfix. // A real increasing version is required to prompt CocoaPods to fetch // new artifacts when the source URL changes. - final int minorHotfixVersion = gitTagVersion.z * 100 + (gitTagVersion.hotfix ?? 0); + final int minorHotfixVersion = (gitTagVersion.z ?? 0) * 100 + (gitTagVersion.hotfix ?? 0); final File license = _cache.getLicenseFile(); if (!license.existsSync()) { @@ -309,7 +303,7 @@ end final Status status = globals.logger.startProgress( ' ├─Copying Flutter.xcframework...', ); - final String engineCacheFlutterFrameworkDirectory = globals.artifacts.getArtifactPath( + final String engineCacheFlutterFrameworkDirectory = globals.artifacts!.getArtifactPath( Artifact.flutterXcframework, platform: TargetPlatform.ios, mode: buildInfo.mode, @@ -369,15 +363,15 @@ end kIosArchs: defaultIOSArchsForEnvironment(sdkType) .map(getNameForDarwinArch) .join(' '), - kSdkRoot: await globals.xcode.sdkLocation(sdkType), + kSdkRoot: await globals.xcode!.sdkLocation(sdkType), ...buildInfo.toBuildSystemEnvironment(), }, - artifacts: globals.artifacts, + artifacts: globals.artifacts!, fileSystem: globals.fs, logger: globals.logger, processManager: globals.processManager, platform: globals.platform, - engineVersion: globals.artifacts.isLocalEngine + engineVersion: globals.artifacts!.isLocalEngine ? null : globals.flutterVersion.engineRevision, generateDartPluginRegistry: true, @@ -423,7 +417,7 @@ end 'bitcode' : 'marker'; // In release, force bitcode embedding without archiving. List pluginsBuildCommand = [ - ...globals.xcode.xcrunCommand(), + ...globals.xcode!.xcrunCommand(), 'xcodebuild', '-alltargets', '-sdk', @@ -439,7 +433,6 @@ end RunResult buildPluginsResult = await globals.processUtils.run( pluginsBuildCommand, workingDirectory: _project.ios.hostAppRoot.childDirectory('Pods').path, - allowReentrantFlutter: false, ); if (buildPluginsResult.exitCode != 0) { @@ -449,7 +442,7 @@ end // Always build debug for simulator. final String simulatorConfiguration = sentenceCase(getNameForBuildMode(BuildMode.debug)); pluginsBuildCommand = [ - ...globals.xcode.xcrunCommand(), + ...globals.xcode!.xcrunCommand(), 'xcodebuild', '-alltargets', '-sdk', @@ -467,7 +460,6 @@ end workingDirectory: _project.ios.hostAppRoot .childDirectory('Pods') .path, - allowReentrantFlutter: false, ); if (buildPluginsResult.exitCode != 0) { @@ -515,7 +507,7 @@ end return; } final List xcframeworkCommand = [ - ...globals.xcode.xcrunCommand(), + ...globals.xcode!.xcrunCommand(), 'xcodebuild', '-create-xcframework', for (Directory framework in frameworks) ...[ @@ -536,7 +528,6 @@ end final RunResult xcframeworkResult = await globals.processUtils.run( xcframeworkCommand, - allowReentrantFlutter: false, ); if (xcframeworkResult.exitCode != 0) { diff --git a/packages/flutter_tools/lib/src/commands/build_linux.dart b/packages/flutter_tools/lib/src/commands/build_linux.dart index ce462fd74ef..d783f537769 100644 --- a/packages/flutter_tools/lib/src/commands/build_linux.dart +++ b/packages/flutter_tools/lib/src/commands/build_linux.dart @@ -2,10 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - -import 'package:meta/meta.dart'; - import '../base/analyze_size.dart'; import '../base/common.dart'; import '../base/os.dart'; @@ -21,7 +17,7 @@ import 'build.dart'; /// A command to build a linux desktop target through a build shell script. class BuildLinuxCommand extends BuildSubCommand { BuildLinuxCommand({ - @required OperatingSystemUtils operatingSystemUtils, + required OperatingSystemUtils operatingSystemUtils, bool verboseHelp = false, }) : _operatingSystemUtils = operatingSystemUtils, super(verboseHelp: verboseHelp) { @@ -63,7 +59,7 @@ class BuildLinuxCommand extends BuildSubCommand { final BuildInfo buildInfo = await getBuildInfo(); final FlutterProject flutterProject = FlutterProject.current(); final TargetPlatform targetPlatform = - getTargetPlatformForName(stringArg('target-platform')); + getTargetPlatformForName(stringArg('target-platform')!); final bool needCrossBuild = getNameForHostPlatformArch(_operatingSystemUtils.hostPlatform) != getNameForTargetPlatformArch(targetPlatform); @@ -97,7 +93,7 @@ class BuildLinuxCommand extends BuildSubCommand { ), needCrossBuild: needCrossBuild, targetPlatform: targetPlatform, - targetSysroot: stringArg('target-sysroot'), + targetSysroot: stringArg('target-sysroot')!, ); return FlutterCommandResult.success(); } diff --git a/packages/flutter_tools/lib/src/commands/build_macos.dart b/packages/flutter_tools/lib/src/commands/build_macos.dart index 84bc5fb0a1c..415de8f5d27 100644 --- a/packages/flutter_tools/lib/src/commands/build_macos.dart +++ b/packages/flutter_tools/lib/src/commands/build_macos.dart @@ -2,10 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - -import 'package:meta/meta.dart'; - import '../base/analyze_size.dart'; import '../base/common.dart'; import '../build_info.dart'; @@ -20,7 +16,7 @@ import 'build.dart'; /// A command to build a macOS desktop target through a build shell script. class BuildMacosCommand extends BuildSubCommand { BuildMacosCommand({ - @required bool verboseHelp, + required bool verboseHelp, }) : super(verboseHelp: verboseHelp) { addCommonDesktopBuildOptions(verboseHelp: verboseHelp); usesBuildNumberOption(); diff --git a/packages/flutter_tools/lib/src/commands/build_web.dart b/packages/flutter_tools/lib/src/commands/build_web.dart index 4c63d91e92e..8cc322dcdf0 100644 --- a/packages/flutter_tools/lib/src/commands/build_web.dart +++ b/packages/flutter_tools/lib/src/commands/build_web.dart @@ -2,10 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - -import 'package:meta/meta.dart'; - import '../base/common.dart'; import '../build_info.dart'; import '../build_system/targets/web.dart'; @@ -19,7 +15,7 @@ import 'build.dart'; class BuildWebCommand extends BuildSubCommand { BuildWebCommand({ - @required bool verboseHelp, + required bool verboseHelp, }) : super(verboseHelp: verboseHelp) { addTreeShakeIconsFlag(enabledByDefault: false); usesTargetOption(); @@ -31,14 +27,12 @@ class BuildWebCommand extends BuildSubCommand { addNullSafetyModeOptions(hide: !verboseHelp); addNativeNullAssertions(); argParser.addFlag('csp', - defaultsTo: false, negatable: false, help: 'Disable dynamic generation of code in the generated output. ' 'This is necessary to satisfy CSP restrictions (see http://www.w3.org/TR/CSP/).' ); argParser.addFlag( 'source-maps', - defaultsTo: false, help: 'Generate a sourcemap file. These can be used by browsers ' 'to view and debug the original source code of a compiled and minified Dart ' 'application.' @@ -91,12 +85,13 @@ class BuildWebCommand extends BuildSubCommand { throwToolExit('"build web" is not currently supported. To enable, run "flutter config --enable-web".'); } final FlutterProject flutterProject = FlutterProject.current(); - final String target = stringArg('target'); + final String target = stringArg('target')!; final BuildInfo buildInfo = await getBuildInfo(); if (buildInfo.isDebug) { throwToolExit('debug builds cannot be built directly for the web. Try using "flutter run"'); } - if (stringArg('base-href') != null && !(stringArg('base-href').startsWith('/') && stringArg('base-href').endsWith('/'))) { + final String? baseHref = stringArg('base-href'); + if (baseHref != null && !(baseHref.startsWith('/') && baseHref.endsWith('/'))) { throwToolExit('base-href should start and end with /'); } if (!flutterProject.web.existsSync()) { @@ -107,7 +102,7 @@ class BuildWebCommand extends BuildSubCommand { .childFile('index.html') .readAsStringSync() .contains(kBaseHrefPlaceholder) && - stringArg('base-href') != null) { + baseHref != null) { throwToolExit( "Couldn't find the placeholder for base href. " r'Please add `` to web/index.html' @@ -119,10 +114,10 @@ class BuildWebCommand extends BuildSubCommand { target, buildInfo, boolArg('csp'), - stringArg('pwa-strategy'), + stringArg('pwa-strategy')!, boolArg('source-maps'), boolArg('native-null-assertions'), - stringArg('base-href'), + baseHref, ); return FlutterCommandResult.success(); } diff --git a/packages/flutter_tools/lib/src/commands/build_windows.dart b/packages/flutter_tools/lib/src/commands/build_windows.dart index 611899f8dea..b42c97676af 100644 --- a/packages/flutter_tools/lib/src/commands/build_windows.dart +++ b/packages/flutter_tools/lib/src/commands/build_windows.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:meta/meta.dart'; import '../base/analyze_size.dart'; @@ -41,7 +39,7 @@ class BuildWindowsCommand extends BuildSubCommand { String get description => 'Build a Windows desktop application.'; @visibleForTesting - VisualStudio visualStudioOverride; + VisualStudio? visualStudioOverride; @override Future runCommand() async { diff --git a/packages/flutter_tools/lib/src/commands/build_winuwp.dart b/packages/flutter_tools/lib/src/commands/build_winuwp.dart index f8761c447f9..7fb6eb96177 100644 --- a/packages/flutter_tools/lib/src/commands/build_winuwp.dart +++ b/packages/flutter_tools/lib/src/commands/build_winuwp.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import 'package:meta/meta.dart'; import '../base/common.dart'; @@ -40,7 +38,7 @@ class BuildWindowsUwpCommand extends BuildSubCommand { String get description => 'Build a Windows UWP desktop application.'; @visibleForTesting - VisualStudio visualStudioOverride; + VisualStudio? visualStudioOverride; @override Future runCommand() async { diff --git a/packages/flutter_tools/lib/src/globals.dart b/packages/flutter_tools/lib/src/globals.dart index cef2d2ae2e9..35fe0291b07 100644 --- a/packages/flutter_tools/lib/src/globals.dart +++ b/packages/flutter_tools/lib/src/globals.dart @@ -50,7 +50,7 @@ import 'version.dart'; String get flutterGit => platform.environment['FLUTTER_GIT_URL'] ?? 'https://github.com/flutter/flutter.git'; Artifacts? get artifacts => context.get(); -BuildSystem? get buildSystem => context.get(); +BuildSystem get buildSystem => context.get()!; Cache get cache => context.get()!; CocoaPodsValidator? get cocoapodsValidator => context.get(); Config get config => context.get()!; diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index 04033e5cf25..96bff4a819a 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart @@ -1295,7 +1295,7 @@ abstract class FlutterCommand extends Command { await generateLocalizationsSyntheticPackage( environment: environment, - buildSystem: globals.buildSystem!, + buildSystem: globals.buildSystem, ); await pub.get( diff --git a/packages/flutter_tools/lib/src/web/compile.dart b/packages/flutter_tools/lib/src/web/compile.dart index 054c552abad..e9fa471a96a 100644 --- a/packages/flutter_tools/lib/src/web/compile.dart +++ b/packages/flutter_tools/lib/src/web/compile.dart @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// @dart = 2.8 - import '../artifacts.dart'; import '../base/common.dart'; import '../base/file_system.dart'; @@ -26,7 +24,7 @@ Future buildWeb( String serviceWorkerStrategy, bool sourceMaps, bool nativeNullAssertions, - String baseHref, + String? baseHref, ) async { final bool hasWebPlugins = (await findPlugins(flutterProject)) .any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey)); @@ -47,20 +45,21 @@ Future buildWeb( kTargetFile: target, kHasWebPlugins: hasWebPlugins.toString(), kCspMode: csp.toString(), - kBaseHref : baseHref, + if (baseHref != null) + kBaseHref : baseHref, kSourceMapsEnabled: sourceMaps.toString(), kNativeNullAssertions: nativeNullAssertions.toString(), if (serviceWorkerStrategy != null) kServiceWorkerStrategy: serviceWorkerStrategy, ...buildInfo.toBuildSystemEnvironment(), }, - artifacts: globals.artifacts, + artifacts: globals.artifacts!, fileSystem: globals.fs, logger: globals.logger, processManager: globals.processManager, platform: globals.platform, cacheDir: globals.cache.getRoot(), - engineVersion: globals.artifacts.isLocalEngine + engineVersion: globals.artifacts!.isLocalEngine ? null : globals.flutterVersion.engineRevision, flutterRootDir: globals.fs.directory(Cache.flutterRoot), diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_web_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_web_test.dart index e783ab8ef43..dea76d9b886 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/build_web_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/build_web_test.dart @@ -111,7 +111,6 @@ void main() { 'DartObfuscation': 'false', 'TrackWidgetCreation': 'false', 'TreeShakeIcons': 'false', - 'baseHref': null, }); }), }); diff --git a/packages/flutter_tools/test/commands.shard/permeable/build_bundle_test.dart b/packages/flutter_tools/test/commands.shard/permeable/build_bundle_test.dart index 450f2e93f98..8bb4cc85037 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/build_bundle_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/build_bundle_test.dart @@ -89,8 +89,7 @@ void main() { globals.fs.file('lib/main.dart').createSync(recursive: true); globals.fs.file('pubspec.yaml').createSync(recursive: true); globals.fs.file('.packages').createSync(recursive: true); - final CommandRunner runner = createTestCommandRunner(BuildBundleCommand() - ..bundleBuilder = FakeBundleBuilder()); + final CommandRunner runner = createTestCommandRunner(BuildBundleCommand(bundleBuilder: FakeBundleBuilder())); expect(() => runner.run([ 'bundle', @@ -107,8 +106,7 @@ void main() { globals.fs.file('lib/main.dart').createSync(recursive: true); globals.fs.file('pubspec.yaml').createSync(); globals.fs.file('.packages').createSync(); - final CommandRunner runner = createTestCommandRunner(BuildBundleCommand() - ..bundleBuilder = FakeBundleBuilder()); + final CommandRunner runner = createTestCommandRunner(BuildBundleCommand(bundleBuilder: FakeBundleBuilder())); expect(() => runner.run([ 'bundle', @@ -125,8 +123,7 @@ void main() { globals.fs.file('lib/main.dart').createSync(recursive: true); globals.fs.file('pubspec.yaml').createSync(); globals.fs.file('.packages').createSync(); - final CommandRunner runner = createTestCommandRunner(BuildBundleCommand() - ..bundleBuilder = FakeBundleBuilder()); + final CommandRunner runner = createTestCommandRunner(BuildBundleCommand(bundleBuilder: FakeBundleBuilder())); expect(() => runner.run([ 'bundle', @@ -143,8 +140,7 @@ void main() { globals.fs.file('lib/main.dart').createSync(recursive: true); globals.fs.file('pubspec.yaml').createSync(); globals.fs.file('.packages').createSync(); - final CommandRunner runner = createTestCommandRunner(BuildBundleCommand() - ..bundleBuilder = FakeBundleBuilder()); + final CommandRunner runner = createTestCommandRunner(BuildBundleCommand(bundleBuilder: FakeBundleBuilder())); expect(() => runner.run([ 'bundle', @@ -161,8 +157,7 @@ void main() { globals.fs.file('lib/main.dart').createSync(recursive: true); globals.fs.file('pubspec.yaml').createSync(); globals.fs.file('.packages').createSync(); - final CommandRunner runner = createTestCommandRunner(BuildBundleCommand() - ..bundleBuilder = FakeBundleBuilder()); + final CommandRunner runner = createTestCommandRunner(BuildBundleCommand(bundleBuilder: FakeBundleBuilder())); await runner.run([ 'bundle', @@ -179,8 +174,7 @@ void main() { globals.fs.file('lib/main.dart').createSync(recursive: true); globals.fs.file('pubspec.yaml').createSync(); globals.fs.file('.packages').createSync(); - final CommandRunner runner = createTestCommandRunner(BuildBundleCommand() - ..bundleBuilder = FakeBundleBuilder()); + final CommandRunner runner = createTestCommandRunner(BuildBundleCommand(bundleBuilder: FakeBundleBuilder())); await runner.run([ 'bundle', @@ -197,8 +191,7 @@ void main() { globals.fs.file('lib/main.dart').createSync(recursive: true); globals.fs.file('pubspec.yaml').createSync(); globals.fs.file('.packages').createSync(); - final CommandRunner runner = createTestCommandRunner(BuildBundleCommand() - ..bundleBuilder = FakeBundleBuilder()); + final CommandRunner runner = createTestCommandRunner(BuildBundleCommand(bundleBuilder: FakeBundleBuilder())); await runner.run([ 'bundle',