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