Skip to content

Commit 0ffc4ce

Browse files
authored
Remove --template=skeleton and add a placeholder error message instead. (#160695)
Closes flutter/flutter#160673. Does the following: - Renames `FlutterProjectType` to `FlutterTemplateType`; did some enhanced enum cleanups while at it - Creates a hierarchy of `RemovedFlutterTemplateType` from `ParsedFlutterTemplateType` - Removes the `skeleton` directory - Merges `app_shared` back into `app` (no longer required now that `skeleton` is removed) Final cleanups are tracked in flutter/flutter#160692. (Added @zanderso just to spot check this is what he meant by flutter/flutter#160673 (comment))
1 parent 62c6859 commit 0ffc4ce

File tree

169 files changed

+660
-1174
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

169 files changed

+660
-1174
lines changed

dev/bots/analyze.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2443,7 +2443,7 @@ final String _kTemplateRelativePath = path.join(
24432443
'packages',
24442444
'flutter_tools',
24452445
'templates',
2446-
'app_shared',
2446+
'app',
24472447
'windows.tmpl',
24482448
'runner',
24492449
);

engine/src/flutter/shell/platform/windows/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ See also:
1919

2020
1. [Flutter tool's Windows logic](https://github.com/flutter/flutter/tree/master/packages/flutter_tools/lib/src/windows) - Builds and runs Flutter Windows apps on
2121
the command line.
22-
1. [Windows app template](https://github.com/flutter/flutter/tree/master/packages/flutter_tools/templates/app_shared/windows.tmpl) - The entrypoint for Flutter Windows app. This
22+
1. [Windows app template](https://github.com/flutter/flutter/tree/master/packages/flutter_tools/templates/app/windows.tmpl) - The entrypoint for Flutter Windows app. This
2323
launches the Windows embedder.
2424
1. [`platform-windows` GitHub issues label](https://github.com/flutter/flutter/issues?q=is%3Aopen+label%3Aplatform-windows+sort%3Aupdated-desc)
2525
1. [`#hackers-desktop` Discord channel](https://discord.com/channels/608014603317936148/608020180177780791)

packages/flutter_tools/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Normally (from the root) we ignore .idea folders, but the ones present
2+
# in ide_templates/ and templates/ are real folders we intend to copy as part of
3+
# "flutter create".
4+
5+
!ide_templates/intellij/.idea
6+
!templates/**/.idea

packages/flutter_tools/lib/src/commands/create.dart

Lines changed: 65 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -104,13 +104,16 @@ class CreateCommand extends FlutterCommand with CreateBase {
104104
hide: !verboseHelp,
105105
);
106106
addPlatformsOptions(customHelp: kPlatformHelp);
107+
108+
final List<ParsedFlutterTemplateType> enabledTemplates =
109+
ParsedFlutterTemplateType.enabledValues(featureFlags);
107110
argParser.addOption(
108111
'template',
109112
abbr: 't',
110-
allowed: FlutterProjectType.enabledValues.map<String>((FlutterProjectType e) => e.cliName),
113+
allowed: enabledTemplates.map((ParsedFlutterTemplateType t) => t.cliName),
111114
help: 'Specify the type of project to create.',
112115
valueHelp: 'type',
113-
allowedHelp: CliEnum.allowedHelp(FlutterProjectType.enabledValues),
116+
allowedHelp: CliEnum.allowedHelp(enabledTemplates),
114117
);
115118
argParser.addOption(
116119
'sample',
@@ -228,13 +231,28 @@ class CreateCommand extends FlutterCommand with CreateBase {
228231
}
229232
}
230233

231-
FlutterProjectType _getProjectType(Directory projectDir) {
232-
FlutterProjectType? template;
233-
FlutterProjectType? detectedProjectType;
234+
FlutterTemplateType _getProjectType(Directory projectDir) {
235+
FlutterTemplateType? template;
236+
FlutterTemplateType? detectedProjectType;
234237
final bool metadataExists = projectDir.absolute.childFile('.metadata').existsSync();
235238
final String? templateArgument = stringArg('template');
236239
if (templateArgument != null) {
237-
template = FlutterProjectType.fromCliName(templateArgument);
240+
final ParsedFlutterTemplateType? parsedTemplate = ParsedFlutterTemplateType.fromCliName(
241+
templateArgument,
242+
);
243+
switch (parsedTemplate) {
244+
case RemovedFlutterTemplateType():
245+
throwToolExit(
246+
'The template ${parsedTemplate.cliName} is no longer available. For '
247+
'your convenience the former help text is repeated below with context '
248+
'about the removal and other possible resources:\n\n'
249+
'${parsedTemplate.helpText}',
250+
);
251+
case FlutterTemplateType():
252+
template = parsedTemplate;
253+
case null:
254+
break;
255+
}
238256
}
239257
// If the project directory exists and isn't empty, then try to determine the template
240258
// type from the project directory.
@@ -250,7 +268,7 @@ class CreateCommand extends FlutterCommand with CreateBase {
250268
);
251269
}
252270
}
253-
template ??= detectedProjectType ?? FlutterProjectType.app;
271+
template ??= detectedProjectType ?? FlutterTemplateType.app;
254272
if (detectedProjectType != null && template != detectedProjectType && metadataExists) {
255273
// We can only be definitive that this is the wrong type if the .metadata file
256274
// exists and contains a type that doesn't match.
@@ -279,27 +297,27 @@ class CreateCommand extends FlutterCommand with CreateBase {
279297
String? sampleCode;
280298
final String? sampleArgument = stringArg('sample');
281299
final bool emptyArgument = boolArg('empty');
282-
final FlutterProjectType template = _getProjectType(projectDir);
300+
final FlutterTemplateType template = _getProjectType(projectDir);
283301
if (sampleArgument != null) {
284-
if (template != FlutterProjectType.app) {
302+
if (template != FlutterTemplateType.app) {
285303
throwToolExit(
286304
'Cannot specify --sample with a project type other than '
287-
'"${FlutterProjectType.app.cliName}"',
305+
'"${FlutterTemplateType.app.cliName}"',
288306
);
289307
}
290308
// Fetch the sample from the server.
291309
sampleCode = await _fetchSampleFromServer(sampleArgument);
292310
}
293-
if (emptyArgument && template != FlutterProjectType.app) {
311+
if (emptyArgument && template != FlutterTemplateType.app) {
294312
throwToolExit('The --empty flag is only supported for the app template.');
295313
}
296314

297-
final bool generateModule = template == FlutterProjectType.module;
298-
final bool generateMethodChannelsPlugin = template == FlutterProjectType.plugin;
299-
final bool generateFfiPackage = template == FlutterProjectType.packageFfi;
300-
final bool generateFfiPlugin = template == FlutterProjectType.pluginFfi;
315+
final bool generateModule = template == FlutterTemplateType.module;
316+
final bool generateMethodChannelsPlugin = template == FlutterTemplateType.plugin;
317+
final bool generateFfiPackage = template == FlutterTemplateType.packageFfi;
318+
final bool generateFfiPlugin = template == FlutterTemplateType.pluginFfi;
301319
final bool generateFfi = generateFfiPlugin || generateFfiPackage;
302-
final bool generatePackage = template == FlutterProjectType.package;
320+
final bool generatePackage = template == FlutterTemplateType.package;
303321

304322
final List<String> platforms = stringsArg('platforms');
305323
// `--platforms` does not support module or package.
@@ -359,15 +377,15 @@ class CreateCommand extends FlutterCommand with CreateBase {
359377
final bool includeLinux;
360378
final bool includeMacos;
361379
final bool includeWindows;
362-
if (template == FlutterProjectType.module) {
380+
if (template == FlutterTemplateType.module) {
363381
// The module template only supports iOS and Android.
364382
includeIos = true;
365383
includeAndroid = true;
366384
includeWeb = false;
367385
includeLinux = false;
368386
includeMacos = false;
369387
includeWindows = false;
370-
} else if (template == FlutterProjectType.package) {
388+
} else if (template == FlutterTemplateType.package) {
371389
// The package template does not supports any platform.
372390
includeIos = false;
373391
includeAndroid = false;
@@ -443,7 +461,7 @@ class CreateCommand extends FlutterCommand with CreateBase {
443461
int generatedFileCount = 0;
444462
final PubContext pubContext;
445463
switch (template) {
446-
case FlutterProjectType.app:
464+
case FlutterTemplateType.app:
447465
final bool skipWidgetTestsGeneration = sampleCode != null || emptyArgument;
448466

449467
generatedFileCount += await generateApp(
@@ -455,33 +473,23 @@ class CreateCommand extends FlutterCommand with CreateBase {
455473
projectType: template,
456474
);
457475
pubContext = PubContext.create;
458-
case FlutterProjectType.skeleton:
459-
generatedFileCount += await generateApp(
460-
<String>['skeleton'],
461-
relativeDir,
462-
templateContext,
463-
overwrite: overwrite,
464-
printStatusWhenWriting: !creatingNewProject,
465-
generateMetadata: false,
466-
);
467-
pubContext = PubContext.create;
468-
case FlutterProjectType.module:
476+
case FlutterTemplateType.module:
469477
generatedFileCount += await _generateModule(
470478
relativeDir,
471479
templateContext,
472480
overwrite: overwrite,
473481
printStatusWhenWriting: !creatingNewProject,
474482
);
475483
pubContext = PubContext.create;
476-
case FlutterProjectType.package:
484+
case FlutterTemplateType.package:
477485
generatedFileCount += await _generatePackage(
478486
relativeDir,
479487
templateContext,
480488
overwrite: overwrite,
481489
printStatusWhenWriting: !creatingNewProject,
482490
);
483491
pubContext = PubContext.createPackage;
484-
case FlutterProjectType.plugin:
492+
case FlutterTemplateType.plugin:
485493
generatedFileCount += await _generateMethodChannelPlugin(
486494
relativeDir,
487495
templateContext,
@@ -490,7 +498,7 @@ class CreateCommand extends FlutterCommand with CreateBase {
490498
projectType: template,
491499
);
492500
pubContext = PubContext.createPlugin;
493-
case FlutterProjectType.pluginFfi:
501+
case FlutterTemplateType.pluginFfi:
494502
generatedFileCount += await _generateFfiPlugin(
495503
relativeDir,
496504
templateContext,
@@ -499,7 +507,7 @@ class CreateCommand extends FlutterCommand with CreateBase {
499507
projectType: template,
500508
);
501509
pubContext = PubContext.createPlugin;
502-
case FlutterProjectType.packageFfi:
510+
case FlutterTemplateType.packageFfi:
503511
generatedFileCount += await _generateFfiPackage(
504512
relativeDir,
505513
templateContext,
@@ -667,7 +675,7 @@ Your $application code is in $relativeAppMain.
667675
Map<String, Object?> templateContext, {
668676
bool overwrite = false,
669677
bool printStatusWhenWriting = true,
670-
required FlutterProjectType projectType,
678+
required FlutterTemplateType projectType,
671679
}) async {
672680
// Plugins only add a platform if it was requested explicitly by the user.
673681
if (!argResults!.wasParsed('platforms')) {
@@ -763,7 +771,7 @@ Your $application code is in $relativeAppMain.
763771
Map<String, Object?> templateContext, {
764772
bool overwrite = false,
765773
bool printStatusWhenWriting = true,
766-
required FlutterProjectType projectType,
774+
required FlutterTemplateType projectType,
767775
}) async {
768776
// Plugins only add a platform if it was requested explicitly by the user.
769777
if (!argResults!.wasParsed('platforms')) {
@@ -844,7 +852,7 @@ Your $application code is in $relativeAppMain.
844852
Map<String, Object?> templateContext, {
845853
bool overwrite = false,
846854
bool printStatusWhenWriting = true,
847-
required FlutterProjectType projectType,
855+
required FlutterTemplateType projectType,
848856
}) async {
849857
int generatedCount = 0;
850858
final String? description =
@@ -1025,7 +1033,7 @@ void _printIncompatibleJavaAgpGradleVersionsWarning({
10251033
required String templateGradleVersion,
10261034
required String templateAgpVersion,
10271035
required String templateAgpVersionForModule,
1028-
required FlutterProjectType projectType,
1036+
required FlutterTemplateType projectType,
10291037
required String projectDirPath,
10301038
}) {
10311039
// Determine if the Java version specified conflicts with the template Gradle or AGP version.
@@ -1041,7 +1049,7 @@ void _printIncompatibleJavaAgpGradleVersionsWarning({
10411049
);
10421050
String relevantTemplateAgpVersion = templateAgpVersion;
10431051

1044-
if (projectType == FlutterProjectType.module &&
1052+
if (projectType == FlutterTemplateType.module &&
10451053
Version.parse(templateAgpVersion)! < Version.parse(templateAgpVersionForModule)!) {
10461054
// If a module is being created, make sure to check for Java/AGP compatibility between the highest used version of AGP in the module template.
10471055
javaAgpVersionsCompatible = gradle.validateJavaAndAgp(
@@ -1066,7 +1074,7 @@ void _printIncompatibleJavaAgpGradleVersionsWarning({
10661074
);
10671075

10681076
if (!javaGradleVersionsCompatible) {
1069-
if (projectType == FlutterProjectType.plugin || projectType == FlutterProjectType.pluginFfi) {
1077+
if (projectType == FlutterTemplateType.plugin || projectType == FlutterTemplateType.pluginFfi) {
10701078
// Only impacted files could be in sample code.
10711079
return;
10721080
}
@@ -1157,24 +1165,26 @@ globally for Flutter by running:
11571165

11581166
// Returns path of the gradle-wrapper.properties file for the specified
11591167
// generated project type.
1160-
String? _getGradleWrapperPropertiesFilePath(FlutterProjectType projectType, String projectDirPath) {
1168+
String? _getGradleWrapperPropertiesFilePath(
1169+
FlutterTemplateType projectType,
1170+
String projectDirPath,
1171+
) {
11611172
String gradleWrapperPropertiesFilePath = '';
11621173
switch (projectType) {
1163-
case FlutterProjectType.app:
1164-
case FlutterProjectType.skeleton:
1174+
case FlutterTemplateType.app:
11651175
gradleWrapperPropertiesFilePath = globals.fs.path.join(
11661176
projectDirPath,
11671177
'android/gradle/wrapper/gradle-wrapper.properties',
11681178
);
1169-
case FlutterProjectType.module:
1179+
case FlutterTemplateType.module:
11701180
gradleWrapperPropertiesFilePath = globals.fs.path.join(
11711181
projectDirPath,
11721182
'.android/gradle/wrapper/gradle-wrapper.properties',
11731183
);
1174-
case FlutterProjectType.plugin:
1175-
case FlutterProjectType.pluginFfi:
1176-
case FlutterProjectType.package:
1177-
case FlutterProjectType.packageFfi:
1184+
case FlutterTemplateType.plugin:
1185+
case FlutterTemplateType.pluginFfi:
1186+
case FlutterTemplateType.package:
1187+
case FlutterTemplateType.packageFfi:
11781188
// TODO(camsim99): Add relevant file path for packageFfi when Android is supported.
11791189
// No gradle-wrapper.properties files not part of sample code that
11801190
// can be determined.
@@ -1186,18 +1196,17 @@ String? _getGradleWrapperPropertiesFilePath(FlutterProjectType projectType, Stri
11861196
// Returns the path(s) of the build.gradle file(s) for the specified generated
11871197
// project type.
11881198
List<String>? _getBuildGradleConfigurationFilePaths(
1189-
FlutterProjectType projectType,
1199+
FlutterTemplateType projectType,
11901200
String projectDirPath,
11911201
) {
11921202
final List<String> buildGradleConfigurationFilePaths = <String>[];
11931203
switch (projectType) {
1194-
case FlutterProjectType.app:
1195-
case FlutterProjectType.skeleton:
1196-
case FlutterProjectType.pluginFfi:
1204+
case FlutterTemplateType.app:
1205+
case FlutterTemplateType.pluginFfi:
11971206
buildGradleConfigurationFilePaths.add(
11981207
globals.fs.path.join(projectDirPath, 'android/build.gradle'),
11991208
);
1200-
case FlutterProjectType.module:
1209+
case FlutterTemplateType.module:
12011210
const String moduleBuildGradleFilePath = '.android/build.gradle';
12021211
const String moduleAppBuildGradleFlePath = '.android/app/build.gradle';
12031212
const String moduleFlutterBuildGradleFilePath = '.android/Flutter/build.gradle';
@@ -1206,12 +1215,12 @@ List<String>? _getBuildGradleConfigurationFilePaths(
12061215
globals.fs.path.join(projectDirPath, moduleAppBuildGradleFlePath),
12071216
globals.fs.path.join(projectDirPath, moduleFlutterBuildGradleFilePath),
12081217
]);
1209-
case FlutterProjectType.plugin:
1218+
case FlutterTemplateType.plugin:
12101219
buildGradleConfigurationFilePaths.add(
12111220
globals.fs.path.join(projectDirPath, 'android/app/build.gradle'),
12121221
);
1213-
case FlutterProjectType.package:
1214-
case FlutterProjectType.packageFfi:
1222+
case FlutterTemplateType.package:
1223+
case FlutterTemplateType.packageFfi:
12151224
// TODO(camsim99): Add any relevant file paths for packageFfi when Android is supported.
12161225
// No build.gradle file because there is no platform-specific implementation.
12171226
return null;

packages/flutter_tools/lib/src/commands/create_base.dart

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ mixin CreateBase on FlutterCommand {
158158
/// Throws assertion if [projectDir] does not exist or empty.
159159
/// Returns null if no project type can be determined.
160160
@protected
161-
FlutterProjectType? determineTemplateType() {
161+
FlutterTemplateType? determineTemplateType() {
162162
assert(projectDir.existsSync() && projectDir.listSync().isNotEmpty);
163163
final File metadataFile = globals.fs.file(
164164
globals.fs.path.join(projectDir.absolute.path, '.metadata'),
@@ -167,7 +167,7 @@ mixin CreateBase on FlutterCommand {
167167
metadataFile,
168168
globals.logger,
169169
);
170-
final FlutterProjectType? projectType = projectMetadata.projectType;
170+
final FlutterTemplateType? projectType = projectMetadata.projectType;
171171
if (projectType != null) {
172172
return projectType;
173173
}
@@ -184,7 +184,7 @@ mixin CreateBase on FlutterCommand {
184184
if (exists(<String>['android', 'app']) ||
185185
exists(<String>['ios', 'Runner']) ||
186186
exists(<String>['ios', 'Flutter'])) {
187-
return FlutterProjectType.app;
187+
return FlutterTemplateType.app;
188188
}
189189
// Since we can't really be definitive on nearly-empty directories, err on
190190
// the side of prudence and just say we don't know.
@@ -472,11 +472,11 @@ mixin CreateBase on FlutterCommand {
472472
bool pluginExampleApp = false,
473473
bool printStatusWhenWriting = true,
474474
bool generateMetadata = true,
475-
FlutterProjectType? projectType,
475+
FlutterTemplateType? projectType,
476476
}) async {
477477
int generatedCount = 0;
478478
generatedCount += await renderMerged(
479-
<String>[...templateNames, 'app_shared'],
479+
<String>[...templateNames],
480480
directory,
481481
templateContext,
482482
overwrite: overwrite,

0 commit comments

Comments
 (0)