From a0334fb50036e4bb779119dca6b8664c57ea4442 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 24 Jun 2020 16:20:21 -0700 Subject: [PATCH] [flutter_tools] maintain file manifest for create (#59706) First pass at fixing #57985 and implementing #59602 This doesn't have enough metadata to be useful for IDEs yet, but it prevents the issue from getting worse while we iterate on it. --- .../lib/src/commands/create.dart | 29 +- .../lib/src/commands/ide_config.dart | 8 +- packages/flutter_tools/lib/src/project.dart | 4 +- packages/flutter_tools/lib/src/template.dart | 23 +- .../templates/template_manifest.json | 291 ++++++++++++++++++ .../hermetic/create_usage_test.dart | 4 + .../template_manifest_test.dart | 32 ++ .../flutter_tools/test/template_test.dart | 22 +- 8 files changed, 400 insertions(+), 13 deletions(-) create mode 100644 packages/flutter_tools/templates/template_manifest.json create mode 100644 packages/flutter_tools/test/integration.shard/template_manifest_test.dart diff --git a/packages/flutter_tools/lib/src/commands/create.dart b/packages/flutter_tools/lib/src/commands/create.dart index 112cd39ce0..3775be599e 100644 --- a/packages/flutter_tools/lib/src/commands/create.dart +++ b/packages/flutter_tools/lib/src/commands/create.dart @@ -278,6 +278,29 @@ class CreateCommand extends FlutterCommand { return template; } + Set get templateManifest => _templateManifest ??= _computeTemplateManifest(); + Set _templateManifest; + Set _computeTemplateManifest() { + final String flutterToolsAbsolutePath = globals.fs.path.join( + Cache.flutterRoot, + 'packages', + 'flutter_tools', + ); + final String manifestPath = globals.fs.path.join( + flutterToolsAbsolutePath, + 'templates', + 'template_manifest.json', + ); + final Map manifest = json.decode( + globals.fs.file(manifestPath).readAsStringSync(), + ) as Map; + return Set.from( + (manifest['files'] as List) + .cast() + .map((String path) => Uri.file(globals.fs.path.join(flutterToolsAbsolutePath, path))), + ); + } + @override Future runCommand() async { if (argResults['list-samples'] != null) { @@ -750,7 +773,11 @@ https://flutter.dev/docs/development/packages-and-plugins/developing-packages#pl } Future _renderTemplate(String templateName, Directory directory, Map context, { bool overwrite = false }) async { - final Template template = await Template.fromName(templateName, fileSystem: globals.fs); + final Template template = await Template.fromName( + templateName, + fileSystem: globals.fs, + templateManifest: templateManifest, + ); return template.render(directory, context, overwriteExisting: overwrite); } diff --git a/packages/flutter_tools/lib/src/commands/ide_config.dart b/packages/flutter_tools/lib/src/commands/ide_config.dart index a006416f52..ab7340d588 100644 --- a/packages/flutter_tools/lib/src/commands/ide_config.dart +++ b/packages/flutter_tools/lib/src/commands/ide_config.dart @@ -247,7 +247,13 @@ class IdeConfigCommand extends FlutterCommand { } int _renderTemplate(String templateName, String dirPath, Map context) { - final Template template = Template(_templateDirectory, _templateDirectory, null, fileSystem: globals.fs); + final Template template = Template( + _templateDirectory, + _templateDirectory, + null, + fileSystem: globals.fs, + templateManifest: null, + ); return template.render( globals.fs.directory(dirPath), context, diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart index 896a0fdd0d..2fe310cb81 100644 --- a/packages/flutter_tools/lib/src/project.dart +++ b/packages/flutter_tools/lib/src/project.dart @@ -647,7 +647,7 @@ class IosProject extends FlutterProjectPlatform implements XcodeBasedProject { } Future _overwriteFromTemplate(String path, Directory target) async { - final Template template = await Template.fromName(path, fileSystem: globals.fs); + final Template template = await Template.fromName(path, fileSystem: globals.fs, templateManifest: null); template.render( target, { @@ -797,7 +797,7 @@ class AndroidProject extends FlutterProjectPlatform { } Future _overwriteFromTemplate(String path, Directory target) async { - final Template template = await Template.fromName(path, fileSystem: globals.fs); + final Template template = await Template.fromName(path, fileSystem: globals.fs, templateManifest: null); template.render( target, { diff --git a/packages/flutter_tools/lib/src/template.dart b/packages/flutter_tools/lib/src/template.dart index d36353d3b1..b3f8f78094 100644 --- a/packages/flutter_tools/lib/src/template.dart +++ b/packages/flutter_tools/lib/src/template.dart @@ -32,7 +32,9 @@ import 'globals.dart' as globals hide fs; class Template { Template(Directory templateSource, Directory baseDir, this.imageSourceDir, { @required FileSystem fileSystem, - }) : _fileSystem = fileSystem { + @required Set templateManifest, + }) : _fileSystem = fileSystem, + _templateManifest = templateManifest { _templateFilePaths = {}; if (!templateSource.existsSync()) { @@ -46,10 +48,14 @@ class Template { // We are only interesting in template *file* URIs. continue; } + if (_templateManifest != null && !_templateManifest.contains(Uri.file(entity.absolute.path))) { + globals.logger.printTrace('Skipping ${entity.absolute.path}, missing from the template manifest.'); + // Skip stale files in the flutter_tools directory. + continue; + } final String relativePath = fileSystem.path.relative(entity.path, from: baseDir.absolute.path); - if (relativePath.contains(templateExtension)) { // If '.tmpl' appears anywhere within the path of this entity, it is // is a candidate for rendering. This catches cases where the folder @@ -59,14 +65,23 @@ class Template { } } - static Future