From d8b6fa153a1ba065cbd4584141cbe8cc1350dc43 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Wed, 15 Jul 2020 10:12:52 -0700 Subject: [PATCH] [flutter_tools] generate a synthetic flutter_gen package on pub get (#61261) Allow configuring the flutter_manifest to support a synthetic package, this is done through flutter: generate: true. When running pub get, insert a flutter_gen entry into the packages if it does not already exist. This points to .dart_tool/flutter_gen, which can be updated to contain the generated intl sources (But doesn't currently) Adds an integration test that verifies this code can be run and imported when enabled. Part of #60914 --- .../lib/src/build_runner/build_runner.dart | 1 + .../src/build_runner/resident_web_runner.dart | 3 +- .../web_compilation_delegate.dart | 1 + .../lib/src/commands/create.dart | 10 +++- .../lib/src/commands/packages.dart | 9 ++-- .../flutter_tools/lib/src/commands/test.dart | 10 ++-- .../lib/src/commands/update_packages.dart | 2 + .../lib/src/commands/upgrade.dart | 8 ++- .../lib/src/commands/version.dart | 1 + .../flutter_tools/lib/src/context_runner.dart | 1 + packages/flutter_tools/lib/src/dart/pub.dart | 46 +++++++++++++++- .../lib/src/flutter_manifest.dart | 22 ++++++++ .../lib/src/runner/flutter_command.dart | 7 ++- packages/flutter_tools/lib/src/template.dart | 1 + .../hermetic/analyze_continuously_test.dart | 13 ++++- .../test/general.shard/dart/pub_get_test.dart | 19 +++++-- .../general.shard/flutter_manifest_test.dart | 54 +++++++++++++++++++ .../resident_web_runner_test.dart | 1 + .../integration.shard/flutter_gen_test.dart | 32 +++++++++++ .../test_data/basic_project.dart | 32 +++++++++-- .../integration.shard/test_data/project.dart | 4 ++ .../flutter_tools/test/src/throwing_pub.dart | 1 + .../flutter_tools/test/template_test.dart | 1 + 23 files changed, 254 insertions(+), 25 deletions(-) create mode 100644 packages/flutter_tools/test/integration.shard/flutter_gen_test.dart diff --git a/packages/flutter_tools/lib/src/build_runner/build_runner.dart b/packages/flutter_tools/lib/src/build_runner/build_runner.dart index 4331ac773f..ee3e01425a 100644 --- a/packages/flutter_tools/lib/src/build_runner/build_runner.dart +++ b/packages/flutter_tools/lib/src/build_runner/build_runner.dart @@ -104,6 +104,7 @@ class BuildRunner extends CodeGenerator { directory: generatedDirectory.path, upgrade: false, checkLastModified: false, + generateSyntheticPackage: false, ); if (!scriptIdFile.existsSync()) { scriptIdFile.createSync(recursive: true); diff --git a/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart b/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart index 2e93e2d36c..66afb5f50b 100644 --- a/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart +++ b/packages/flutter_tools/lib/src/build_runner/resident_web_runner.dart @@ -448,7 +448,8 @@ class _ResidentWebRunner extends ResidentWebRunner { // This will result in a NoSuchMethodError thrown by injected_handler.darts await pub.get( context: PubContext.pubGet, - directory: globals.fs.path.join(Cache.flutterRoot, 'packages', 'flutter_tools') + directory: globals.fs.path.join(Cache.flutterRoot, 'packages', 'flutter_tools'), + generateSyntheticPackage: false, ); final ExpressionCompiler expressionCompiler = diff --git a/packages/flutter_tools/lib/src/build_runner/web_compilation_delegate.dart b/packages/flutter_tools/lib/src/build_runner/web_compilation_delegate.dart index 7f2d700ad9..32c8024b81 100644 --- a/packages/flutter_tools/lib/src/build_runner/web_compilation_delegate.dart +++ b/packages/flutter_tools/lib/src/build_runner/web_compilation_delegate.dart @@ -211,6 +211,7 @@ class BuildDaemonCreator { await pub.get( context: PubContext.pubGet, directory: globals.fs.file(buildScriptPackages).parent.path, + generateSyntheticPackage: false, ); } final String flutterWebSdk = globals.artifacts.getArtifactPath(Artifact.flutterWebSdk); diff --git a/packages/flutter_tools/lib/src/commands/create.dart b/packages/flutter_tools/lib/src/commands/create.dart index d91ebd46f0..6739f6edae 100644 --- a/packages/flutter_tools/lib/src/commands/create.dart +++ b/packages/flutter_tools/lib/src/commands/create.dart @@ -543,6 +543,7 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi context: PubContext.create, directory: directory.path, offline: boolArg('offline'), + generateSyntheticPackage: false, ); final FlutterProject project = FlutterProject.fromDirectory(directory); await project.ensureReadyForPlatformSpecificTooling(checkProjects: false); @@ -562,6 +563,7 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi context: PubContext.createPackage, directory: directory.path, offline: boolArg('offline'), + generateSyntheticPackage: false, ); } return generatedCount; @@ -606,6 +608,7 @@ To edit platform code in an IDE see https://flutter.dev/developing-packages/#edi context: PubContext.createPlugin, directory: directory.path, offline: boolArg('offline'), + generateSyntheticPackage: false, ); } @@ -674,7 +677,12 @@ https://flutter.dev/docs/development/packages-and-plugins/developing-packages#pl } if (boolArg('pub')) { - await pub.get(context: PubContext.create, directory: directory.path, offline: boolArg('offline')); + await pub.get( + context: PubContext.create, + directory: directory.path, + offline: boolArg('offline'), + generateSyntheticPackage: false, + ); await project.ensureReadyForPlatformSpecificTooling(checkProjects: pluginExampleApp); } if (templateContext['android'] == true) { diff --git a/packages/flutter_tools/lib/src/commands/packages.dart b/packages/flutter_tools/lib/src/commands/packages.dart index f71c38ac69..65677d5303 100644 --- a/packages/flutter_tools/lib/src/commands/packages.dart +++ b/packages/flutter_tools/lib/src/commands/packages.dart @@ -88,7 +88,7 @@ class PackagesGetCommand extends FlutterCommand { return usageValues; } - Future _runPubGet(String directory) async { + Future _runPubGet(String directory, FlutterProject flutterProject) async { final Stopwatch pubGetTimer = Stopwatch()..start(); try { await pub.get(context: PubContext.pubGet, @@ -96,6 +96,7 @@ class PackagesGetCommand extends FlutterCommand { upgrade: upgrade , offline: boolArg('offline'), checkLastModified: false, + generateSyntheticPackage: flutterProject.manifest.generateSyntheticPackage, ); pubGetTimer.stop(); globals.flutterUsage.sendTiming('pub', 'get', pubGetTimer.elapsed, label: 'success'); @@ -121,15 +122,15 @@ class PackagesGetCommand extends FlutterCommand { '${ workingDirectory ?? "current working directory" }.' ); } - - await _runPubGet(target); final FlutterProject rootProject = FlutterProject.fromPath(target); + + await _runPubGet(target, rootProject); await rootProject.ensureReadyForPlatformSpecificTooling(checkProjects: true); // Get/upgrade packages in example app as well if (rootProject.hasExampleApp) { final FlutterProject exampleProject = rootProject.example; - await _runPubGet(exampleProject.directory.path); + await _runPubGet(exampleProject.directory.path, exampleProject); await exampleProject.ensureReadyForPlatformSpecificTooling(checkProjects: true); } diff --git a/packages/flutter_tools/lib/src/commands/test.dart b/packages/flutter_tools/lib/src/commands/test.dart index f30f73ea07..c556236d8a 100644 --- a/packages/flutter_tools/lib/src/commands/test.dart +++ b/packages/flutter_tools/lib/src/commands/test.dart @@ -163,15 +163,19 @@ class TestCommand extends FlutterCommand { "called *_test.dart and must reside in the package's 'test' " 'directory (or one of its subdirectories).'); } + final FlutterProject flutterProject = FlutterProject.current(); if (shouldRunPub) { - await pub.get(context: PubContext.getVerifyContext(name), skipPubspecYamlCheck: true); + await pub.get( + context: PubContext.getVerifyContext(name), + skipPubspecYamlCheck: true, + generateSyntheticPackage: flutterProject.manifest.generateSyntheticPackage, + ); } final bool buildTestAssets = boolArg('test-assets'); final List names = stringsArg('name'); final List plainNames = stringsArg('plain-name'); final String tags = stringArg('tags'); final String excludeTags = stringArg('exclude-tags'); - final FlutterProject flutterProject = FlutterProject.current(); if (buildTestAssets && flutterProject.manifest.assets.isNotEmpty) { await _buildTestAsset(); @@ -222,7 +226,7 @@ class TestCommand extends FlutterCommand { final bool machine = boolArg('machine'); CoverageCollector collector; if (boolArg('coverage') || boolArg('merge-coverage')) { - final String projectName = FlutterProject.current().manifest.appName; + final String projectName = flutterProject.manifest.appName; collector = CoverageCollector( verbose: !machine, libraryPredicate: (String libraryName) => libraryName.contains(projectName), diff --git a/packages/flutter_tools/lib/src/commands/update_packages.dart b/packages/flutter_tools/lib/src/commands/update_packages.dart index 37d7c13514..c16bdf7d9f 100644 --- a/packages/flutter_tools/lib/src/commands/update_packages.dart +++ b/packages/flutter_tools/lib/src/commands/update_packages.dart @@ -308,6 +308,7 @@ class UpdatePackagesCommand extends FlutterCommand { flutterRootOverride: upgrade ? temporaryFlutterSdk.path : null, + generateSyntheticPackage: false, ); // Cleanup the temporary SDK try { @@ -387,6 +388,7 @@ class UpdatePackagesCommand extends FlutterCommand { directory: dir.path, checkLastModified: false, offline: offline, + generateSyntheticPackage: false, ); count += 1; } diff --git a/packages/flutter_tools/lib/src/commands/upgrade.dart b/packages/flutter_tools/lib/src/commands/upgrade.dart index 3c0b182651..c852816757 100644 --- a/packages/flutter_tools/lib/src/commands/upgrade.dart +++ b/packages/flutter_tools/lib/src/commands/upgrade.dart @@ -294,7 +294,13 @@ class UpgradeCommandRunner { final String projectRoot = findProjectRoot(); if (projectRoot != null) { globals.printStatus(''); - await pub.get(context: PubContext.pubUpgrade, directory: projectRoot, upgrade: true, checkLastModified: false); + await pub.get( + context: PubContext.pubUpgrade, + directory: projectRoot, + upgrade: true, + checkLastModified: false, + generateSyntheticPackage: false, + ); } } diff --git a/packages/flutter_tools/lib/src/commands/version.dart b/packages/flutter_tools/lib/src/commands/version.dart index 5044364f95..056e3efac5 100644 --- a/packages/flutter_tools/lib/src/commands/version.dart +++ b/packages/flutter_tools/lib/src/commands/version.dart @@ -154,6 +154,7 @@ class VersionCommand extends FlutterCommand { directory: projectRoot, upgrade: true, checkLastModified: false, + generateSyntheticPackage: false, ); } diff --git a/packages/flutter_tools/lib/src/context_runner.dart b/packages/flutter_tools/lib/src/context_runner.dart index 53f355e442..c208e01b02 100644 --- a/packages/flutter_tools/lib/src/context_runner.dart +++ b/packages/flutter_tools/lib/src/context_runner.dart @@ -207,6 +207,7 @@ Future runInContext( botDetector: globals.botDetector, platform: globals.platform, usage: globals.flutterUsage, + toolStampFile: globals.cache.getStampFileFor('flutter_tools'), ), ShutdownHooks: () => ShutdownHooks(logger: globals.logger), Stdio: () => Stdio(), diff --git a/packages/flutter_tools/lib/src/dart/pub.dart b/packages/flutter_tools/lib/src/dart/pub.dart index 4029d12074..c69013d62e 100644 --- a/packages/flutter_tools/lib/src/dart/pub.dart +++ b/packages/flutter_tools/lib/src/dart/pub.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'package:meta/meta.dart'; +import 'package:package_config/package_config.dart'; import 'package:process/process.dart'; import '../base/bot_detector.dart'; @@ -16,6 +17,7 @@ import '../base/logger.dart'; import '../base/platform.dart'; import '../base/process.dart'; import '../cache.dart'; +import '../dart/package_map.dart'; import '../reporting/reporting.dart'; /// The [Pub] instance. @@ -39,7 +41,7 @@ class PubContext { for (final String item in _values) { if (!_validContext.hasMatch(item)) { throw ArgumentError.value( - _values, 'value', 'Must match RegExp ${_validContext.pattern}'); + _values, 'value', 'Must match RegExp ${_validContext.pattern}'); } } } @@ -80,6 +82,7 @@ abstract class Pub { @required Platform platform, @required BotDetector botDetector, @required Usage usage, + File toolStampFile, }) = _DefaultPub; /// Runs `pub get`. @@ -94,6 +97,7 @@ abstract class Pub { bool offline = false, bool checkLastModified = true, bool skipPubspecYamlCheck = false, + bool generateSyntheticPackage = false, String flutterRootOverride, }); @@ -139,7 +143,9 @@ class _DefaultPub implements Pub { @required Platform platform, @required BotDetector botDetector, @required Usage usage, - }) : _fileSystem = fileSystem, + File toolStampFile, + }) : _toolStampFile = toolStampFile, + _fileSystem = fileSystem, _logger = logger, _platform = platform, _botDetector = botDetector, @@ -155,6 +161,7 @@ class _DefaultPub implements Pub { final Platform _platform; final BotDetector _botDetector; final Usage _usage; + final File _toolStampFile; @override Future get({ @@ -165,6 +172,7 @@ class _DefaultPub implements Pub { bool offline = false, bool checkLastModified = true, bool skipPubspecYamlCheck = false, + bool generateSyntheticPackage = false, String flutterRootOverride, }) async { directory ??= _fileSystem.currentDirectory.path; @@ -173,6 +181,7 @@ class _DefaultPub implements Pub { _fileSystem.path.join(directory, 'pubspec.yaml')); final File packageConfigFile = _fileSystem.file( _fileSystem.path.join(directory, '.dart_tool', 'package_config.json')); + final Directory generatedDirectory = _fileSystem.directory(_fileSystem.path.join(directory, '.dart_tool', 'flutter_gen')); if (!skipPubspecYamlCheck && !pubSpecYaml.existsSync()) { if (!skipIfAbsent) { @@ -242,6 +251,10 @@ class _DefaultPub implements Pub { 'The time now is: $now' ); } + // Insert references to synthetic flutter package. + if (generateSyntheticPackage) { + await _updatePackageConfig(packageConfigFile, generatedDirectory); + } } @override @@ -387,6 +400,12 @@ class _DefaultPub implements Pub { if (pubSpecYaml.lastModifiedSync().isAfter(dotPackagesLastModified)) { return true; } + + if (_toolStampFile != null && + _toolStampFile.existsSync() && + _toolStampFile.lastModifiedSync().isAfter(dotPackagesLastModified)) { + return true; + } return false; } @@ -439,4 +458,27 @@ class _DefaultPub implements Pub { } return environment; } + + /// Insert the flutter_gen synthetic package into the package configuration file if + /// there is an l10n.yaml. + Future _updatePackageConfig(File packageConfigFile, Directory generatedDirectory) async { + if (!packageConfigFile.existsSync()) { + return; + } + final PackageConfig packageConfig = await loadPackageConfigWithLogging(packageConfigFile, logger: _logger); + final Package flutterGen = Package('flutter_gen', generatedDirectory.uri, languageVersion: LanguageVersion(2, 8)); + if (packageConfig.packages.any((Package package) => package.name == 'flutter_gen')) { + return; + } + final PackageConfig newPackageConfig = PackageConfig( + [ + ...packageConfig.packages, + flutterGen, + ], + ); + // There is no current API for saving a package_config without hitting the real filesystem. + if (packageConfigFile.fileSystem is LocalFileSystem) { + await savePackageConfig(newPackageConfig, packageConfigFile.parent.parent); + } + } } diff --git a/packages/flutter_tools/lib/src/flutter_manifest.dart b/packages/flutter_tools/lib/src/flutter_manifest.dart index bc2d2cddac..d2a8860b4b 100644 --- a/packages/flutter_tools/lib/src/flutter_manifest.dart +++ b/packages/flutter_tools/lib/src/flutter_manifest.dart @@ -279,6 +279,26 @@ class FlutterManifest { } return fonts; } + + /// Whether a synthetic flutter_gen package should be generated. + /// + /// This can be provided to the [Pub] interface to inject a new entry + /// into the package_config.json file which points to `.dart_tool/flutter_gen`. + /// + /// This allows generated source code to be imported using a package + /// alias. + bool get generateSyntheticPackage => _generateSyntheticPackage ??= _computeGenerateSyntheticPackage(); + bool _generateSyntheticPackage; + bool _computeGenerateSyntheticPackage() { + if (!_flutterDescriptor.containsKey('generate')) { + return false; + } + final Object value = _flutterDescriptor['generate']; + if (value is! bool) { + return false; + } + return value as bool; + } } class Font { @@ -438,6 +458,8 @@ void _validateFlutter(YamlMap yaml, List errors) { final List pluginErrors = Plugin.validatePluginYaml(kvp.value as YamlMap); errors.addAll(pluginErrors); break; + case 'generate': + break; default: errors.add('Unexpected child "${kvp.key}" found under "flutter".'); break; diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index c525f22a55..98188c95af 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart @@ -845,10 +845,13 @@ abstract class FlutterCommand extends Command { await validateCommand(); if (shouldRunPub) { - await pub.get(context: PubContext.getVerifyContext(name)); + final FlutterProject project = FlutterProject.current(); + await pub.get( + context: PubContext.getVerifyContext(name), + generateSyntheticPackage: project.manifest.generateSyntheticPackage, + ); // All done updating dependencies. Release the cache lock. Cache.releaseLock(); - final FlutterProject project = FlutterProject.current(); await project.ensureReadyForPlatformSpecificTooling(checkProjects: true); } else { Cache.releaseLock(); diff --git a/packages/flutter_tools/lib/src/template.dart b/packages/flutter_tools/lib/src/template.dart index b3f8f78094..931a41e2b8 100644 --- a/packages/flutter_tools/lib/src/template.dart +++ b/packages/flutter_tools/lib/src/template.dart @@ -301,5 +301,6 @@ Future _ensurePackageDependencies(String packagePath) async { await pub.get( context: PubContext.pubGet, directory: packagePath, + generateSyntheticPackage: false, ); } diff --git a/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart index a8001ccffd..e4dafc9749 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/analyze_continuously_test.dart @@ -77,7 +77,11 @@ void main() { botDetector: globals.botDetector, usage: globals.flutterUsage, ); - await pub.get(context: PubContext.flutterTests, directory: tempDir.path); + await pub.get( + context: PubContext.flutterTests, + directory: tempDir.path, + generateSyntheticPackage: false, + ); server = AnalysisServer( globals.artifacts.getArtifactPath(Artifact.engineDartSdkPath), @@ -111,8 +115,13 @@ void main() { platform: const LocalPlatform(), usage: globals.flutterUsage, botDetector: globals.botDetector, + toolStampFile: globals.fs.file('test'), + ); + await pub.get( + context: PubContext.flutterTests, + directory: tempDir.path, + generateSyntheticPackage: false, ); - await pub.get(context: PubContext.flutterTests, directory: tempDir.path); server = AnalysisServer( globals.artifacts.getArtifactPath(Artifact.engineDartSdkPath), diff --git a/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart b/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart index c8cc13845f..b200fa6ff4 100644 --- a/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart +++ b/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart @@ -197,10 +197,10 @@ void main() { }); testWithoutContext('analytics sent on success', () async { - MockDirectory.findCache = true; + final FileSystem fileSystem = MemoryFileSystem.test(); final MockUsage usage = MockUsage(); final Pub pub = Pub( - fileSystem: MockFileSystem(), + fileSystem: fileSystem, logger: BufferLogger.test(), processManager: MockProcessManager(0), botDetector: const BotDetectorAlwaysNo(), @@ -211,8 +211,16 @@ void main() { } ), ); + fileSystem.file('pubspec.yaml').createSync(); + fileSystem.file('.dart_tool/package_config.json') + ..createSync(recursive: true) + ..writeAsStringSync('{"configVersion": 2,"packages": []}'); - await pub.get(context: PubContext.flutterTests, checkLastModified: false); + await pub.get( + context: PubContext.flutterTests, + generateSyntheticPackage: true, + checkLastModified: false, + ); verify(usage.sendEvent('pub-result', 'flutter-tests', label: 'success')).called(1); }); @@ -242,10 +250,10 @@ void main() { }); testWithoutContext('analytics sent on failed version solve', () async { - MockDirectory.findCache = true; final MockUsage usage = MockUsage(); + final FileSystem fileSystem = MemoryFileSystem.test(); final Pub pub = Pub( - fileSystem: MockFileSystem(), + fileSystem: fileSystem, logger: BufferLogger.test(), processManager: MockProcessManager( 1, @@ -259,6 +267,7 @@ void main() { usage: usage, botDetector: const BotDetectorAlwaysNo(), ); + fileSystem.file('pubspec.yaml').writeAsStringSync('name: foo'); try { await pub.get(context: PubContext.flutterTests, checkLastModified: false); diff --git a/packages/flutter_tools/test/general.shard/flutter_manifest_test.dart b/packages/flutter_tools/test/general.shard/flutter_manifest_test.dart index ce85b2ecde..fb28e4dfe9 100644 --- a/packages/flutter_tools/test/general.shard/flutter_manifest_test.dart +++ b/packages/flutter_tools/test/general.shard/flutter_manifest_test.dart @@ -82,6 +82,60 @@ flutter: expect(flutterManifest.usesMaterialDesign, true); }); + testWithoutContext('FlutterManifest knows if generate is provided', () async { + const String manifest = ''' +name: test +dependencies: + flutter: + sdk: flutter +flutter: + generate: true +'''; + final BufferLogger logger = BufferLogger.test(); + final FlutterManifest flutterManifest = FlutterManifest.createFromString( + manifest, + logger: logger, + ); + + expect(flutterManifest.generateSyntheticPackage, true); + }); + + testWithoutContext('FlutterManifest can parse invalid generate key', () async { + const String manifest = ''' +name: test +dependencies: + flutter: + sdk: flutter +flutter: + generate: "invalid" +'''; + final BufferLogger logger = BufferLogger.test(); + final FlutterManifest flutterManifest = FlutterManifest.createFromString( + manifest, + logger: logger, + ); + + expect(flutterManifest.generateSyntheticPackage, false); + }); + + testWithoutContext('FlutterManifest knows if generate is disabled', () async { + const String manifest = ''' +name: test +dependencies: + flutter: + sdk: flutter +flutter: + generate: false +'''; + final BufferLogger logger = BufferLogger.test(); + final FlutterManifest flutterManifest = FlutterManifest.createFromString( + manifest, + logger: logger, + ); + + expect(flutterManifest.generateSyntheticPackage, false); + }); + testWithoutContext('FlutterManifest has two assets', () async { const String manifest = ''' name: test diff --git a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart index 67fb1e3fd4..9f2725cce2 100644 --- a/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/resident_web_runner_test.dart @@ -297,6 +297,7 @@ void main() { verify(pub.get( context: PubContext.pubGet, directory: anyNamed('directory'), + generateSyntheticPackage: false, )).called(1); expect(bufferLogger.statusText, contains('Debug service listening on ws://127.0.0.1/abcd/')); diff --git a/packages/flutter_tools/test/integration.shard/flutter_gen_test.dart b/packages/flutter_tools/test/integration.shard/flutter_gen_test.dart new file mode 100644 index 0000000000..cf98465a12 --- /dev/null +++ b/packages/flutter_tools/test/integration.shard/flutter_gen_test.dart @@ -0,0 +1,32 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:file/file.dart'; +import 'package:flutter_tools/src/base/file_system.dart'; + +import '../src/common.dart'; +import 'test_data/basic_project.dart'; +import 'test_driver.dart'; +import 'test_utils.dart'; + +void main() { + Directory tempDir; + final BasicProjectWithFlutterGen project = BasicProjectWithFlutterGen(); + FlutterRunTestDriver flutter; + + setUp(() async { + tempDir = createResolvedTempDirectorySync('run_test.'); + await project.setUpIn(tempDir); + flutter = FlutterRunTestDriver(tempDir); + }); + + tearDown(() async { + await flutter.stop(); + tryToDelete(tempDir); + }); + + test('can correctly reference flutter generated code.', () async { + await flutter.run(); + }); +} diff --git a/packages/flutter_tools/test/integration.shard/test_data/basic_project.dart b/packages/flutter_tools/test/integration.shard/test_data/basic_project.dart index a771ab51d2..5f899b9a60 100644 --- a/packages/flutter_tools/test/integration.shard/test_data/basic_project.dart +++ b/packages/flutter_tools/test/integration.shard/test_data/basic_project.dart @@ -53,7 +53,11 @@ class BasicProject extends Project { int get topLevelFunctionBreakpointLine => lineContaining(main, '// TOP LEVEL BREAKPOINT'); } -class BasicProjectWithUnaryMain extends Project { +class BasicProjectWithFlutterGen extends Project { + @override + final String generatedFile = ''' + String x = "a"; + '''; @override final String pubspec = ''' @@ -64,21 +68,42 @@ class BasicProjectWithUnaryMain extends Project { dependencies: flutter: sdk: flutter + + flutter: + generate: true '''; @override final String main = r''' import 'dart:async'; + import 'package:flutter_gen/flutter_gen.dart'; + void main() {} + '''; +} + +class BasicProjectWithUnaryMain extends Project { + + @override + final String pubspec = ''' + name: test + environment: + sdk: ">=2.0.0-dev.68.0 <3.0.0" + dependencies: + flutter: + sdk: flutter + '''; + + @override + final String main = r''' + import 'dart:async'; import 'package:flutter/material.dart'; - Future main(List args) async { while (true) { runApp(new MyApp()); await Future.delayed(const Duration(milliseconds: 50)); } } - class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { @@ -89,7 +114,6 @@ class BasicProjectWithUnaryMain extends Project { ); } } - topLevelFunction() { print("topLevelFunction"); // TOP LEVEL BREAKPOINT } diff --git a/packages/flutter_tools/test/integration.shard/test_data/project.dart b/packages/flutter_tools/test/integration.shard/test_data/project.dart index 1e888ceac3..01cae15509 100644 --- a/packages/flutter_tools/test/integration.shard/test_data/project.dart +++ b/packages/flutter_tools/test/integration.shard/test_data/project.dart @@ -27,6 +27,7 @@ abstract class Project { String get pubspec; String get main; String get test => null; + String get generatedFile => null; Uri get mainDart => Uri.parse('package:test/main.dart'); @@ -39,6 +40,9 @@ abstract class Project { if (test != null) { writeFile(globals.fs.path.join(dir.path, 'test', 'test.dart'), test); } + if (generatedFile != null) { + writeFile(globals.fs.path.join(dir.path, '.dart_tool', 'flutter_gen', 'flutter_gen.dart'), generatedFile); + } writeFile(globals.fs.path.join(dir.path, 'web', 'index.html'), _kDefaultHtml); writePackages(dir.path); await getPackages(dir.path); diff --git a/packages/flutter_tools/test/src/throwing_pub.dart b/packages/flutter_tools/test/src/throwing_pub.dart index 0e535cbacd..6fb864dc89 100644 --- a/packages/flutter_tools/test/src/throwing_pub.dart +++ b/packages/flutter_tools/test/src/throwing_pub.dart @@ -30,6 +30,7 @@ class ThrowingPub implements Pub { bool offline = false, bool checkLastModified = true, bool skipPubspecYamlCheck = false, + bool generateSyntheticPackage = false, String flutterRootOverride, }) { throw UnsupportedError('Attempted to invoke pub during test.'); diff --git a/packages/flutter_tools/test/template_test.dart b/packages/flutter_tools/test/template_test.dart index e0ea6520be..3d82a28a2e 100644 --- a/packages/flutter_tools/test/template_test.dart +++ b/packages/flutter_tools/test/template_test.dart @@ -95,6 +95,7 @@ void main() { when(pub.get( context: PubContext.pubGet, directory: anyNamed('directory'), + generateSyntheticPackage: false, )).thenAnswer((Invocation invocation) async { // Create valid package entry. packagesFile.writeAsStringSync('flutter_template_images:file:///flutter_template_images');