Unverified Commit 09987dc0 authored by Jenn Magder's avatar Jenn Magder Committed by GitHub

Migrate create command to null safety (#104484)

parent b5adbee1
......@@ -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 <output directory>';
String get invocation => '${runner?.executableName} $name <output directory>';
@override
Future<CustomDimensions> 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<HttpClientFactory>(),
logger: globals.logger,
platform: globals.platform,
......@@ -112,7 +107,7 @@ class CreateCommand extends CreateBase {
? 'api.flutter.dev'
: 'master-api.flutter.dev';
Future<String> _fetchSampleFromServer(String sampleId) async {
Future<String?> _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<int> data = await _net.fetchUrl(snippetsUri);
final List<int>? 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<String> _fetchSamplesIndexFromServer() async {
Future<String?> _fetchSamplesIndexFromServer() async {
final Uri snippetsUri = Uri.https(_snippetsHost, 'snippets/index.json');
final List<int> data = await _net.fetchUrl(snippetsUri, maxAttempts: 2);
final List<int>? 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<FlutterCommandResult> 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<String> 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<String, Object> templateContext = createTemplateContext(
final Map<String, Object?> templateContext = createTemplateContext(
organization: organization,
projectName: projectName,
titleCaseProjectName: titleCaseProjectName,
......@@ -432,12 +430,12 @@ Your $application code is in $relativeAppMain.
Future<int> _generateModule(
Directory directory,
Map<String, dynamic> templateContext, {
Map<String, Object?> 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<int> _generatePackage(
Directory directory,
Map<String, dynamic> templateContext, {
Map<String, Object?> 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<int> _generateMethodChannelPlugin(
Directory directory,
Map<String, dynamic> templateContext, {
Map<String, Object?> 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<int> _generateFfiPlugin(
Directory directory,
Map<String, dynamic> templateContext, {
Map<String, Object?> 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<String> _getSupportedPlatformsFromTemplateContext(Map<String, dynamic> templateContext) {
List<String> _getSupportedPlatformsFromTemplateContext(Map<String, Object?> templateContext) {
return <String>[
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<String> _getUserRequestedPlatforms() {
if (!argResults.wasParsed('platforms')) {
if (!argResults!.wasParsed('platforms')) {
return <String>[];
}
return stringsArg('platforms');
......@@ -682,10 +676,11 @@ Your $application code is in $relativeAppMain.
// Determine what platforms are supported based on generated files.
List<String> _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<String> platforms = manifest.validSupportedPlatforms == null
final FlutterManifest? manifest = FlutterManifest.createFromPath(pubspecPath, fileSystem: globals.fs, logger: globals.logger);
final Map<String, Object?>? validSupportedPlatforms = manifest?.validSupportedPlatforms;
final List<String> platforms = validSupportedPlatforms == null
? <String>[]
: manifest.validSupportedPlatforms.keys.toList();
: validSupportedPlatforms.keys.toList();
return platforms;
}
......
......@@ -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: <String>[ '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<String>? 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<String> path) {
......@@ -243,8 +236,8 @@ abstract class CreateBase extends FlutterCommand {
/// If `--org` is not specified, returns the organization from the existing project.
@protected
Future<String> 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<String> 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<String, Object> 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<String, Object?> 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 <String, Object>{
return <String, Object?>{
'organization': organization,
'projectName': projectName,
'titleCaseProjectName': titleCaseProjectName,
......@@ -433,7 +427,7 @@ abstract class CreateBase extends FlutterCommand {
Future<int> renderTemplate(
String templateName,
Directory directory,
Map<String, Object> context, {
Map<String, Object?> context, {
bool overwrite = false,
bool printStatusWhenWriting = true,
}) async {
......@@ -461,7 +455,7 @@ abstract class CreateBase extends FlutterCommand {
Future<int> renderMerged(
List<String> names,
Directory directory,
Map<String, Object> context, {
Map<String, Object?> context, {
bool overwrite = false,
bool printStatusWhenWriting = true,
}) async {
......@@ -488,12 +482,12 @@ abstract class CreateBase extends FlutterCommand {
Future<int> generateApp(
List<String> templateNames,
Directory directory,
Map<String, Object> templateContext, {
Map<String, Object?> 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<Uri> get _templateManifest =>
__templateManifest ??= _computeTemplateManifest();
Set<Uri> __templateManifest;
late final Set<Uri> _templateManifest = _computeTemplateManifest();
Set<Uri> _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<String, Object>;
return Set<Uri>.from(
(manifest['files'] as List<Object>).cast<String>().map<Uri>(
(manifest['files']! as List<Object>).cast<String>().map<Uri>(
(String path) =>
Uri.file(globals.fs.path.join(flutterToolsAbsolutePath, path))),
);
......@@ -793,7 +784,7 @@ const Set<String> _packageDependencies = <String>{
/// 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.';
......
......@@ -155,7 +155,7 @@ class Template {
/// May throw a [ToolExit] if the directory is not writable.
int render(
Directory destination,
Map<String, Object> context, {
Map<String, Object?> context, {
bool overwriteExisting = true,
bool printStatusWhenWriting = true,
}) {
......
......@@ -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<void> createTestCommandRunner([ FlutterCommand command ]) {
CommandRunner<void> createTestCommandRunner([ FlutterCommand? command ]) {
final FlutterCommandRunner runner = TestFlutterCommandRunner();
if (command != null) {
runner.addCommand(command);
......@@ -31,7 +29,7 @@ CommandRunner<void> 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<String> createProject(Directory temp, { List<String> arguments }) async {
Future<String> createProject(Directory temp, { List<String>? arguments }) async {
arguments ??= <String>['--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);
}
);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment