From 09987dc00a84a85f233632fd95b7e26ddaee71c8 Mon Sep 17 00:00:00 2001 From: Jenn Magder Date: Tue, 24 May 2022 18:48:10 -0700 Subject: [PATCH] Migrate create command to null safety (#104484) --- .../lib/src/commands/create.dart | 111 +++++++++--------- .../lib/src/commands/create_base.dart | 105 ++++++++--------- packages/flutter_tools/lib/src/template.dart | 2 +- .../test/src/test_flutter_command_runner.dart | 8 +- 4 files changed, 105 insertions(+), 121 deletions(-) diff --git a/packages/flutter_tools/lib/src/commands/create.dart b/packages/flutter_tools/lib/src/commands/create.dart index dbe675364142..f506a2f5cb54 100644 --- a/packages/flutter_tools/lib/src/commands/create.dart +++ b/packages/flutter_tools/lib/src/commands/create.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/gradle_utils.dart' as gradle; import '../base/common.dart'; import '../base/context.dart'; @@ -32,8 +30,8 @@ const String kPlatformHelp = class CreateCommand extends CreateBase { CreateCommand({ - bool verboseHelp = false, - }) : super(verboseHelp: verboseHelp) { + super.verboseHelp = false, + }) { addPlatformsOptions(customHelp: kPlatformHelp); argParser.addOption( 'template', @@ -57,7 +55,6 @@ class CreateCommand extends CreateBase { flutterProjectTypeToString(FlutterProjectType.module): 'Generate a project to add a Flutter module to an ' 'existing Android or iOS application.', }, - defaultsTo: null, ); argParser.addOption( 'sample', @@ -66,7 +63,6 @@ class CreateCommand extends CreateBase { '"--template=app". The value should be the sample ID of the desired sample from the API ' 'documentation website (http://docs.flutter.dev/). An example can be found at: ' 'https://api.flutter.dev/flutter/widgets/SingleChildScrollView-class.html', - defaultsTo: null, valueHelp: 'id', ); argParser.addOption( @@ -88,7 +84,7 @@ class CreateCommand extends CreateBase { String get category => FlutterCommandCategory.project; @override - String get invocation => '${runner.executableName} $name '; + String get invocation => '${runner?.executableName} $name '; @override Future get usageValues async { @@ -100,8 +96,7 @@ class CreateCommand extends CreateBase { } // Lazy-initialize the net utilities with values from the context. - Net _cachedNet; - Net get _net => _cachedNet ??= Net( + late final Net _net = Net( httpClientFactory: context.get(), logger: globals.logger, platform: globals.platform, @@ -112,7 +107,7 @@ class CreateCommand extends CreateBase { ? 'api.flutter.dev' : 'master-api.flutter.dev'; - Future _fetchSampleFromServer(String sampleId) async { + Future _fetchSampleFromServer(String sampleId) async { // Sanity check the sampleId if (sampleId.contains(RegExp(r'[^-\w\.]'))) { throwToolExit('Sample ID "$sampleId" contains invalid characters. Check the ID in the ' @@ -120,7 +115,7 @@ class CreateCommand extends CreateBase { } final Uri snippetsUri = Uri.https(_snippetsHost, 'snippets/$sampleId.dart'); - final List data = await _net.fetchUrl(snippetsUri); + final List? data = await _net.fetchUrl(snippetsUri); if (data == null || data.isEmpty) { return null; } @@ -128,9 +123,9 @@ class CreateCommand extends CreateBase { } /// Fetches the samples index file from the Flutter docs website. - Future _fetchSamplesIndexFromServer() async { + Future _fetchSamplesIndexFromServer() async { final Uri snippetsUri = Uri.https(_snippetsHost, 'snippets/index.json'); - final List data = await _net.fetchUrl(snippetsUri, maxAttempts: 2); + final List? data = await _net.fetchUrl(snippetsUri, maxAttempts: 2); if (data == null || data.isEmpty) { return null; } @@ -145,7 +140,7 @@ class CreateCommand extends CreateBase { if (outputFile.existsSync()) { throwToolExit('File "$outputFilePath" already exists', exitCode: 1); } - final String samplesJson = await _fetchSamplesIndexFromServer(); + final String? samplesJson = await _fetchSamplesIndexFromServer(); if (samplesJson == null) { throwToolExit('Unable to download samples', exitCode: 2); } else { @@ -158,11 +153,12 @@ class CreateCommand extends CreateBase { } FlutterProjectType _getProjectType(Directory projectDir) { - FlutterProjectType template; - FlutterProjectType detectedProjectType; + FlutterProjectType? template; + FlutterProjectType? detectedProjectType; final bool metadataExists = projectDir.absolute.childFile('.metadata').existsSync(); - if (argResults['template'] != null) { - template = stringToProjectType(stringArgDeprecated('template')); + final String? templateArgument = stringArg('template'); + if (templateArgument != null) { + template = stringToProjectType(templateArgument); } // If the project directory exists and isn't empty, then try to determine the template // type from the project directory. @@ -188,23 +184,25 @@ class CreateCommand extends CreateBase { @override Future runCommand() async { - if (argResults['list-samples'] != null) { + final String? listSamples = stringArg('list-samples'); + if (listSamples != null) { // _writeSamplesJson can potentially be long-lived. - await _writeSamplesJson(stringArgDeprecated('list-samples')); + await _writeSamplesJson(listSamples); return FlutterCommandResult.success(); } validateOutputDirectoryArg(); - String sampleCode; - if (argResults['sample'] != null) { - if (argResults['template'] != null && - stringToProjectType(stringArgDeprecated('template') ?? 'app') != FlutterProjectType.app) { + String? sampleCode; + final String? sampleArgument = stringArg('sample'); + if (sampleArgument != null) { + final String? templateArgument = stringArg('template'); + if (templateArgument != null && stringToProjectType(templateArgument) != FlutterProjectType.app) { throwToolExit('Cannot specify --sample with a project type other than ' '"${flutterProjectTypeToString(FlutterProjectType.app)}"'); } // Fetch the sample from the server. - sampleCode = await _fetchSampleFromServer(stringArgDeprecated('sample')); + sampleCode = await _fetchSampleFromServer(sampleArgument); } final FlutterProjectType template = _getProjectType(projectDir); @@ -215,7 +213,7 @@ class CreateCommand extends CreateBase { final List platforms = stringsArg('platforms'); // `--platforms` does not support module or package. - if (argResults.wasParsed('platforms') && (generateModule || generatePackage)) { + if (argResults!.wasParsed('platforms') && (generateModule || generatePackage)) { final String template = generateModule ? 'module' : 'package'; throwToolExit( 'The "--platforms" argument is not supported in $template template.', @@ -224,18 +222,18 @@ class CreateCommand extends CreateBase { } else if (platforms == null || platforms.isEmpty) { throwToolExit('Must specify at least one platform using --platforms', exitCode: 2); - } else if (generateFfiPlugin && argResults.wasParsed('platforms') && platforms.contains('web')) { + } else if (generateFfiPlugin && argResults!.wasParsed('platforms') && platforms.contains('web')) { throwToolExit( 'The web platform is not supported in plugin_ffi template.', exitCode: 2, ); - } else if (generateFfiPlugin && argResults.wasParsed('ios-language')) { + } else if (generateFfiPlugin && argResults!.wasParsed('ios-language')) { throwToolExit( 'The "ios-language" option is not supported with the plugin_ffi ' 'template: the language will always be C or C++.', exitCode: 2, ); - } else if (generateFfiPlugin && argResults.wasParsed('android-language')) { + } else if (generateFfiPlugin && argResults!.wasParsed('android-language')) { throwToolExit( 'The "android-language" option is not supported with the plugin_ffi ' 'template: the language will always be C or C++.', @@ -258,7 +256,7 @@ class CreateCommand extends CreateBase { final String dartSdk = globals.cache.dartSdkBuild; final bool includeIos = featureFlags.isIOSEnabled && platforms.contains('ios'); - String developmentTeam; + String? developmentTeam; if (includeIos) { developmentTeam = await getCodeSigningIdentityDevelopmentTeam( processManager: globals.processManager, @@ -272,7 +270,7 @@ class CreateCommand extends CreateBase { // The dart project_name is in snake_case, this variable is the Title Case of the Project Name. final String titleCaseProjectName = snakeCaseToTitleCase(projectName); - final Map templateContext = createTemplateContext( + final Map templateContext = createTemplateContext( organization: organization, projectName: projectName, titleCaseProjectName: titleCaseProjectName, @@ -432,12 +430,12 @@ Your $application code is in $relativeAppMain. Future _generateModule( Directory directory, - Map templateContext, { + Map templateContext, { bool overwrite = false, bool printStatusWhenWriting = true, }) async { int generatedCount = 0; - final String description = argResults.wasParsed('description') + final String? description = argResults!.wasParsed('description') ? stringArgDeprecated('description') : 'A new Flutter module project.'; templateContext['description'] = description; @@ -453,7 +451,6 @@ Your $application code is in $relativeAppMain. context: PubContext.create, directory: directory.path, offline: boolArgDeprecated('offline'), - generateSyntheticPackage: false, ); final FlutterProject project = FlutterProject.fromDirectory(directory); await project.ensureReadyForPlatformSpecificTooling( @@ -466,12 +463,12 @@ Your $application code is in $relativeAppMain. Future _generatePackage( Directory directory, - Map templateContext, { + Map templateContext, { bool overwrite = false, bool printStatusWhenWriting = true, }) async { int generatedCount = 0; - final String description = argResults.wasParsed('description') + final String? description = argResults!.wasParsed('description') ? stringArgDeprecated('description') : 'A new Flutter package project.'; templateContext['description'] = description; @@ -487,7 +484,6 @@ Your $application code is in $relativeAppMain. context: PubContext.createPackage, directory: directory.path, offline: boolArgDeprecated('offline'), - generateSyntheticPackage: false, ); } return generatedCount; @@ -495,13 +491,13 @@ Your $application code is in $relativeAppMain. Future _generateMethodChannelPlugin( Directory directory, - Map templateContext, { + Map templateContext, { bool overwrite = false, bool printStatusWhenWriting = true, - FlutterProjectType projectType, + required FlutterProjectType projectType, }) async { // Plugins only add a platform if it was requested explicitly by the user. - if (!argResults.wasParsed('platforms')) { + if (!argResults!.wasParsed('platforms')) { for (final String platform in kAllCreatePlatforms) { templateContext[platform] = false; } @@ -517,7 +513,7 @@ Your $application code is in $relativeAppMain. final bool willAddPlatforms = platformsToAdd.isNotEmpty; templateContext['no_platforms'] = !willAddPlatforms; int generatedCount = 0; - final String description = argResults.wasParsed('description') + final String? description = argResults!.wasParsed('description') ? stringArgDeprecated('description') : 'A new Flutter plugin project.'; templateContext['description'] = description; @@ -534,7 +530,6 @@ Your $application code is in $relativeAppMain. context: PubContext.createPlugin, directory: directory.path, offline: boolArgDeprecated('offline'), - generateSyntheticPackage: false, ); } @@ -545,9 +540,9 @@ Your $application code is in $relativeAppMain. project: project, requireAndroidSdk: false); } - final String projectName = templateContext['projectName'] as String; - final String organization = templateContext['organization'] as String; - final String androidPluginIdentifier = templateContext['androidIdentifier'] as String; + final String? projectName = templateContext['projectName'] as String?; + final String organization = templateContext['organization']! as String; // Required to make the context. + final String? androidPluginIdentifier = templateContext['androidIdentifier'] as String?; final String exampleProjectName = '${projectName}_example'; templateContext['projectName'] = exampleProjectName; templateContext['androidIdentifier'] = CreateBase.createAndroidIdentifier(organization, exampleProjectName); @@ -572,13 +567,13 @@ Your $application code is in $relativeAppMain. Future _generateFfiPlugin( Directory directory, - Map templateContext, { + Map templateContext, { bool overwrite = false, bool printStatusWhenWriting = true, - FlutterProjectType projectType, + required FlutterProjectType projectType, }) async { // Plugins only add a platform if it was requested explicitly by the user. - if (!argResults.wasParsed('platforms')) { + if (!argResults!.wasParsed('platforms')) { for (final String platform in kAllCreatePlatforms) { templateContext[platform] = false; } @@ -596,7 +591,7 @@ Your $application code is in $relativeAppMain. final bool willAddPlatforms = platformsToAdd.isNotEmpty; templateContext['no_platforms'] = !willAddPlatforms; int generatedCount = 0; - final String description = argResults.wasParsed('description') + final String? description = argResults!.wasParsed('description') ? stringArgDeprecated('description') : 'A new Flutter FFI plugin project.'; templateContext['description'] = description; @@ -613,7 +608,6 @@ Your $application code is in $relativeAppMain. context: PubContext.createPlugin, directory: directory.path, offline: boolArgDeprecated('offline'), - generateSyntheticPackage: false, ); } @@ -623,9 +617,9 @@ Your $application code is in $relativeAppMain. gradle.updateLocalProperties(project: project, requireAndroidSdk: false); } - final String projectName = templateContext['projectName'] as String; - final String organization = templateContext['organization'] as String; - final String androidPluginIdentifier = templateContext['androidIdentifier'] as String; + final String? projectName = templateContext['projectName'] as String?; + final String organization = templateContext['organization']! as String; // Required to make the context. + final String? androidPluginIdentifier = templateContext['androidIdentifier'] as String?; final String exampleProjectName = '${projectName}_example'; templateContext['projectName'] = exampleProjectName; templateContext['androidIdentifier'] = CreateBase.createAndroidIdentifier(organization, exampleProjectName); @@ -662,7 +656,7 @@ Your $application code is in $relativeAppMain. return -files.length; } - List _getSupportedPlatformsFromTemplateContext(Map templateContext) { + List _getSupportedPlatformsFromTemplateContext(Map templateContext) { return [ for (String platform in kAllCreatePlatforms) if (templateContext[platform] == true) platform, @@ -671,7 +665,7 @@ Your $application code is in $relativeAppMain. // Returns a list of platforms that are explicitly requested by user via `--platforms`. List _getUserRequestedPlatforms() { - if (!argResults.wasParsed('platforms')) { + if (!argResults!.wasParsed('platforms')) { return []; } return stringsArg('platforms'); @@ -682,10 +676,11 @@ Your $application code is in $relativeAppMain. // Determine what platforms are supported based on generated files. List _getSupportedPlatformsInPlugin(Directory projectDir) { final String pubspecPath = globals.fs.path.join(projectDir.absolute.path, 'pubspec.yaml'); - final FlutterManifest manifest = FlutterManifest.createFromPath(pubspecPath, fileSystem: globals.fs, logger: globals.logger); - final List platforms = manifest.validSupportedPlatforms == null + final FlutterManifest? manifest = FlutterManifest.createFromPath(pubspecPath, fileSystem: globals.fs, logger: globals.logger); + final Map? validSupportedPlatforms = manifest?.validSupportedPlatforms; + final List platforms = validSupportedPlatforms == null ? [] - : manifest.validSupportedPlatforms.keys.toList(); + : validSupportedPlatforms.keys.toList(); return platforms; } diff --git a/packages/flutter_tools/lib/src/commands/create_base.dart b/packages/flutter_tools/lib/src/commands/create_base.dart index 93aa53973304..d4e2c7a29624 100644 --- a/packages/flutter_tools/lib/src/commands/create_base.dart +++ b/packages/flutter_tools/lib/src/commands/create_base.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 'package:pub_semver/pub_semver.dart'; import 'package:uuid/uuid.dart'; @@ -54,7 +52,7 @@ const String _kDefaultPlatformArgumentHelp = /// Common behavior for `flutter create` commands. abstract class CreateBase extends FlutterCommand { CreateBase({ - @required bool verboseHelp, + required bool verboseHelp, }) { argParser.addFlag( 'pub', @@ -64,7 +62,6 @@ abstract class CreateBase extends FlutterCommand { ); argParser.addFlag( 'offline', - defaultsTo: false, help: 'When "flutter pub get" is run by the create command, this indicates ' 'whether to run it in offline mode or not. In offline mode, it will need to ' @@ -72,8 +69,6 @@ abstract class CreateBase extends FlutterCommand { ); argParser.addFlag( 'with-driver-test', - negatable: true, - defaultsTo: false, help: '(deprecated) Historically, this added a flutter_driver dependency and generated a ' 'sample "flutter drive" test. Now it does nothing. Consider using the ' '"integration_test" package: https://pub.dev/packages/integration_test', @@ -81,8 +76,6 @@ abstract class CreateBase extends FlutterCommand { ); argParser.addFlag( 'overwrite', - negatable: true, - defaultsTo: false, help: 'When performing operations, overwrite existing files.', ); argParser.addOption( @@ -100,7 +93,6 @@ abstract class CreateBase extends FlutterCommand { ); argParser.addOption( 'project-name', - defaultsTo: null, help: 'The project name for this new Flutter project. This must be a valid dart package name.', ); @@ -134,7 +126,6 @@ abstract class CreateBase extends FlutterCommand { ); argParser.addOption( 'initial-create-revision', - defaultsTo: null, help: 'The Flutter SDK git commit hash to store in .migrate_config. This parameter is used by the tool ' 'internally and should generally not be used manually.', hide: !verboseHelp, @@ -144,7 +135,7 @@ abstract class CreateBase extends FlutterCommand { /// The output directory of the command. @protected Directory get projectDir { - return globals.fs.directory(argResults.rest.first); + return globals.fs.directory(argResults!.rest.first); } /// The normalized absolute path of [projectDir]. @@ -157,7 +148,7 @@ abstract class CreateBase extends FlutterCommand { /// /// The help message of the argument is replaced with `customHelp` if `customHelp` is not null. @protected - void addPlatformsOptions({String customHelp}) { + void addPlatformsOptions({String? customHelp}) { argParser.addMultiOption('platforms', help: customHelp ?? _kDefaultPlatformArgumentHelp, aliases: [ 'platform' ], @@ -173,16 +164,17 @@ abstract class CreateBase extends FlutterCommand { /// Throw with exit code 2 if the output directory is invalid. @protected void validateOutputDirectoryArg() { - if (argResults.rest.isEmpty) { + final List? rest = argResults?.rest; + if (rest == null || rest.isEmpty) { throwToolExit( 'No option specified for the output directory.\n$usage', exitCode: 2, ); } - if (argResults.rest.length > 1) { + if (rest.length > 1) { String message = 'Multiple output directories specified.'; - for (final String arg in argResults.rest) { + for (final String arg in rest) { if (arg.startsWith('-')) { message += '\nTry moving $arg to be immediately following $name'; break; @@ -194,7 +186,7 @@ abstract class CreateBase extends FlutterCommand { /// Gets the flutter root directory. @protected - String get flutterRoot => Cache.flutterRoot; + String get flutterRoot => Cache.flutterRoot!; /// Determines the project type in an existing flutter project. /// @@ -207,14 +199,15 @@ abstract class CreateBase extends FlutterCommand { /// Throws assertion if [projectDir] does not exist or empty. /// Returns null if no project type can be determined. @protected - FlutterProjectType determineTemplateType() { + FlutterProjectType? determineTemplateType() { assert(projectDir.existsSync() && projectDir.listSync().isNotEmpty); final File metadataFile = globals.fs .file(globals.fs.path.join(projectDir.absolute.path, '.metadata')); final FlutterProjectMetadata projectMetadata = FlutterProjectMetadata(metadataFile, globals.logger); - if (projectMetadata.projectType != null) { - return projectMetadata.projectType; + final FlutterProjectType? projectType = projectMetadata.projectType; + if (projectType != null) { + return projectType; } bool exists(List path) { @@ -243,8 +236,8 @@ abstract class CreateBase extends FlutterCommand { /// If `--org` is not specified, returns the organization from the existing project. @protected Future getOrganization() async { - String organization = stringArgDeprecated('org'); - if (!argResults.wasParsed('org')) { + String? organization = stringArgDeprecated('org'); + if (!argResults!.wasParsed('org')) { final FlutterProject project = FlutterProject.fromDirectory(projectDir); final Set existingOrganizations = await project.organizationNames; if (existingOrganizations.length == 1) { @@ -255,6 +248,9 @@ abstract class CreateBase extends FlutterCommand { 'The --org command line argument must be specified to recreate project.'); } } + if (organization == null) { + throwToolExit('The --org command line argument must be specified to create a project.'); + } return organization; } @@ -297,12 +293,10 @@ abstract class CreateBase extends FlutterCommand { // Do not overwrite files. throwToolExit("Invalid project name: '$projectDirPath' - file exists.", exitCode: 2); - break; case FileSystemEntityType.link: // Do not overwrite links. throwToolExit("Invalid project name: '$projectDirPath' - refers to a link.", exitCode: 2); - break; case FileSystemEntityType.directory: case FileSystemEntityType.notFound: break; @@ -317,7 +311,7 @@ abstract class CreateBase extends FlutterCommand { final String projectName = stringArgDeprecated('project-name') ?? globals.fs.path.basename(projectDirPath); if (!boolArgDeprecated('skip-name-checks')) { - final String error = _validateProjectName(projectName); + final String? error = _validateProjectName(projectName); if (error != null) { throwToolExit(error); } @@ -328,19 +322,19 @@ abstract class CreateBase extends FlutterCommand { /// Creates a template to use for [renderTemplate]. @protected - Map createTemplateContext({ - String organization, - String projectName, - String titleCaseProjectName, - String projectDescription, - String androidLanguage, - String iosDevelopmentTeam, - String iosLanguage, - String flutterRoot, - String dartSdkVersionBounds, - String agpVersion, - String kotlinVersion, - String gradleVersion, + Map createTemplateContext({ + required String organization, + required String projectName, + required String titleCaseProjectName, + String? projectDescription, + String? androidLanguage, + String? iosDevelopmentTeam, + String? iosLanguage, + required String flutterRoot, + required String dartSdkVersionBounds, + String? agpVersion, + String? kotlinVersion, + String? gradleVersion, bool withPlatformChannelPluginHook = false, bool withFfiPluginHook = false, bool ios = false, @@ -376,7 +370,7 @@ abstract class CreateBase extends FlutterCommand { ? globals.flutterVersion.frameworkVersion : ffiPluginStableRelease.toString(); - return { + return { 'organization': organization, 'projectName': projectName, 'titleCaseProjectName': titleCaseProjectName, @@ -433,7 +427,7 @@ abstract class CreateBase extends FlutterCommand { Future renderTemplate( String templateName, Directory directory, - Map context, { + Map context, { bool overwrite = false, bool printStatusWhenWriting = true, }) async { @@ -461,7 +455,7 @@ abstract class CreateBase extends FlutterCommand { Future renderMerged( List names, Directory directory, - Map context, { + Map context, { bool overwrite = false, bool printStatusWhenWriting = true, }) async { @@ -488,12 +482,12 @@ abstract class CreateBase extends FlutterCommand { Future generateApp( List templateNames, Directory directory, - Map templateContext, { + Map templateContext, { bool overwrite = false, bool pluginExampleApp = false, bool printStatusWhenWriting = true, bool generateMetadata = true, - FlutterProjectType projectType, + FlutterProjectType? projectType, }) async { int generatedCount = 0; generatedCount += await renderMerged( @@ -508,16 +502,16 @@ abstract class CreateBase extends FlutterCommand { generatedCount += _injectGradleWrapper(project); } - final bool androidPlatform = templateContext['android'] as bool ?? false; - final bool iosPlatform = templateContext['ios'] as bool ?? false; - final bool linuxPlatform = templateContext['linux'] as bool ?? false; - final bool macOSPlatform = templateContext['macos'] as bool ?? false; - final bool windowsPlatform = templateContext['windows'] as bool ?? false; - final bool webPlatform = templateContext['web'] as bool ?? false; + final bool androidPlatform = templateContext['android'] as bool? ?? false; + final bool iosPlatform = templateContext['ios'] as bool? ?? false; + final bool linuxPlatform = templateContext['linux'] as bool? ?? false; + final bool macOSPlatform = templateContext['macos'] as bool? ?? false; + final bool windowsPlatform = templateContext['windows'] as bool? ?? false; + final bool webPlatform = templateContext['web'] as bool? ?? false; if (boolArgDeprecated('pub')) { final Environment environment = Environment( - artifacts: globals.artifacts, + artifacts: globals.artifacts!, logger: globals.logger, cacheDir: globals.cache.getRoot(), engineVersion: globals.flutterVersion.engineRevision, @@ -591,7 +585,6 @@ abstract class CreateBase extends FlutterCommand { metadata.populate( platforms: platformsForMigrateConfig, projectDirectory: directory, - create: true, update: false, currentRevision: stringArgDeprecated('initial-create-revision') ?? globals.flutterVersion.frameworkRevision, createRevision: globals.flutterVersion.frameworkRevision, @@ -663,12 +656,10 @@ abstract class CreateBase extends FlutterCommand { return segments.join('.'); } - Set get _templateManifest => - __templateManifest ??= _computeTemplateManifest(); - Set __templateManifest; + late final Set _templateManifest = _computeTemplateManifest(); Set _computeTemplateManifest() { final String flutterToolsAbsolutePath = globals.fs.path.join( - Cache.flutterRoot, + Cache.flutterRoot!, 'packages', 'flutter_tools', ); @@ -681,7 +672,7 @@ abstract class CreateBase extends FlutterCommand { globals.fs.file(manifestPath).readAsStringSync(), ) as Map; return Set.from( - (manifest['files'] as List).cast().map( + (manifest['files']! as List).cast().map( (String path) => Uri.file(globals.fs.path.join(flutterToolsAbsolutePath, path))), ); @@ -793,7 +784,7 @@ const Set _packageDependencies = { /// Whether [name] is a valid Pub package. @visibleForTesting bool isValidPackageName(String name) { - final Match match = _identifierRegExp.matchAsPrefix(name); + final Match? match = _identifierRegExp.matchAsPrefix(name); return match != null && match.end == name.length && !_keywords.contains(name); @@ -801,7 +792,7 @@ bool isValidPackageName(String name) { // Return null if the project name is legal. Return a validation message if // we should disallow the project name. -String _validateProjectName(String projectName) { +String? _validateProjectName(String projectName) { if (!isValidPackageName(projectName)) { return '"$projectName" is not a valid Dart package name.\n\n' 'See https://dart.dev/tools/pub/pubspec#name for more information.'; diff --git a/packages/flutter_tools/lib/src/template.dart b/packages/flutter_tools/lib/src/template.dart index d32fa9642d7c..0ce99422464b 100644 --- a/packages/flutter_tools/lib/src/template.dart +++ b/packages/flutter_tools/lib/src/template.dart @@ -155,7 +155,7 @@ class Template { /// May throw a [ToolExit] if the directory is not writable. int render( Directory destination, - Map context, { + Map context, { bool overwriteExisting = true, bool printStatusWhenWriting = true, }) { diff --git a/packages/flutter_tools/test/src/test_flutter_command_runner.dart b/packages/flutter_tools/test/src/test_flutter_command_runner.dart index b8ad91f76b4f..528a01c4ef31 100644 --- a/packages/flutter_tools/test/src/test_flutter_command_runner.dart +++ b/packages/flutter_tools/test/src/test_flutter_command_runner.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 'dart:async'; import 'package:args/args.dart'; @@ -20,7 +18,7 @@ import 'package:flutter_tools/src/runner/flutter_command_runner.dart'; export 'package:test_api/test_api.dart' hide test, isInstanceOf; // ignore: deprecated_member_use -CommandRunner createTestCommandRunner([ FlutterCommand command ]) { +CommandRunner createTestCommandRunner([ FlutterCommand? command ]) { final FlutterCommandRunner runner = TestFlutterCommandRunner(); if (command != null) { runner.addCommand(command); @@ -31,7 +29,7 @@ CommandRunner createTestCommandRunner([ FlutterCommand command ]) { /// Creates a flutter project in the [temp] directory using the /// [arguments] list if specified, or `--no-pub` if not. /// Returns the path to the flutter project. -Future createProject(Directory temp, { List arguments }) async { +Future createProject(Directory temp, { List? arguments }) async { arguments ??= ['--no-pub']; final String projectPath = globals.fs.path.join(temp.path, 'flutter_project'); final CreateCommand command = CreateCommand(); @@ -61,7 +59,7 @@ class TestFlutterCommandRunner extends FlutterCommandRunner { userMessages: UserMessages(), ); // For compatibility with tests that set this to a relative path. - Cache.flutterRoot = globals.fs.path.normalize(globals.fs.path.absolute(Cache.flutterRoot)); + Cache.flutterRoot = globals.fs.path.normalize(globals.fs.path.absolute(Cache.flutterRoot!)); return super.runCommand(topLevelResults); } );