From d46da3ae112890054472f9c93e56e85edd1c0c2f Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Tue, 21 Apr 2020 19:55:15 -0700 Subject: [PATCH] [flutter_tools] remove PackageMap and finish PackageConfig migration (#55244) --- .../flutter_tools/bin/fuchsia_tester.dart | 2 +- packages/flutter_tools/lib/src/asset.dart | 14 +-- .../lib/src/build_runner/devfs_web.dart | 12 +- .../src/build_runner/resident_web_runner.dart | 2 +- .../web_compilation_delegate.dart | 2 +- .../lib/src/build_system/targets/dart.dart | 13 +- .../lib/src/build_system/targets/web.dart | 14 +-- packages/flutter_tools/lib/src/bundle.dart | 4 +- .../flutter_tools/lib/src/commands/drive.dart | 4 +- .../lib/src/commands/inject_plugins.dart | 2 +- .../lib/src/dart/package_map.dart | 111 ++++++------------ .../lib/src/macos/cocoapod_utils.dart | 2 +- packages/flutter_tools/lib/src/plugins.dart | 36 +++--- packages/flutter_tools/lib/src/project.dart | 2 +- .../lib/src/resident_runner.dart | 8 +- packages/flutter_tools/lib/src/run_hot.dart | 36 ++---- .../lib/src/runner/flutter_command.dart | 10 +- .../src/runner/flutter_command_runner.dart | 18 +-- packages/flutter_tools/lib/src/template.dart | 9 +- .../lib/src/test/coverage_collector.dart | 2 +- .../lib/src/test/flutter_platform.dart | 2 +- .../lib/src/test/flutter_web_platform.dart | 28 ++--- .../flutter_tools/lib/src/test/runner.dart | 4 +- .../lib/src/test/test_compiler.dart | 14 +-- .../lib/src/tester/flutter_tester.dart | 2 +- .../flutter_tools/lib/src/web/compile.dart | 2 +- .../build_system/targets/web_test.dart | 2 +- .../test/general.shard/plugins_test.dart | 50 ++++---- .../runner/flutter_command_runner_test.dart | 6 + 29 files changed, 159 insertions(+), 254 deletions(-) diff --git a/packages/flutter_tools/bin/fuchsia_tester.dart b/packages/flutter_tools/bin/fuchsia_tester.dart index 0fc00e52124..fb032bfb7fc 100644 --- a/packages/flutter_tools/bin/fuchsia_tester.dart +++ b/packages/flutter_tools/bin/fuchsia_tester.dart @@ -111,7 +111,7 @@ Future run(List args) async { // TODO(tvolkert): Remove once flutter_tester no longer looks for this. globals.fs.link(sdkRootDest.childFile('platform.dill').path).createSync('platform_strong.dill'); - PackageMap.globalPackagesPath = + globalPackagesPath = globals.fs.path.normalize(globals.fs.path.absolute(argResults[_kOptionPackages] as String)); Directory testDirectory; diff --git a/packages/flutter_tools/lib/src/asset.dart b/packages/flutter_tools/lib/src/asset.dart index 6db13de90df..e93a63fdb21 100644 --- a/packages/flutter_tools/lib/src/asset.dart +++ b/packages/flutter_tools/lib/src/asset.dart @@ -125,7 +125,7 @@ class _ManifestAssetBundle implements AssetBundle { bool reportLicensedPackages = false, }) async { assetDirPath ??= getAssetBuildDirectory(); - packagesPath ??= globals.fs.path.absolute(PackageMap.globalPackagesPath); + packagesPath ??= globals.fs.path.absolute(globalPackagesPath); FlutterManifest flutterManifest; try { flutterManifest = FlutterManifest.createFromPath( @@ -152,15 +152,9 @@ class _ManifestAssetBundle implements AssetBundle { } final String assetBasePath = globals.fs.path.dirname(globals.fs.path.absolute(manifestPath)); - final PackageConfig packageConfig = await loadPackageConfigUri( - globals.fs.file(packagesPath).absolute.uri, - loader: (Uri uri) { - final File file = globals.fs.file(uri); - if (!file.existsSync()) { - return null; - } - return file.readAsBytes(); - }, + final PackageConfig packageConfig = await loadPackageConfigOrFail( + globals.fs.file(packagesPath), + logger: globals.logger, ); final List wildcardDirectories = []; diff --git a/packages/flutter_tools/lib/src/build_runner/devfs_web.dart b/packages/flutter_tools/lib/src/build_runner/devfs_web.dart index b3d935e6fe1..b0089255af5 100644 --- a/packages/flutter_tools/lib/src/build_runner/devfs_web.dart +++ b/packages/flutter_tools/lib/src/build_runner/devfs_web.dart @@ -144,15 +144,9 @@ class WebAssetServer implements AssetReader { address = (await InternetAddress.lookup(hostname)).first; } final HttpServer httpServer = await HttpServer.bind(address, port); - final PackageConfig packageConfig = await loadPackageConfigUri( - globals.fs.file(PackageMap.globalPackagesPath).absolute.uri, - loader: (Uri uri) { - final File file = globals.fs.file(uri); - if (!file.existsSync()) { - return null; - } - return file.readAsBytes(); - } + final PackageConfig packageConfig = await loadPackageConfigOrFail( + globals.fs.file(globalPackagesPath), + logger: globals.logger, ); final Map digests = {}; final Map modules = {}; 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 26f1dbd87c7..4508c37e502 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 @@ -551,7 +551,7 @@ class _ResidentWebRunner extends ResidentWebRunner { ..createSync(); result = _generatedEntrypointDirectory.childFile('web_entrypoint.dart'); - final bool hasWebPlugins = findPlugins(flutterProject) + final bool hasWebPlugins = (await findPlugins(flutterProject)) .any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey)); await injectPlugins(flutterProject, checkProjects: true); 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 b41322c3644..1df05da1a11 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 @@ -41,7 +41,7 @@ class BuildRunnerWebCompilationProxy extends WebCompilationProxy { .childDirectory('.dart_tool') .createSync(); final FlutterProject flutterProject = FlutterProject.fromDirectory(projectDirectory); - final bool hasWebPlugins = findPlugins(flutterProject) + final bool hasWebPlugins = (await findPlugins(flutterProject)) .any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey)); final BuildDaemonClient client = await const BuildDaemonCreator().startBuildDaemon( projectDirectory.path, diff --git a/packages/flutter_tools/lib/src/build_system/targets/dart.dart b/packages/flutter_tools/lib/src/build_system/targets/dart.dart index b7bbcd439ef..4da27b7bc54 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/dart.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/dart.dart @@ -9,6 +9,7 @@ import '../../base/build.dart'; import '../../base/file_system.dart'; import '../../build_info.dart'; import '../../compile.dart'; +import '../../dart/package_map.dart'; import '../../globals.dart' as globals; import '../../project.dart'; import '../build_system.dart'; @@ -231,15 +232,9 @@ class KernelSnapshot extends Target { forceLinkPlatform = false; } - final PackageConfig packageConfig = await loadPackageConfigUri( - packagesFile.absolute.uri, - loader: (Uri uri) { - final File file = globals.fs.file(uri); - if (!file.existsSync()) { - return null; - } - return file.readAsBytes(); - } + final PackageConfig packageConfig = await loadPackageConfigOrFail( + environment.projectDir.childFile('.packages'), + logger: environment.logger, ); final CompilerOutput output = await compiler.compile( diff --git a/packages/flutter_tools/lib/src/build_system/targets/web.dart b/packages/flutter_tools/lib/src/build_system/targets/web.dart index 4937bd9c935..f31e25f2b53 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/web.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/web.dart @@ -57,15 +57,9 @@ class WebEntrypointTarget extends Target { final bool shouldInitializePlatform = environment.defines[kInitializePlatform] == 'true'; final bool hasPlugins = environment.defines[kHasWebPlugins] == 'true'; final Uri importUri = environment.fileSystem.file(targetFile).absolute.uri; - final PackageConfig packageConfig = await loadPackageConfigUri( - environment.projectDir.childFile('.packages').absolute.uri, - loader: (Uri uri) { - final File file = environment.fileSystem.file(uri); - if (!file.existsSync()) { - return null; - } - return file.readAsBytes(); - } + final PackageConfig packageConfig = await loadPackageConfigOrFail( + environment.projectDir.childFile('.packages'), + logger: environment.logger, ); // Use the PackageConfig to find the correct package-scheme import path @@ -159,7 +153,7 @@ class Dart2JSTarget extends Target { final bool csp = environment.defines[kCspMode] == 'true'; final BuildMode buildMode = getBuildModeForName(environment.defines[kBuildMode]); final String specPath = globals.fs.path.join(globals.artifacts.getArtifactPath(Artifact.flutterWebSdk), 'libraries.json'); - final String packageFile = PackageMap.globalPackagesPath; + final String packageFile = globalPackagesPath; final File outputKernel = environment.buildDir.childFile('app.dill'); final File outputFile = environment.buildDir.childFile('main.dart.js'); final List dartDefines = parseDartDefines(environment); diff --git a/packages/flutter_tools/lib/src/bundle.dart b/packages/flutter_tools/lib/src/bundle.dart index 8fd7fd69a8f..20e1b46dbe9 100644 --- a/packages/flutter_tools/lib/src/bundle.dart +++ b/packages/flutter_tools/lib/src/bundle.dart @@ -74,7 +74,7 @@ class BundleBuilder { mainPath ??= defaultMainPath; depfilePath ??= defaultDepfilePath; assetDirPath ??= getAssetBuildDirectory(); - packagesPath ??= globals.fs.path.absolute(PackageMap.globalPackagesPath); + packagesPath ??= globals.fs.path.absolute(globalPackagesPath); final FlutterProject flutterProject = FlutterProject.current(); await buildWithAssemble( buildMode: buildInfo.mode, @@ -177,7 +177,7 @@ Future buildAssets({ bool reportLicensedPackages = false, }) async { assetDirPath ??= getAssetBuildDirectory(); - packagesPath ??= globals.fs.path.absolute(PackageMap.globalPackagesPath); + packagesPath ??= globals.fs.path.absolute(globalPackagesPath); // Build the asset bundle. final AssetBundle assetBundle = AssetBundleFactory.instance.createBundle(); diff --git a/packages/flutter_tools/lib/src/commands/drive.dart b/packages/flutter_tools/lib/src/commands/drive.dart index 871a9327e25..b6bfdf26c65 100644 --- a/packages/flutter_tools/lib/src/commands/drive.dart +++ b/packages/flutter_tools/lib/src/commands/drive.dart @@ -470,14 +470,14 @@ void restoreTestRunner() { Future _runTests(List testArgs, Map environment) async { globals.printTrace('Running driver tests.'); - PackageMap.globalPackagesPath = globals.fs.path.normalize(globals.fs.path.absolute(PackageMap.globalPackagesPath)); + globalPackagesPath = globals.fs.path.normalize(globals.fs.path.absolute(globalPackagesPath)); final String dartVmPath = globals.fs.path.join(dartSdkPath, 'bin', 'dart'); final int result = await processUtils.stream( [ dartVmPath, ...dartVmFlags, ...testArgs, - '--packages=${PackageMap.globalPackagesPath}', + '--packages=$globalPackagesPath', '-rexpanded', ], environment: environment, diff --git a/packages/flutter_tools/lib/src/commands/inject_plugins.dart b/packages/flutter_tools/lib/src/commands/inject_plugins.dart index 2cf56338fc0..9f6b0e05e11 100644 --- a/packages/flutter_tools/lib/src/commands/inject_plugins.dart +++ b/packages/flutter_tools/lib/src/commands/inject_plugins.dart @@ -29,7 +29,7 @@ class InjectPluginsCommand extends FlutterCommand { @override Future runCommand() async { final FlutterProject project = FlutterProject.current(); - refreshPluginsList(project, checkProjects: true); + await refreshPluginsList(project, checkProjects: true); await injectPlugins(project, checkProjects: true); final bool result = hasPlugins(project); if (result) { diff --git a/packages/flutter_tools/lib/src/dart/package_map.dart b/packages/flutter_tools/lib/src/dart/package_map.dart index 316aae4b585..e7b122128e8 100644 --- a/packages/flutter_tools/lib/src/dart/package_map.dart +++ b/packages/flutter_tools/lib/src/dart/package_map.dart @@ -2,86 +2,53 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -import 'package:meta/meta.dart'; -// TODO(bkonyi): remove deprecated member usage, https://github.com/flutter/flutter/issues/51951 -// ignore: deprecated_member_use -import 'package:package_config/packages_file.dart' as packages_file; +import 'dart:typed_data'; +import 'package:meta/meta.dart'; +import 'package:package_config/package_config.dart'; + +import '../base/common.dart'; import '../base/file_system.dart'; -import '../globals.dart' as globals hide fs; +import '../base/logger.dart'; const String kPackagesFileName = '.packages'; -Map _parse(String packagesPath, FileSystem fileSystem) { - final List source = fileSystem.file(packagesPath).readAsBytesSync(); - return packages_file.parse(source, - Uri.file(packagesPath, windows: globals.platform.isWindows)); +String get globalPackagesPath => _globalPackagesPath ?? kPackagesFileName; + +set globalPackagesPath(String value) { + _globalPackagesPath = value; } -class PackageMap { - PackageMap(this.packagesPath, { - @required FileSystem fileSystem, - }) : _fileSystem = fileSystem; +bool get isUsingCustomPackagesPath => _globalPackagesPath != null; - /// Create a [PackageMap] for testing. - PackageMap.test(Map input, { - @required FileSystem fileSystem, - }) : packagesPath = '.packages', - _map = input, - _fileSystem = fileSystem; +String _globalPackagesPath; - final FileSystem _fileSystem; - - static String get globalPackagesPath => _globalPackagesPath ?? kPackagesFileName; - - static set globalPackagesPath(String value) { - _globalPackagesPath = value; - } - - static bool get isUsingCustomPackagesPath => _globalPackagesPath != null; - - static String _globalPackagesPath; - - final String packagesPath; - - /// Load and parses the .packages file. - void load() { - _map ??= _parse(packagesPath, _fileSystem); - } - - Map get map { - load(); - return _map; - } - Map _map; - - /// Returns the path to [packageUri]. - String pathForPackage(Uri packageUri) => uriForPackage(packageUri).path; - - /// Returns the path to [packageUri] as URL. - Uri uriForPackage(Uri packageUri) { - assert(packageUri.scheme == 'package'); - final List pathSegments = packageUri.pathSegments.toList(); - final String packageName = pathSegments.removeAt(0); - final Uri packageBase = map[packageName]; - if (packageBase == null) { - return null; +/// Load the package configuration from [file] or throws a [ToolExit] +/// if the operation would fail. +Future loadPackageConfigOrFail(File file, { + @required Logger logger, +}) { + final FileSystem fileSystem = file.fileSystem; + return loadPackageConfigUri( + file.absolute.uri, + loader: (Uri uri) { + final File configFile = fileSystem.file(uri); + if (!configFile.existsSync()) { + return null; + } + return Future.value(configFile.readAsBytesSync()); + }, + onError: (dynamic error) { + logger.printTrace(error.toString()); + String message = '${file.path} does not exist.'; + final String pubspecPath = fileSystem.path.absolute(fileSystem.path.dirname(file.path), 'pubspec.yaml'); + if (fileSystem.isFileSync(pubspecPath)) { + message += '\nDid you run "flutter pub get" in this directory?'; + } else { + message += '\nDid you run this command from the same directory as your pubspec.yaml file?'; + } + logger.printError(message); + throwToolExit(null); } - final String packageRelativePath = _fileSystem.path.joinAll(pathSegments); - return packageBase.resolveUri(_fileSystem.path.toUri(packageRelativePath)); - } - - String checkValid() { - if (_fileSystem.isFileSync(packagesPath)) { - return null; - } - String message = '$packagesPath does not exist.'; - final String pubspecPath = _fileSystem.path.absolute(_fileSystem.path.dirname(packagesPath), 'pubspec.yaml'); - if (_fileSystem.isFileSync(pubspecPath)) { - message += '\nDid you run "flutter pub get" in this directory?'; - } else { - message += '\nDid you run this command from the same directory as your pubspec.yaml file?'; - } - return message; - } + ); } diff --git a/packages/flutter_tools/lib/src/macos/cocoapod_utils.dart b/packages/flutter_tools/lib/src/macos/cocoapod_utils.dart index f45b2d44f28..86667f430c9 100644 --- a/packages/flutter_tools/lib/src/macos/cocoapod_utils.dart +++ b/packages/flutter_tools/lib/src/macos/cocoapod_utils.dart @@ -16,7 +16,7 @@ import '../project.dart'; Future processPodsIfNeeded(XcodeBasedProject xcodeProject, String buildDirectory, BuildMode buildMode) async { final FlutterProject project = xcodeProject.parent; // Ensure that the plugin list is up to date, since hasPlugins relies on it. - refreshPluginsList(project); + await refreshPluginsList(project); if (!(hasPlugins(project) || (project.isModule && xcodeProject.podfile.existsSync()))) { return; } diff --git a/packages/flutter_tools/lib/src/plugins.dart b/packages/flutter_tools/lib/src/plugins.dart index 366bcbc916a..af951b1030b 100644 --- a/packages/flutter_tools/lib/src/plugins.dart +++ b/packages/flutter_tools/lib/src/plugins.dart @@ -5,6 +5,7 @@ import 'dart:async'; import 'package:meta/meta.dart'; +import 'package:package_config/package_config.dart'; import 'package:yaml/yaml.dart'; import 'android/gradle.dart'; @@ -298,26 +299,23 @@ Plugin _pluginFromPackage(String name, Uri packageRoot) { ); } -List findPlugins(FlutterProject project) { +Future> findPlugins(FlutterProject project) async { final List plugins = []; - Map packages; - try { - final String packagesFile = globals.fs.path.join( - project.directory.path, - PackageMap.globalPackagesPath, - ); - packages = PackageMap(packagesFile, fileSystem: globals.fs).map; - } on FormatException catch (e) { - globals.printTrace('Invalid .packages file: $e'); - return plugins; - } - packages.forEach((String name, Uri uri) { - final Uri packageRoot = uri.resolve('..'); - final Plugin plugin = _pluginFromPackage(name, packageRoot); + final String packagesFile = globals.fs.path.join( + project.directory.path, + globalPackagesPath, + ); + final PackageConfig packageConfig = await loadPackageConfigOrFail( + globals.fs.file(packagesFile), + logger: globals.logger, + ); + for (final Package package in packageConfig.packages) { + final Uri packageRoot = package.packageUriRoot.resolve('..'); + final Plugin plugin = _pluginFromPackage(package.name, packageRoot); if (plugin != null) { plugins.add(plugin); } - }); + } return plugins; } @@ -1065,8 +1063,8 @@ void _createPlatformPluginSymlinks(Directory symlinkDirectory, List pla /// which already exist. /// /// Assumes `pub get` has been executed since last change to `pubspec.yaml`. -void refreshPluginsList(FlutterProject project, {bool checkProjects = false}) { - final List plugins = findPlugins(project); +Future refreshPluginsList(FlutterProject project, {bool checkProjects = false}) async { + final List plugins = await findPlugins(project); // TODO(franciscojma): Remove once migration is complete. // Write the legacy plugin files to avoid breaking existing apps. @@ -1093,7 +1091,7 @@ void refreshPluginsList(FlutterProject project, {bool checkProjects = false}) { /// /// Assumes [refreshPluginsList] has been called since last change to `pubspec.yaml`. Future injectPlugins(FlutterProject project, {bool checkProjects = false}) async { - final List plugins = findPlugins(project); + final List plugins = await findPlugins(project); if ((checkProjects && project.android.existsSync()) || !checkProjects) { await _writeAndroidPluginRegistrant(project, plugins); } diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart index fd7fa2e0b1c..c6fd7528574 100644 --- a/packages/flutter_tools/lib/src/project.dart +++ b/packages/flutter_tools/lib/src/project.dart @@ -226,7 +226,7 @@ class FlutterProject { if (!directory.existsSync() || hasExampleApp) { return; } - refreshPluginsList(this); + await refreshPluginsList(this); if ((android.existsSync() && checkProjects) || !checkProjects) { await android.ensureReadyForPlatformSpecificTooling(); } diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart index 0650e27ff27..c3b7beede94 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart @@ -59,7 +59,7 @@ class FlutterDevice { targetModel: targetModel, experimentalFlags: experimentalFlags, dartDefines: buildInfo.dartDefines, - packagesPath: PackageMap.globalPackagesPath, + packagesPath: globalPackagesPath, ); /// Create a [FlutterDevice] with optional code generation enabled. @@ -107,7 +107,7 @@ class FlutterDevice { dartDefines: buildInfo.dartDefines, librariesSpec: globals.fs.file(globals.artifacts .getArtifactPath(Artifact.flutterWebLibrariesJson)).uri.toString(), - packagesPath: PackageMap.globalPackagesPath, + packagesPath: globalPackagesPath, ); } else { generator = ResidentCompiler( @@ -124,7 +124,7 @@ class FlutterDevice { experimentalFlags: experimentalFlags, dartDefines: buildInfo.dartDefines, initializeFromDill: globals.fs.path.join(getBuildDirectory(), 'cache.dill'), - packagesPath: PackageMap.globalPackagesPath, + packagesPath: globalPackagesPath, ); } @@ -665,7 +665,7 @@ abstract class ResidentRunner { String dillOutputPath, }) : mainPath = findMainDartFile(target), projectRootPath = projectRootPath ?? globals.fs.currentDirectory.path, - packagesFilePath = packagesFilePath ?? globals.fs.path.absolute(PackageMap.globalPackagesPath), + packagesFilePath = packagesFilePath ?? globals.fs.path.absolute(globalPackagesPath), _dillOutputPath = dillOutputPath, artifactDirectory = dillOutputPath == null ? globals.fs.systemTempDirectory.createTempSync('flutter_tool.') diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart index 9b11efe03bb..9a2c6414561 100644 --- a/packages/flutter_tools/lib/src/run_hot.dart +++ b/packages/flutter_tools/lib/src/run_hot.dart @@ -157,15 +157,9 @@ class HotRunner extends ResidentRunner { final Stopwatch stopwatch = Stopwatch()..start(); final UpdateFSReport results = UpdateFSReport(success: true); final List invalidated = [Uri.parse(libraryId)]; - final PackageConfig packageConfig = await loadPackageConfigUri( - globals.fs.file(PackageMap.globalPackagesPath).absolute.uri, - loader: (Uri uri) { - final File file = globals.fs.file(uri); - if (!file.existsSync()) { - return null; - } - return file.readAsBytes(); - } + final PackageConfig packageConfig = await loadPackageConfigOrFail( + globals.fs.file(globalPackagesPath), + logger: globals.logger, ); for (final FlutterDevice device in flutterDevices) { results.incorporateResults(await device.updateDevFS( @@ -361,15 +355,9 @@ class HotRunner extends ResidentRunner { firstBuildTime = DateTime.now(); final List> startupTasks = >[]; - final PackageConfig packageConfig = await loadPackageConfigUri( - globals.fs.file(PackageMap.globalPackagesPath).absolute.uri, - loader: (Uri uri) { - final File file = globals.fs.file(uri); - if (!file.existsSync()) { - return null; - } - return file.readAsBytes(); - } + final PackageConfig packageConfig = await loadPackageConfigOrFail( + globals.fs.file(globalPackagesPath), + logger: globals.logger, ); for (final FlutterDevice device in flutterDevices) { // Here we initialize the frontend_server concurrently with the platform @@ -1301,15 +1289,9 @@ class ProjectFileInvalidator { } Future _createPackageConfig(String packagesPath) { - return loadPackageConfigUri( - _fileSystem.file(packagesPath).absolute.uri, - loader: (Uri uri) { - final File file = _fileSystem.file(uri); - if (!file.existsSync()) { - return null; - } - return file.readAsBytes(); - } + return loadPackageConfigOrFail( + _fileSystem.file(globalPackagesPath), + logger: _logger, ); } } diff --git a/packages/flutter_tools/lib/src/runner/flutter_command.dart b/packages/flutter_tools/lib/src/runner/flutter_command.dart index 31a9dc9dca3..5d5aa78c89f 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart @@ -818,7 +818,7 @@ abstract class FlutterCommand extends Command { @protected @mustCallSuper Future validateCommand() async { - if (_requiresPubspecYaml && !PackageMap.isUsingCustomPackagesPath) { + if (_requiresPubspecYaml && !isUsingCustomPackagesPath) { // Don't expect a pubspec.yaml file if the user passed in an explicit .packages file path. // If there is no pubspec in the current directory, look in the parent @@ -835,14 +835,6 @@ abstract class FlutterCommand extends Command { if (changedDirectory) { globals.printStatus('Changing current working directory to: ${globals.fs.currentDirectory.path}'); } - - // Validate the current package map only if we will not be running "pub get" later. - if (parent?.name != 'pub' && !(_usesPubOption && boolArg('pub'))) { - final String error = PackageMap(PackageMap.globalPackagesPath, fileSystem: globals.fs).checkValid(); - if (error != null) { - throw ToolExit(error); - } - } } if (_usesTargetOption) { diff --git a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart index 5059c4054e2..9ba234948f6 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command_runner.dart @@ -314,7 +314,7 @@ class FlutterCommandRunner extends CommandRunner { } if (topLevelResults.wasParsed('packages')) { - PackageMap.globalPackagesPath = globals.fs.path.normalize(globals.fs.path.absolute(topLevelResults['packages'] as String)); + globalPackagesPath = globals.fs.path.normalize(globals.fs.path.absolute(topLevelResults['packages'] as String)); } // See if the user specified a specific device. @@ -354,19 +354,9 @@ class FlutterCommandRunner extends CommandRunner { if (engineSourcePath == null && globalResults['local-engine'] != null) { try { - final PackageConfig packageConfig = await loadPackageConfigUri( - globals.fs.file(PackageMap.globalPackagesPath).absolute.uri, - onError: (dynamic error) { - // Errors indicate the automatic detection will fail, but are not - // fatal. - }, - loader: (Uri uri) { - final File file = globals.fs.file(uri); - if (!file.existsSync()) { - return null; - } - return file.readAsBytes(); - }, + final PackageConfig packageConfig = await loadPackageConfigOrFail( + globals.fs.file(globalPackagesPath), + logger: globals.logger, ); Uri engineUri = packageConfig[kFlutterEnginePackageName]?.packageUriRoot; // Skip if sky_engine is the self-contained one. diff --git a/packages/flutter_tools/lib/src/template.dart b/packages/flutter_tools/lib/src/template.dart index 499c8aba183..31e8bc7f7a7 100644 --- a/packages/flutter_tools/lib/src/template.dart +++ b/packages/flutter_tools/lib/src/template.dart @@ -3,6 +3,8 @@ // found in the LICENSE file. import 'package:meta/meta.dart'; +import 'package:package_config/package_config.dart'; +import 'package:package_config/package_config_types.dart'; import 'base/common.dart'; import 'base/file_system.dart'; @@ -247,8 +249,11 @@ Future _templateImageDirectory(String name, FileSystem fileSystem) as if (!fileSystem.file(packageFilePath).existsSync()) { await _ensurePackageDependencies(toolPackagePath); } - final PackageMap packageConfig = PackageMap(packageFilePath, fileSystem: fileSystem); - final Uri imagePackageLibDir = packageConfig.map['flutter_template_images']; + final PackageConfig packageConfig = await loadPackageConfigOrFail( + fileSystem.file(packageFilePath), + logger: globals.logger, + ); + final Uri imagePackageLibDir = packageConfig['flutter_template_images']?.packageUriRoot; // Ensure that the template image package is present. if (imagePackageLibDir == null || !fileSystem.directory(imagePackageLibDir).existsSync()) { await _ensurePackageDependencies(toolPackagePath); diff --git a/packages/flutter_tools/lib/src/test/coverage_collector.dart b/packages/flutter_tools/lib/src/test/coverage_collector.dart index be308469060..cb18c6ccc3f 100644 --- a/packages/flutter_tools/lib/src/test/coverage_collector.dart +++ b/packages/flutter_tools/lib/src/test/coverage_collector.dart @@ -115,7 +115,7 @@ class CoverageCollector extends TestWatcher { return null; } if (formatter == null) { - final coverage.Resolver resolver = coverage.Resolver(packagesPath: PackageMap.globalPackagesPath); + final coverage.Resolver resolver = coverage.Resolver(packagesPath: globalPackagesPath); final String packagePath = globals.fs.currentDirectory.path; final List reportOn = coverageDirectory == null ? [globals.fs.path.join(packagePath, 'lib')] diff --git a/packages/flutter_tools/lib/src/test/flutter_platform.dart b/packages/flutter_tools/lib/src/test/flutter_platform.dart index a27aa8f50c7..a27e406abd8 100644 --- a/packages/flutter_tools/lib/src/test/flutter_platform.dart +++ b/packages/flutter_tools/lib/src/test/flutter_platform.dart @@ -459,7 +459,7 @@ class FlutterPlatform extends PlatformPlugin { final Process process = await _startProcess( shellPath, mainDart, - packages: PackageMap.globalPackagesPath, + packages: globalPackagesPath, enableObservatory: enableObservatory, startPaused: startPaused, disableServiceAuthCodes: disableServiceAuthCodes, diff --git a/packages/flutter_tools/lib/src/test/flutter_web_platform.dart b/packages/flutter_tools/lib/src/test/flutter_web_platform.dart index fa153ec3cc9..258f731ec09 100644 --- a/packages/flutter_tools/lib/src/test/flutter_web_platform.dart +++ b/packages/flutter_tools/lib/src/test/flutter_web_platform.dart @@ -97,32 +97,20 @@ class FlutterWebPlatform extends PlatformPlugin { ); } - final Future _packagesFuture = loadPackageConfigUri( - Uri.base.resolve('.packages'), - loader: (Uri uri) { - final File file = globals.fs.file(uri); - if (!file.existsSync()) { - return null; - } - return file.readAsBytes(); - } + final Future _packagesFuture = loadPackageConfigOrFail( + globals.fs.file(globalPackagesPath), + logger: globals.logger, ); - final Future _flutterToolsPackageMap = loadPackageConfigUri( + final Future _flutterToolsPackageMap = loadPackageConfigOrFail( globals.fs.file(globals.fs.path.join( Cache.flutterRoot, 'packages', 'flutter_tools', '.packages', - )).absolute.uri, - loader: (Uri uri) { - final File file = globals.fs.file(uri); - if (!file.existsSync()) { - return null; - } - return file.readAsBytes(); - } - ); + )), + logger: globals.logger, + ); /// Uri of the test package. Future get testUri async => (await _flutterToolsPackageMap)['test']?.packageUriRoot; @@ -874,7 +862,7 @@ class TestGoldenComparator { shellPath, '--disable-observatory', '--non-interactive', - '--packages=${PackageMap.globalPackagesPath}', + '--packages=$globalPackagesPath', output, ]; diff --git a/packages/flutter_tools/lib/src/test/runner.dart b/packages/flutter_tools/lib/src/test/runner.dart index 851d539d383..8df2eff329a 100644 --- a/packages/flutter_tools/lib/src/test/runner.dart +++ b/packages/flutter_tools/lib/src/test/runner.dart @@ -179,8 +179,8 @@ class _FlutterTestRunnerImpl implements FlutterTestRunner { // Make the global packages path absolute. // (Makes sure it still works after we change the current directory.) - PackageMap.globalPackagesPath = - globals.fs.path.normalize(globals.fs.path.absolute(PackageMap.globalPackagesPath)); + globalPackagesPath = + globals.fs.path.normalize(globals.fs.path.absolute(globalPackagesPath)); // Call package:test's main method in the appropriate directory. final Directory saved = globals.fs.currentDirectory; diff --git a/packages/flutter_tools/lib/src/test/test_compiler.dart b/packages/flutter_tools/lib/src/test/test_compiler.dart index c569c379786..c6c5bc7dcb6 100644 --- a/packages/flutter_tools/lib/src/test/test_compiler.dart +++ b/packages/flutter_tools/lib/src/test/test_compiler.dart @@ -103,7 +103,7 @@ class TestCompiler { initializeFromDill: testFilePath, unsafePackageSerialization: false, dartDefines: const [], - packagesPath: PackageMap.globalPackagesPath, + packagesPath: globalPackagesPath, ); if (flutterProject.hasBuilders) { return CodeGeneratingResidentCompiler.create( @@ -126,15 +126,9 @@ class TestCompiler { if (!isEmpty) { return; } - _packageConfig ??= await loadPackageConfigUri( - globals.fs.file(PackageMap.globalPackagesPath).absolute.uri, - loader: (Uri uri) async { - final File file = globals.fs.file(uri); - if (!file.existsSync()) { - return null; - } - return file.readAsBytes(); - } + _packageConfig ??= await loadPackageConfigOrFail( + globals.fs.file(globalPackagesPath), + logger: globals.logger, ); while (compilationQueue.isNotEmpty) { final _CompilationRequest request = compilationQueue.first; diff --git a/packages/flutter_tools/lib/src/tester/flutter_tester.dart b/packages/flutter_tools/lib/src/tester/flutter_tester.dart index 1158886447c..8ae000a119a 100644 --- a/packages/flutter_tools/lib/src/tester/flutter_tester.dart +++ b/packages/flutter_tools/lib/src/tester/flutter_tester.dart @@ -128,7 +128,7 @@ class FlutterTesterDevice extends Device { '--run-forever', '--non-interactive', '--enable-dart-profiling', - '--packages=${PackageMap.globalPackagesPath}', + '--packages=$globalPackagesPath', ]; if (debuggingOptions.debuggingEnabled) { if (debuggingOptions.startPaused) { diff --git a/packages/flutter_tools/lib/src/web/compile.dart b/packages/flutter_tools/lib/src/web/compile.dart index e4d99ecdc46..80db5598404 100644 --- a/packages/flutter_tools/lib/src/web/compile.dart +++ b/packages/flutter_tools/lib/src/web/compile.dart @@ -32,7 +32,7 @@ Future buildWeb( if (!flutterProject.web.existsSync()) { throwToolExit('Missing index.html.'); } - final bool hasWebPlugins = findPlugins(flutterProject) + final bool hasWebPlugins = (await findPlugins(flutterProject)) .any((Plugin p) => p.platforms.containsKey(WebPlugin.kConfigKey)); await injectPlugins(flutterProject, checkProjects: true); final Status status = globals.logger.startProgress('Compiling $target for the Web...', timeout: null); diff --git a/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart b/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart index ee6a1ee404e..330ea597f29 100644 --- a/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart +++ b/packages/flutter_tools/test/general.shard/build_system/targets/web_test.dart @@ -46,7 +46,7 @@ void main() { final File packagesFile = globals.fs.file(globals.fs.path.join('foo', '.packages')) ..createSync(recursive: true) ..writeAsStringSync('foo:lib/\n'); - PackageMap.globalPackagesPath = packagesFile.path; + globalPackagesPath = packagesFile.path; globals.fs.currentDirectory.childDirectory('bar').createSync(); processManager = FakeProcessManager.list([]); diff --git a/packages/flutter_tools/test/general.shard/plugins_test.dart b/packages/flutter_tools/test/general.shard/plugins_test.dart index bbc52a18fbf..709ac06e1f5 100644 --- a/packages/flutter_tools/test/general.shard/plugins_test.dart +++ b/packages/flutter_tools/test/general.shard/plugins_test.dart @@ -104,7 +104,7 @@ void main() { // Set up a simple .packages file for all the tests to use, pointing to one package. dummyPackageDirectory = fs.directory('/pubcache/apackage/lib/'); - packagesFile = fs.file(fs.path.join(flutterProject.directory.path, PackageMap.globalPackagesPath)); + packagesFile = fs.file(fs.path.join(flutterProject.directory.path, globalPackagesPath)); packagesFile..createSync(recursive: true) ..writeAsStringSync('apackage:file://${dummyPackageDirectory.path}\n'); }); @@ -359,8 +359,9 @@ EndGlobal'''); } group('refreshPlugins', () { - testUsingContext('Refreshing the plugin list is a no-op when the plugins list stays empty', () { - refreshPluginsList(flutterProject); + testUsingContext('Refreshing the plugin list is a no-op when the plugins list stays empty', () async { + await refreshPluginsList(flutterProject); + expect(flutterProject.flutterPluginsFile.existsSync(), false); expect(flutterProject.flutterPluginsDependenciesFile.existsSync(), false); }, overrides: { @@ -368,11 +369,12 @@ EndGlobal'''); ProcessManager: () => FakeProcessManager.any(), }); - testUsingContext('Refreshing the plugin list deletes the plugin file when there were plugins but no longer are', () { + testUsingContext('Refreshing the plugin list deletes the plugin file when there were plugins but no longer are', () async { flutterProject.flutterPluginsFile.createSync(); flutterProject.flutterPluginsDependenciesFile.createSync(); - refreshPluginsList(flutterProject); + await refreshPluginsList(flutterProject); + expect(flutterProject.flutterPluginsFile.existsSync(), false); expect(flutterProject.flutterPluginsDependenciesFile.existsSync(), false); }, overrides: { @@ -380,11 +382,12 @@ EndGlobal'''); ProcessManager: () => FakeProcessManager.any(), }); - testUsingContext('Refreshing the plugin list creates a plugin directory when there are plugins', () { + testUsingContext('Refreshing the plugin list creates a plugin directory when there are plugins', () async { configureDummyPackageAsPlugin(); when(iosProject.existsSync()).thenReturn(true); - refreshPluginsList(flutterProject); + await refreshPluginsList(flutterProject); + expect(flutterProject.flutterPluginsFile.existsSync(), true); expect(flutterProject.flutterPluginsDependenciesFile.existsSync(), true); }, overrides: { @@ -392,7 +395,9 @@ EndGlobal'''); ProcessManager: () => FakeProcessManager.any(), }); - testUsingContext('Refreshing the plugin list modifies .flutter-plugins and .flutter-plugins-dependencies when there are plugins', () { + testUsingContext( + 'Refreshing the plugin list modifies .flutter-plugins ' + 'and .flutter-plugins-dependencies when there are plugins', () async { final Directory pluginA = createPluginWithDependencies(name: 'plugin-a', dependencies: const ['plugin-b', 'plugin-c', 'random-package']); final Directory pluginB = createPluginWithDependencies(name: 'plugin-b', dependencies: const ['plugin-c']); final Directory pluginC = createPluginWithDependencies(name: 'plugin-c', dependencies: const []); @@ -407,7 +412,7 @@ EndGlobal'''); (Invocation _) => version ); - refreshPluginsList(flutterProject); + await refreshPluginsList(flutterProject); // Verify .flutter-plugins-dependencies is configured correctly. expect(flutterProject.flutterPluginsFile.existsSync(), true); @@ -494,13 +499,14 @@ EndGlobal'''); FlutterVersion: () => mockVersion }); - testUsingContext('Changes to the plugin list invalidates the Cocoapod lockfiles', () { + testUsingContext('Changes to the plugin list invalidates the Cocoapod lockfiles', () async { simulatePodInstallRun(iosProject); simulatePodInstallRun(macosProject); configureDummyPackageAsPlugin(); when(iosProject.existsSync()).thenReturn(true); when(macosProject.existsSync()).thenReturn(true); - refreshPluginsList(flutterProject); + + await refreshPluginsList(flutterProject); expect(iosProject.podManifestLock.existsSync(), false); expect(macosProject.podManifestLock.existsSync(), false); }, overrides: { @@ -510,7 +516,7 @@ EndGlobal'''); FlutterVersion: () => mockVersion }); - testUsingContext('No changes to the plugin list does not invalidate the Cocoapod lockfiles', () { + testUsingContext('No changes to the plugin list does not invalidate the Cocoapod lockfiles', () async { configureDummyPackageAsPlugin(); when(iosProject.existsSync()).thenReturn(true); when(macosProject.existsSync()).thenReturn(true); @@ -519,11 +525,11 @@ EndGlobal'''); // Since there was no plugins list, the lock files will be invalidated. // The second call is where the plugins list is compared to the existing one, and if there is no change, // the podfiles shouldn't be invalidated. - refreshPluginsList(flutterProject); + await refreshPluginsList(flutterProject); simulatePodInstallRun(iosProject); simulatePodInstallRun(macosProject); - refreshPluginsList(flutterProject); + await refreshPluginsList(flutterProject); expect(iosProject.podManifestLock.existsSync(), true); expect(macosProject.podManifestLock.existsSync(), true); }, overrides: { @@ -1081,11 +1087,11 @@ flutter: when(featureFlags.isWindowsEnabled).thenReturn(true); }); - testUsingContext('Symlinks are created for Linux plugins', () { + testUsingContext('Symlinks are created for Linux plugins', () async { when(linuxProject.existsSync()).thenReturn(true); configureDummyPackageAsPlugin(); // refreshPluginsList should call createPluginSymlinks. - refreshPluginsList(flutterProject); + await refreshPluginsList(flutterProject); expect(linuxProject.pluginSymlinkDirectory.childLink('apackage').existsSync(), true); }, overrides: { @@ -1094,11 +1100,11 @@ flutter: FeatureFlags: () => featureFlags, }); - testUsingContext('Symlinks are created for Windows plugins', () { + testUsingContext('Symlinks are created for Windows plugins', () async { when(windowsProject.existsSync()).thenReturn(true); configureDummyPackageAsPlugin(); // refreshPluginsList should call createPluginSymlinks. - refreshPluginsList(flutterProject); + await refreshPluginsList(flutterProject); expect(windowsProject.pluginSymlinkDirectory.childLink('apackage').existsSync(), true); }, overrides: { @@ -1130,7 +1136,7 @@ flutter: FeatureFlags: () => featureFlags, }); - testUsingContext('Existing symlinks are removed automatically on refresh when no longer in use', () { + testUsingContext('Existing symlinks are removed automatically on refresh when no longer in use', () async { when(linuxProject.existsSync()).thenReturn(true); when(windowsProject.existsSync()).thenReturn(true); @@ -1144,7 +1150,7 @@ flutter: // refreshPluginsList should remove existing links and recreate on changes. configureDummyPackageAsPlugin(); - refreshPluginsList(flutterProject); + await refreshPluginsList(flutterProject); for (final File file in dummyFiles) { expect(file.existsSync(), false); @@ -1179,11 +1185,11 @@ flutter: FeatureFlags: () => featureFlags, }); - testUsingContext('createPluginSymlinks repairs missing links', () { + testUsingContext('createPluginSymlinks repairs missing links', () async { when(linuxProject.existsSync()).thenReturn(true); when(windowsProject.existsSync()).thenReturn(true); configureDummyPackageAsPlugin(); - refreshPluginsList(flutterProject); + await refreshPluginsList(flutterProject); final List links = [ linuxProject.pluginSymlinkDirectory.childLink('apackage'), diff --git a/packages/flutter_tools/test/general.shard/runner/flutter_command_runner_test.dart b/packages/flutter_tools/test/general.shard/runner/flutter_command_runner_test.dart index 3779ff895a1..19126608500 100644 --- a/packages/flutter_tools/test/general.shard/runner/flutter_command_runner_test.dart +++ b/packages/flutter_tools/test/general.shard/runner/flutter_command_runner_test.dart @@ -116,11 +116,13 @@ void main() { fs.directory('$_kArbitraryEngineRoot/src/out/ios_debug/gen/dart-pkg/sky_engine/lib/').createSync(recursive: true); fs.directory('$_kArbitraryEngineRoot/src/out/host_debug').createSync(recursive: true); fs.file(_kDotPackages).writeAsStringSync('sky_engine:file://$_kArbitraryEngineRoot/src/out/ios_debug/gen/dart-pkg/sky_engine/lib/'); + await runner.run(['dummy', '--local-engine=ios_debug']); // Verify that this also works if the sky_engine path is a symlink to the engine root. fs.link('/symlink').createSync(_kArbitraryEngineRoot); fs.file(_kDotPackages).writeAsStringSync('sky_engine:file:///symlink/src/out/ios_debug/gen/dart-pkg/sky_engine/lib/'); + await runner.run(['dummy', '--local-engine=ios_debug']); }, overrides: { FileSystem: () => fs, @@ -129,8 +131,10 @@ void main() { }, initializeFlutterRoot: false); testUsingContext('works if --local-engine is specified and --local-engine-src-path is specified', () async { + fs.file(_kDotPackages).writeAsStringSync('\n'); fs.directory('$_kArbitraryEngineRoot/src/out/ios_debug').createSync(recursive: true); fs.directory('$_kArbitraryEngineRoot/src/out/host_debug').createSync(recursive: true); + await runner.run(['dummy', '--local-engine-src-path=$_kArbitraryEngineRoot/src', '--local-engine=ios_debug']); }, overrides: { FileSystem: () => fs, @@ -139,8 +143,10 @@ void main() { }, initializeFlutterRoot: false); testUsingContext('works if --local-engine is specified and --local-engine-src-path is determined by flutter root', () async { + fs.file(_kDotPackages).writeAsStringSync('\n'); fs.directory('$_kEngineRoot/src/out/ios_debug').createSync(recursive: true); fs.directory('$_kEngineRoot/src/out/host_debug').createSync(recursive: true); + await runner.run(['dummy', '--local-engine=ios_debug']); }, overrides: { FileSystem: () => fs,