diff --git a/packages/flutter_tools/bin/fuchsia_asset_builder.dart b/packages/flutter_tools/bin/fuchsia_asset_builder.dart index 05f30dd910..803b6ef45b 100644 --- a/packages/flutter_tools/bin/fuchsia_asset_builder.dart +++ b/packages/flutter_tools/bin/fuchsia_asset_builder.dart @@ -14,6 +14,7 @@ import 'package:flutter_tools/src/bundle.dart'; import 'package:flutter_tools/src/bundle_builder.dart'; import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/context_runner.dart'; +import 'package:flutter_tools/src/dart/package_map.dart'; import 'package:flutter_tools/src/globals.dart' as globals; import 'package:flutter_tools/src/reporting/reporting.dart'; @@ -44,7 +45,7 @@ Future writeAssetFile(libfs.File outputFile, AssetBundleEntry asset) async Future run(List args) async { final ArgParser parser = ArgParser() - ..addOption(_kOptionPackages, help: 'The .packages file') + ..addOption(_kOptionPackages, help: 'The .dart_tool/package_config file') ..addOption(_kOptionAsset, help: 'The directory where to put temporary files') ..addOption(_kOptionManifest, help: 'The manifest file') @@ -63,7 +64,8 @@ Future run(List args) async { final AssetBundle? assets = await buildAssets( manifestPath: argResults[_kOptionManifest] as String? ?? defaultManifestPath, assetDirPath: assetDir, - packagesPath: argResults[_kOptionPackages] as String?, + packageConfigPath: argResults[_kOptionPackages] as String? ?? + findPackageConfigFileOrDefault(globals.fs.currentDirectory).path, targetPlatform: TargetPlatform.fuchsia_arm64 // This is not arch specific. ); diff --git a/packages/flutter_tools/lib/src/asset.dart b/packages/flutter_tools/lib/src/asset.dart index a6cbfff212..97fced1cb0 100644 --- a/packages/flutter_tools/lib/src/asset.dart +++ b/packages/flutter_tools/lib/src/asset.dart @@ -125,7 +125,7 @@ abstract class AssetBundle { /// Returns 0 for success; non-zero for failure. Future build({ String manifestPath = defaultManifestPath, - required String packagesPath, + required String packageConfigPath, bool deferredComponentsEnabled = false, TargetPlatform? targetPlatform, String? flavor, @@ -246,7 +246,7 @@ class ManifestAssetBundle implements AssetBundle { Future build({ String manifestPath = defaultManifestPath, FlutterProject? flutterProject, - required String packagesPath, + required String packageConfigPath, bool deferredComponentsEnabled = false, TargetPlatform? targetPlatform, String? flavor, @@ -293,7 +293,7 @@ class ManifestAssetBundle implements AssetBundle { } final String assetBasePath = _fileSystem.path.dirname(_fileSystem.path.absolute(manifestPath)); - final File packageConfigFile = _fileSystem.file(packagesPath); + final File packageConfigFile = _fileSystem.file(packageConfigPath); inputFiles.add(packageConfigFile); final PackageConfig packageConfig = await loadPackageConfigWithLogging( packageConfigFile, diff --git a/packages/flutter_tools/lib/src/build_system/build_system.dart b/packages/flutter_tools/lib/src/build_system/build_system.dart index f017e4dcd2..0fd777ab22 100644 --- a/packages/flutter_tools/lib/src/build_system/build_system.dart +++ b/packages/flutter_tools/lib/src/build_system/build_system.dart @@ -334,6 +334,7 @@ class Environment { /// [engineVersion] should be set to null for local engine builds. factory Environment({ required Directory projectDir, + required String packageConfigPath, required Directory outputDir, required Directory cacheDir, required Directory flutterRootDir, @@ -374,6 +375,7 @@ class Environment { return Environment._( outputDir: outputDir, projectDir: projectDir, + packageConfigPath: packageConfigPath, buildDir: buildDirectory, rootBuildDir: rootBuildDir, cacheDir: cacheDir, @@ -398,6 +400,7 @@ class Environment { @visibleForTesting factory Environment.test(Directory testDirectory, { Directory? projectDir, + String? packageConfigPath, Directory? outputDir, Directory? cacheDir, Directory? flutterRootDir, @@ -416,6 +419,7 @@ class Environment { }) { return Environment( projectDir: projectDir ?? testDirectory, + packageConfigPath: packageConfigPath ?? '.dart_tool/package_config.json', outputDir: outputDir ?? testDirectory, cacheDir: cacheDir ?? testDirectory, flutterRootDir: flutterRootDir ?? testDirectory, @@ -437,6 +441,7 @@ class Environment { Environment._({ required this.outputDir, required this.projectDir, + required this.packageConfigPath, required this.buildDir, required this.rootBuildDir, required this.cacheDir, @@ -457,6 +462,11 @@ class Environment { /// The [Source] value which is substituted with the path to [projectDir]. static const String kProjectDirectory = '{PROJECT_DIR}'; + /// The [Source] value which is substituted with the path to the directory + /// that contains `.dart_tool/package_config.json1`. + /// That is the grand-parent of [BuildInfo.packageConfigPath]. + static const String kWorkspaceDirectory = '{WORKSPACE_DIR}'; + /// The [Source] value which is substituted with the path to [buildDir]. static const String kBuildDirectory = '{BUILD_DIR}'; @@ -475,10 +485,16 @@ class Environment { /// can be located. final Directory projectDir; + /// The path to the package configuration file to use for compilation. + /// + /// This is used by package:package_config to locate the actual package_config.json + /// file. If not provided, defaults to `.dart_tool/package_config.json`. + final String packageConfigPath; + /// The `BUILD_DIR` environment variable. /// /// The root of the output directory where build step intermediates and - /// outputs are written. Current usages of assemble configure ths to be + /// outputs are written. Current usages of assemble configure this to be /// a unique directory under `.dart_tool/flutter_build`, though it can /// be placed anywhere. The uniqueness is only enforced by callers, and /// is currently done by hashing the build configuration. diff --git a/packages/flutter_tools/lib/src/build_system/source.dart b/packages/flutter_tools/lib/src/build_system/source.dart index 435c049325..c1617a6178 100644 --- a/packages/flutter_tools/lib/src/build_system/source.dart +++ b/packages/flutter_tools/lib/src/build_system/source.dart @@ -99,6 +99,12 @@ class SourceVisitor implements ResolvedFiles { // flutter root will not contain a symbolic link. Environment.kFlutterRootDirectory => environment.flutterRootDir.absolute.path, Environment.kProjectDirectory => environment.projectDir.resolveSymbolicLinksSync(), + Environment.kWorkspaceDirectory => + environment.fileSystem.path.dirname( + environment.fileSystem.path.dirname( + environment.packageConfigPath, + ), + ), Environment.kBuildDirectory => environment.buildDir.resolveSymbolicLinksSync(), Environment.kCacheDirectory => environment.cacheDir.resolveSymbolicLinksSync(), Environment.kOutputDirectory => environment.outputDir.resolveSymbolicLinksSync(), diff --git a/packages/flutter_tools/lib/src/build_system/targets/assets.dart b/packages/flutter_tools/lib/src/build_system/targets/assets.dart index efd8b3339f..9a4496a451 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/assets.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/assets.dart @@ -11,6 +11,7 @@ import '../../base/file_system.dart'; import '../../base/logger.dart'; import '../../build_info.dart'; import '../../convert.dart'; +import '../../dart/package_map.dart'; import '../../devfs.dart'; import '../../flutter_manifest.dart'; import '../build_system.dart'; @@ -60,7 +61,7 @@ Future copyAssets( ).createBundle(); final int resultCode = await assetBundle.build( manifestPath: pubspecFile.path, - packagesPath: environment.projectDir.childFile('.packages').path, + packageConfigPath: findPackageConfigFileOrDefault(environment.projectDir).path, deferredComponentsEnabled: environment.defines[kDeferredComponents] == 'true', targetPlatform: targetPlatform, flavor: flavor, diff --git a/packages/flutter_tools/lib/src/build_system/targets/common.dart b/packages/flutter_tools/lib/src/build_system/targets/common.dart index e7ae8228e8..1dc827db6f 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/common.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/common.dart @@ -181,9 +181,7 @@ class KernelSnapshotProgram extends Target { } final BuildMode buildMode = BuildMode.fromCliName(buildModeEnvironment); final String targetFile = environment.defines[kTargetFile] ?? environment.fileSystem.path.join('lib', 'main.dart'); - final File packagesFile = environment.projectDir - .childDirectory('.dart_tool') - .childFile('package_config.json'); + final File packagesFile = findPackageConfigFileOrDefault(environment.projectDir); final String targetFileAbsolute = environment.fileSystem.file(targetFile).absolute.path; // everything besides 'false' is considered to be enabled. final bool trackWidgetCreation = environment.defines[kTrackWidgetCreation] != 'false'; @@ -340,9 +338,7 @@ class KernelSnapshotNativeAssets extends Target { throw MissingDefineException(kTargetPlatform, 'kernel_snapshot'); } final BuildMode buildMode = BuildMode.fromCliName(buildModeEnvironment); - final File packagesFile = environment.projectDir - .childDirectory('.dart_tool') - .childFile('package_config.json'); + final File packageConfigFile = findPackageConfigFileOrDefault(environment.projectDir); final TargetPlatform targetPlatform = getTargetPlatformForName(targetPlatformEnvironment); @@ -355,7 +351,7 @@ class KernelSnapshotNativeAssets extends Target { environment.logger.printTrace('Embedding native assets mapping $nativeAssets in kernel.'); final PackageConfig packageConfig = await loadPackageConfigWithLogging( - packagesFile, + packageConfigFile, logger: environment.logger, ); @@ -371,7 +367,7 @@ class KernelSnapshotNativeAssets extends Target { buildMode: buildMode, trackWidgetCreation: false, outputFilePath: dillPath, - packagesPath: packagesFile.path, + packagesPath: packageConfigFile.path, frontendServerStarterPath: frontendServerStarterPath, packageConfig: packageConfig, buildDir: environment.buildDir, diff --git a/packages/flutter_tools/lib/src/build_system/targets/dart_plugin_registrant.dart b/packages/flutter_tools/lib/src/build_system/targets/dart_plugin_registrant.dart index 3cc4dc2186..f469704788 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/dart_plugin_registrant.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/dart_plugin_registrant.dart @@ -31,8 +31,9 @@ class DartPluginRegistrantTarget extends Target { assert(environment.generateDartPluginRegistry); final FlutterProject project = _project ?? FlutterProject.fromDirectory(environment.projectDir); + final File packageConfigFile = findPackageConfigFileOrDefault(environment.projectDir); final PackageConfig packageConfig = await loadPackageConfigWithLogging( - project.packageConfigFile, + packageConfigFile, logger: environment.logger, ); final String targetFilePath = environment.defines[kTargetFile] ?? @@ -73,7 +74,7 @@ class DartPluginRegistrantTarget extends Target { @override List get inputs => [ - const Source.pattern('{PROJECT_DIR}/.dart_tool/package_config_subset'), + const Source.pattern('{WORKSPACE_DIR}/.dart_tool/package_config_subset'), ]; @override diff --git a/packages/flutter_tools/lib/src/build_system/targets/native_assets.dart b/packages/flutter_tools/lib/src/build_system/targets/native_assets.dart index 4775a262d6..fae9b56cf5 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/native_assets.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/native_assets.dart @@ -64,17 +64,15 @@ class NativeAssets extends Target { } final TargetPlatform targetPlatform = getTargetPlatformForName(targetPlatformEnvironment); final Uri projectUri = environment.projectDir.uri; - final File packagesFile = fileSystem - .directory(projectUri) - .childDirectory('.dart_tool') - .childFile('package_config.json'); + final PackageConfig packageConfig = await loadPackageConfigWithLogging( - packagesFile, + fileSystem.file(environment.packageConfigPath), logger: environment.logger, ); final NativeAssetsBuildRunner buildRunner = _buildRunner ?? NativeAssetsBuildRunnerImpl( projectUri, + environment.packageConfigPath, packageConfig, fileSystem, environment.logger, @@ -380,7 +378,7 @@ class NativeAssets extends Target { List get inputs => const [ Source.pattern('{FLUTTER_ROOT}/packages/flutter_tools/lib/src/build_system/targets/native_assets.dart'), // If different packages are resolved, different native assets might need to be built. - Source.pattern('{PROJECT_DIR}/.dart_tool/package_config_subset'), + Source.pattern('{WORKSPACE_DIR}/.dart_tool/package_config_subset'), // TODO(mosuem): Should consume resources.json. https://github.com/flutter/flutter/issues/146263 ]; 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 01cdca1300..aaf3a26ae2 100644 --- a/packages/flutter_tools/lib/src/build_system/targets/web.dart +++ b/packages/flutter_tools/lib/src/build_system/targets/web.dart @@ -54,10 +54,10 @@ class WebEntrypointTarget extends Target { Future build(Environment environment) async { final String? targetFile = environment.defines[kTargetFile]; final Uri importUri = environment.fileSystem.file(targetFile).absolute.uri; - // TODO(zanderso): support configuration of this file. - const String packageFile = '.packages'; + final File packageConfigFile = findPackageConfigFileOrDefault(environment.projectDir); + final PackageConfig packageConfig = await loadPackageConfigWithLogging( - environment.fileSystem.file(packageFile), + packageConfigFile, logger: environment.logger, ); final FlutterProject flutterProject = FlutterProject.current(); @@ -129,7 +129,7 @@ abstract class Dart2WebTarget extends Target { compilerSnapshot, const Source.artifact(Artifact.engineDartBinary), const Source.pattern('{BUILD_DIR}/main.dart'), - const Source.pattern('{PROJECT_DIR}/.dart_tool/package_config_subset'), + const Source.pattern('{WORKSPACE_DIR}/.dart_tool/package_config_subset'), ]; @override @@ -188,7 +188,7 @@ class Dart2JSTarget extends Dart2WebTarget { ...compilerConfig.toSharedCommandOptions(buildMode), '-o', environment.buildDir.childFile('app.dill').path, - '--packages=.dart_tool/package_config.json', + '--packages=${findPackageConfigFileOrDefault(environment.projectDir).path}', '--cfe-only', environment.buildDir.childFile('main.dart').path, // dartfile ]; @@ -302,7 +302,7 @@ class Dart2WasmTarget extends Dart2WebTarget { artifacts.getArtifactPath(Artifact.engineDartBinary, platform: TargetPlatform.web_javascript), 'compile', 'wasm', - '--packages=.dart_tool/package_config.json', + '--packages=${findPackageConfigFileOrDefault(environment.projectDir).path}', '--extra-compiler-option=--platform=$platformFilePath', '--extra-compiler-option=--delete-tostring-package-uri=dart:ui', '--extra-compiler-option=--delete-tostring-package-uri=package:flutter', diff --git a/packages/flutter_tools/lib/src/bundle_builder.dart b/packages/flutter_tools/lib/src/bundle_builder.dart index 9e6b0605c7..83ebbcd732 100644 --- a/packages/flutter_tools/lib/src/bundle_builder.dart +++ b/packages/flutter_tools/lib/src/bundle_builder.dart @@ -55,6 +55,7 @@ class BundleBuilder { // If the precompiled flag was not passed, force us into debug mode. final Environment environment = Environment( projectDir: project.directory, + packageConfigPath: buildInfo.packageConfigPath, outputDir: globals.fs.directory(assetDirPath), buildDir: project.dartTool.childDirectory('flutter_build'), cacheDir: globals.cache.getRoot(), @@ -115,18 +116,17 @@ class BundleBuilder { Future buildAssets({ required String manifestPath, String? assetDirPath, - String? packagesPath, + required String packageConfigPath, TargetPlatform? targetPlatform, String? flavor, }) async { assetDirPath ??= getAssetBuildDirectory(); - packagesPath ??= globals.fs.path.absolute('.packages'); // Build the asset bundle. final AssetBundle assetBundle = AssetBundleFactory.instance.createBundle(); final int result = await assetBundle.build( manifestPath: manifestPath, - packagesPath: packagesPath, + packageConfigPath: packageConfigPath, targetPlatform: targetPlatform, flavor: flavor, ); diff --git a/packages/flutter_tools/lib/src/commands/assemble.dart b/packages/flutter_tools/lib/src/commands/assemble.dart index 56278362ab..42252acbee 100644 --- a/packages/flutter_tools/lib/src/commands/assemble.dart +++ b/packages/flutter_tools/lib/src/commands/assemble.dart @@ -236,6 +236,7 @@ class AssembleCommand extends FlutterCommand { .childDirectory('.dart_tool') .childDirectory('flutter_build'), projectDir: _flutterProject.directory, + packageConfigPath: packageConfigPath(), defines: _parseDefines(stringsArg('define')), inputs: _parseDefines(stringsArg('input')), cacheDir: globals.cache.getRoot(), diff --git a/packages/flutter_tools/lib/src/commands/build_ios_framework.dart b/packages/flutter_tools/lib/src/commands/build_ios_framework.dart index e0452f0012..fd6589397b 100644 --- a/packages/flutter_tools/lib/src/commands/build_ios_framework.dart +++ b/packages/flutter_tools/lib/src/commands/build_ios_framework.dart @@ -435,6 +435,7 @@ end frameworks.add(outputBuildDirectory.childDirectory(appFrameworkName)); final Environment environment = Environment( projectDir: globals.fs.currentDirectory, + packageConfigPath: packageConfigPath(), outputDir: outputBuildDirectory, buildDir: project.dartTool.childDirectory('flutter_build'), cacheDir: globals.cache.getRoot(), diff --git a/packages/flutter_tools/lib/src/commands/build_macos_framework.dart b/packages/flutter_tools/lib/src/commands/build_macos_framework.dart index 32ccec5dfc..deebf44e4b 100644 --- a/packages/flutter_tools/lib/src/commands/build_macos_framework.dart +++ b/packages/flutter_tools/lib/src/commands/build_macos_framework.dart @@ -217,6 +217,7 @@ end try { final Environment environment = Environment( projectDir: globals.fs.currentDirectory, + packageConfigPath: packageConfigPath(), outputDir: macosBuildOutput, buildDir: project.dartTool.childDirectory('flutter_build'), cacheDir: globals.cache.getRoot(), diff --git a/packages/flutter_tools/lib/src/commands/build_preview.dart b/packages/flutter_tools/lib/src/commands/build_preview.dart index 3c5ab3325a..93894b5e81 100644 --- a/packages/flutter_tools/lib/src/commands/build_preview.dart +++ b/packages/flutter_tools/lib/src/commands/build_preview.dart @@ -60,13 +60,15 @@ class BuildPreviewCommand extends BuildSubCommand { try { final FlutterProject flutterProject = await _createProject(targetDir); + final File packageConfigFile = findPackageConfigFileOrDefault(flutterProject.directory); + final BuildInfo buildInfo = BuildInfo( BuildMode.debug, null, // no flavor // users may add icons later - packageConfigPath: flutterProject.packageConfigFile.path, + packageConfigPath: packageConfigFile.path, packageConfig: await loadPackageConfigWithLogging( - flutterProject.packageConfigFile, + packageConfigFile, logger: logger, ), treeShakeIcons: false, diff --git a/packages/flutter_tools/lib/src/commands/clean.dart b/packages/flutter_tools/lib/src/commands/clean.dart index 3cd5d74f3a..b23ea262e1 100644 --- a/packages/flutter_tools/lib/src/commands/clean.dart +++ b/packages/flutter_tools/lib/src/commands/clean.dart @@ -54,7 +54,7 @@ class CleanCommand extends FlutterCommand { deleteFile(buildDir); deleteFile(flutterProject.dartTool); - deleteFile(flutterProject.packagesFile); + deleteFile(flutterProject.directory.childFile('.packages')); deleteFile(flutterProject.android.ephemeralDirectory); diff --git a/packages/flutter_tools/lib/src/commands/create_base.dart b/packages/flutter_tools/lib/src/commands/create_base.dart index dc9e60d529..70413d5112 100644 --- a/packages/flutter_tools/lib/src/commands/create_base.dart +++ b/packages/flutter_tools/lib/src/commands/create_base.dart @@ -571,6 +571,7 @@ abstract class CreateBase extends FlutterCommand { usage: globals.flutterUsage, analytics: globals.analytics, projectDir: project.directory, + packageConfigPath: packageConfigPath(), generateDartPluginRegistry: true, ); diff --git a/packages/flutter_tools/lib/src/commands/drive.dart b/packages/flutter_tools/lib/src/commands/drive.dart index 27b73c839d..4921ccc428 100644 --- a/packages/flutter_tools/lib/src/commands/drive.dart +++ b/packages/flutter_tools/lib/src/commands/drive.dart @@ -261,8 +261,10 @@ class DriveCommand extends RunCommandBase { dartSdkPath: globals.artifacts!.getArtifactPath(Artifact.engineDartBinary), devtoolsLauncher: DevtoolsLauncher.instance!, ); + final File packageConfigFile = findPackageConfigFileOrDefault(_fileSystem.currentDirectory); + final PackageConfig packageConfig = await loadPackageConfigWithLogging( - _fileSystem.file('.packages'), + packageConfigFile, logger: _logger, throwOnError: false, ); diff --git a/packages/flutter_tools/lib/src/commands/packages.dart b/packages/flutter_tools/lib/src/commands/packages.dart index c6c3eab196..9ef6a47808 100644 --- a/packages/flutter_tools/lib/src/commands/packages.dart +++ b/packages/flutter_tools/lib/src/commands/packages.dart @@ -13,6 +13,7 @@ import '../build_system/build_system.dart'; import '../build_system/targets/localizations.dart'; import '../cache.dart'; import '../dart/generate_synthetic_packages.dart'; +import '../dart/package_map.dart'; import '../dart/pub.dart'; import '../flutter_plugins.dart'; import '../globals.dart' as globals; @@ -301,6 +302,7 @@ class PackagesGetCommand extends FlutterCommand { usage: globals.flutterUsage, analytics: analytics, projectDir: rootProject.directory, + packageConfigPath: packageConfigPath(), generateDartPluginRegistry: true, ); @@ -323,6 +325,7 @@ class PackagesGetCommand extends FlutterCommand { usage: globals.flutterUsage, analytics: analytics, projectDir: rootProject.directory, + packageConfigPath: packageConfigPath(), generateDartPluginRegistry: true, ); final BuildResult result = await globals.buildSystem.build( @@ -413,7 +416,7 @@ class PackagesGetCommand extends FlutterCommand { int numberPlugins; // Do not send plugin analytics if pub has not run before. final bool hasPlugins = rootProject.flutterPluginsDependenciesFile.existsSync() - && rootProject.packageConfigFile.existsSync(); + && findPackageConfigFile(rootProject.directory) != null; if (hasPlugins) { // Do not fail pub get if package config files are invalid before pub has // had a chance to run. @@ -442,7 +445,7 @@ class PackagesGetCommand extends FlutterCommand { final int numberPlugins; // Do not send plugin analytics if pub has not run before. final bool hasPlugins = rootProject.flutterPluginsDependenciesFile.existsSync() - && rootProject.packageConfigFile.existsSync(); + && findPackageConfigFile(rootProject.directory) != null; if (hasPlugins) { // Do not fail pub get if package config files are invalid before pub has // had a chance to run. diff --git a/packages/flutter_tools/lib/src/commands/test.dart b/packages/flutter_tools/lib/src/commands/test.dart index e5510193f7..95c0b857b1 100644 --- a/packages/flutter_tools/lib/src/commands/test.dart +++ b/packages/flutter_tools/lib/src/commands/test.dart @@ -693,8 +693,10 @@ class TestCommand extends FlutterCommand with DeviceBasedDevelopmentArtifacts { required BuildMode buildMode, }) async { final AssetBundle assetBundle = AssetBundleFactory.instance.createBundle(); + // TODO(sigurdm): parametrize packageConfigPath to support testing + // workspaces. final int build = await assetBundle.build( - packagesPath: '.packages', + packageConfigPath: '.dart_tool/package_config.json', flavor: flavor, ); if (build != 0) { diff --git a/packages/flutter_tools/lib/src/dart/package_map.dart b/packages/flutter_tools/lib/src/dart/package_map.dart index 404583ca73..271358a108 100644 --- a/packages/flutter_tools/lib/src/dart/package_map.dart +++ b/packages/flutter_tools/lib/src/dart/package_map.dart @@ -16,6 +16,46 @@ Future currentPackageConfig() async { return loadPackageConfigUri(Isolate.packageConfigSync!); } +/// Locates the `.dart_tool/package_config.json` relevant to [dir]. +/// +/// Searches [dir] and all parent directories. +/// +/// Returns `null` if no package_config.json was found. +// TODO(sigurdm): Only call this once per run - and read in from BuildInfo. +File? findPackageConfigFile(Directory dir) { + final FileSystem fileSystem = dir.fileSystem; + + Directory candidateDir = fileSystem.directory(dir.path).absolute; + while (true) { + final File candidatePackageConfigFile = candidateDir + .childDirectory('.dart_tool') + .childFile('package_config.json'); + if (candidatePackageConfigFile.existsSync()) { + return candidatePackageConfigFile; + } + // TODO(sigurdm): we should not need to check this file, it is obsolete, + // https://github.com/flutter/flutter/issues/150908. + final File candidatePackagesFile = candidateDir.childFile('.packages'); + if (candidatePackagesFile.existsSync()) { + return candidatePackagesFile; + } + final Directory parentDir = candidateDir.parent; + if (fileSystem.identicalSync(parentDir.path, candidateDir.path)) { + return null; + } + candidateDir = parentDir; + } +} + +/// Locates the `.dart_tool/package_config.json` relevant to [dir]. +/// +/// Like [findPackageConfigFile] but returns +/// `$dir/.dart_tool/package_config.json` if no package config could be found. +File findPackageConfigFileOrDefault(Directory dir) { + return findPackageConfigFile(dir) ?? + dir.childDirectory('.dart_tool').childFile('package_config.json'); +} + /// Load the package configuration from [file] or throws a [ToolExit] /// if the operation would fail. /// diff --git a/packages/flutter_tools/lib/src/dart/pub.dart b/packages/flutter_tools/lib/src/dart/pub.dart index b0f3dfe7b1..c619a77470 100644 --- a/packages/flutter_tools/lib/src/dart/pub.dart +++ b/packages/flutter_tools/lib/src/dart/pub.dart @@ -258,50 +258,87 @@ class _DefaultPub implements Pub { PubOutputMode outputMode = PubOutputMode.all, }) async { final String directory = project.directory.path; - final File packageConfigFile = project.packageConfigFile; - final File lastVersion = _fileSystem.file( - _fileSystem.path.join(directory, '.dart_tool', 'version')); - final File currentVersion = _fileSystem.file( - _fileSystem.path.join(Cache.flutterRoot!, 'version')); - final File pubspecYaml = project.pubspecFile; - final File pubLockFile = _fileSystem.file( - _fileSystem.path.join(directory, 'pubspec.lock') - ); - if (shouldSkipThirdPartyGenerator && project.packageConfigFile.existsSync()) { - Map packageConfigMap; - try { - packageConfigMap = jsonDecode( - project.packageConfigFile.readAsStringSync(), - ) as Map; - } on FormatException { - packageConfigMap = {}; - } - - final bool isPackageConfigGeneratedByThirdParty = - packageConfigMap.containsKey('generator') && - packageConfigMap['generator'] != 'pub'; - - if (isPackageConfigGeneratedByThirdParty) { - _logger.printTrace('Skipping pub get: generated by third-party.'); - return; + // Here we use pub's private helper file to locate the package_config. + // In pub workspaces pub will generate a `.dart_tool/pub/workspace_ref.json` + // inside each workspace-package that refers to the workspace root where + // .dart_tool/package_config.json is located. + // + // By checking for this file instead of iterating parent directories until + // finding .dart_tool/package_config.json we will not mistakenly find a + // package_config.json from outside the workspace. + // + // TODO(sigurdm): avoid relying on pubs implementation details somehow? + final File workspaceRefFile = project + .dartTool + .childDirectory('pub').childFile('workspace_ref.json'); + final File packageConfigFile; + if (workspaceRefFile.existsSync()) { + switch (jsonDecode(workspaceRefFile.readAsStringSync())) { + case {'workspaceRoot': final String workspaceRoot}: + packageConfigFile = _fileSystem.file( + _fileSystem.path.join( + workspaceRefFile.parent.path, + workspaceRoot, + ), + ); + default: + // The workspace_ref.json file was malformed. Attempt to load the + // regular .dart_tool/package_config.json + // + // Most likely this doesn't exist, and we will get a new pub + // resolution. + // + // Alternatively this is a stray file somehow, and it can be ignored. + packageConfigFile = project + .dartTool.childFile('package_config.json'); } + } else { + packageConfigFile = project + .dartTool.childFile('package_config.json'); } - // If the pubspec.yaml is older than the package config file and the last - // flutter version used is the same as the current version skip pub get. - // This will incorrectly skip pub on the master branch if dependencies - // are being added/removed from the flutter framework packages, but this - // can be worked around by manually running pub. - if (checkUpToDate && - packageConfigFile.existsSync() && - pubLockFile.existsSync() && - pubspecYaml.lastModifiedSync().isBefore(pubLockFile.lastModifiedSync()) && - pubspecYaml.lastModifiedSync().isBefore(packageConfigFile.lastModifiedSync()) && - lastVersion.existsSync() && - lastVersion.readAsStringSync() == currentVersion.readAsStringSync()) { - _logger.printTrace('Skipping pub get: version match.'); - return; + if (packageConfigFile.existsSync()) { + final Directory workspaceRoot = packageConfigFile.parent.parent; + final File lastVersion = workspaceRoot.childDirectory('.dart_tool').childFile('version'); + final File currentVersion = _fileSystem.file( + _fileSystem.path.join(Cache.flutterRoot!, 'version')); + final File pubspecYaml = project.pubspecFile; + final File pubLockFile = workspaceRoot.childFile('pubspec.lock'); + + if (shouldSkipThirdPartyGenerator) { + Map packageConfigMap; + try { + packageConfigMap = jsonDecode(packageConfigFile.readAsStringSync(), + ) as Map; + } on FormatException { + packageConfigMap = {}; + } + + final bool isPackageConfigGeneratedByThirdParty = + packageConfigMap.containsKey('generator') && + packageConfigMap['generator'] != 'pub'; + + if (isPackageConfigGeneratedByThirdParty) { + _logger.printTrace('Skipping pub get: generated by third-party.'); + return; + } + } + + // If the pubspec.yaml is older than the package config file and the last + // flutter version used is the same as the current version skip pub get. + // This will incorrectly skip pub on the master branch if dependencies + // are being added/removed from the flutter framework packages, but this + // can be worked around by manually running pub. + if (checkUpToDate && + pubLockFile.existsSync() && + pubspecYaml.lastModifiedSync().isBefore(pubLockFile.lastModifiedSync()) && + pubspecYaml.lastModifiedSync().isBefore(packageConfigFile.lastModifiedSync()) && + lastVersion.existsSync() && + lastVersion.readAsStringSync() == currentVersion.readAsStringSync()) { + _logger.printTrace('Skipping pub get: version match.'); + return; + } } final String command = upgrade ? 'upgrade' : 'get'; @@ -645,19 +682,24 @@ class _DefaultPub implements Pub { /// This should be called after pub invocations that are expected to update /// the packageConfig. Future _updateVersionAndPackageConfig(FlutterProject project) async { - if (!project.packageConfigFile.existsSync()) { + final File? packageConfig = findPackageConfigFile(project.directory); + if (packageConfig == null) { throwToolExit('${project.directory}: pub did not create .dart_tools/package_config.json file.'); } final File lastVersion = _fileSystem.file( - _fileSystem.path.join(project.directory.path, '.dart_tool', 'version'), + _fileSystem.path.join(packageConfig.parent.path, 'version'), ); final File currentVersion = _fileSystem.file( _fileSystem.path.join(Cache.flutterRoot!, 'version')); lastVersion.writeAsStringSync(currentVersion.readAsStringSync()); - await _updatePackageConfig(project); + await _updatePackageConfig(project, packageConfig); if (project.hasExampleApp && project.example.pubspecFile.existsSync()) { - await _updatePackageConfig(project.example); + final File? examplePackageConfig = findPackageConfigFile(project.example.directory); + if (examplePackageConfig == null) { + throwToolExit('${project.directory}: pub did not create example/.dart_tools/package_config.json file.'); + } + await _updatePackageConfig(project.example, examplePackageConfig); } } @@ -674,8 +716,7 @@ class _DefaultPub implements Pub { /// /// For more information, see: /// * [generateLocalizations], `in lib/src/localizations/gen_l10n.dart` - Future _updatePackageConfig(FlutterProject project) async { - final File packageConfigFile = project.packageConfigFile; + Future _updatePackageConfig(FlutterProject project, File packageConfigFile) async { final PackageConfig packageConfig = await loadPackageConfigWithLogging(packageConfigFile, logger: _logger); packageConfigFile.parent @@ -688,6 +729,10 @@ class _DefaultPub implements Pub { if (!project.manifest.generateSyntheticPackage) { return; } + + if (!_fileSystem.path.equals(packageConfigFile.parent.parent.path, project.directory.path)) { + throwToolExit('`generate: true` is not supported within workspaces.'); + } if (packageConfig.packages.any((Package package) => package.name == 'flutter_gen')) { return; } diff --git a/packages/flutter_tools/lib/src/flutter_plugins.dart b/packages/flutter_tools/lib/src/flutter_plugins.dart index 74daee971c..65c4c56605 100644 --- a/packages/flutter_tools/lib/src/flutter_plugins.dart +++ b/packages/flutter_tools/lib/src/flutter_plugins.dart @@ -82,12 +82,9 @@ Future _pluginFromPackage(String name, Uri packageRoot, Set app Future> findPlugins(FlutterProject project, { bool throwOnError = true}) async { final List plugins = []; final FileSystem fs = project.directory.fileSystem; - final String packagesFile = fs.path.join( - project.directory.path, - '.packages', - ); + final File packageConfigFile = findPackageConfigFileOrDefault(project.directory); final PackageConfig packageConfig = await loadPackageConfigWithLogging( - fs.file(packagesFile), + packageConfigFile, logger: globals.logger, throwOnError: throwOnError, ); diff --git a/packages/flutter_tools/lib/src/isolated/native_assets/native_assets.dart b/packages/flutter_tools/lib/src/isolated/native_assets/native_assets.dart index ac2ea77de2..4b9c4cb212 100644 --- a/packages/flutter_tools/lib/src/isolated/native_assets/native_assets.dart +++ b/packages/flutter_tools/lib/src/isolated/native_assets/native_assets.dart @@ -102,12 +102,14 @@ abstract class NativeAssetsBuildRunner { class NativeAssetsBuildRunnerImpl implements NativeAssetsBuildRunner { NativeAssetsBuildRunnerImpl( this.projectUri, + this.packageConfigPath, this.packageConfig, this.fileSystem, this.logger, ); final Uri projectUri; + final String packageConfigPath; final PackageConfig packageConfig; final FileSystem fileSystem; final Logger logger; @@ -418,11 +420,13 @@ class HotRunnerNativeAssetsBuilderImpl implements HotRunnerNativeAssetsBuilder { required Uri projectUri, required FileSystem fileSystem, required List flutterDevices, + required String packageConfigPath, required PackageConfig packageConfig, required Logger logger, }) async { final NativeAssetsBuildRunner buildRunner = NativeAssetsBuildRunnerImpl( projectUri, + packageConfigPath, packageConfig, fileSystem, globals.logger, diff --git a/packages/flutter_tools/lib/src/isolated/native_assets/test/native_assets.dart b/packages/flutter_tools/lib/src/isolated/native_assets/test/native_assets.dart index e0553dd447..82bba5b9c7 100644 --- a/packages/flutter_tools/lib/src/isolated/native_assets/test/native_assets.dart +++ b/packages/flutter_tools/lib/src/isolated/native_assets/test/native_assets.dart @@ -32,6 +32,7 @@ Future testCompilerBuildNativeAssets(BuildInfo buildInfo) async { final Uri projectUri = FlutterProject.current().directory.uri; final NativeAssetsBuildRunner buildRunner = NativeAssetsBuildRunnerImpl( projectUri, + buildInfo.packageConfigPath, buildInfo.packageConfig, globals.fs, globals.logger, diff --git a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart index cef1026f36..f70ca02206 100644 --- a/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart +++ b/packages/flutter_tools/lib/src/isolated/resident_web_runner.dart @@ -560,7 +560,7 @@ Please provide a valid TCP port (an integer between 0 and 65535, inclusive). if (rebuildBundle) { _logger.printTrace('Updating assets'); final int result = await assetBundle.build( - packagesPath: debuggingOptions.buildInfo.packageConfigPath, + packageConfigPath: debuggingOptions.buildInfo.packageConfigPath, targetPlatform: TargetPlatform.web_javascript, ); if (result != 0) { diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart index 96f7d189f3..09cebef724 100644 --- a/packages/flutter_tools/lib/src/project.dart +++ b/packages/flutter_tools/lib/src/project.dart @@ -214,15 +214,6 @@ class FlutterProject { /// The `pubspec.yaml` file of this project. File get pubspecFile => directory.childFile('pubspec.yaml'); - /// The `.packages` file of this project. - File get packagesFile => directory.childFile('.packages'); - - /// The `package_config.json` file of the project. - /// - /// This is the replacement for .packages which contains language - /// version information. - File get packageConfigFile => directory.childDirectory('.dart_tool').childFile('package_config.json'); - /// The `.metadata` file of this project. File get metadataFile => directory.childFile('.metadata'); diff --git a/packages/flutter_tools/lib/src/resident_runner.dart b/packages/flutter_tools/lib/src/resident_runner.dart index daabad8b91..43512a2bb3 100644 --- a/packages/flutter_tools/lib/src/resident_runner.dart +++ b/packages/flutter_tools/lib/src/resident_runner.dart @@ -1202,6 +1202,7 @@ abstract class ResidentRunner extends ResidentHandlers { usage: globals.flutterUsage, analytics: globals.analytics, projectDir: globals.fs.currentDirectory, + packageConfigPath: debuggingOptions.buildInfo.packageConfigPath, generateDartPluginRegistry: generateDartPluginRegistry, defines: { // Needed for Dart plugin registry generation. diff --git a/packages/flutter_tools/lib/src/run_hot.dart b/packages/flutter_tools/lib/src/run_hot.dart index c73e578df0..8096993c8a 100644 --- a/packages/flutter_tools/lib/src/run_hot.dart +++ b/packages/flutter_tools/lib/src/run_hot.dart @@ -18,7 +18,6 @@ import 'base/utils.dart'; import 'build_info.dart'; import 'compile.dart'; import 'convert.dart'; -import 'dart/package_map.dart'; import 'devfs.dart'; import 'device.dart'; import 'globals.dart' as globals; @@ -375,6 +374,7 @@ class HotRunner extends ResidentRunner { fileSystem: fileSystem, flutterDevices: flutterDevices, logger: logger, + packageConfigPath: debuggingOptions.buildInfo.packageConfigPath, packageConfig: debuggingOptions.buildInfo.packageConfig, ); } @@ -489,7 +489,7 @@ class HotRunner extends ResidentRunner { if (rebuildBundle) { globals.printTrace('Updating assets'); final int result = await assetBundle.build( - packagesPath: '.packages', + packageConfigPath: debuggingOptions.buildInfo.packageConfigPath, flavor: debuggingOptions.buildInfo.flavor, ); if (result != 0) { @@ -1617,24 +1617,13 @@ class ProjectFileInvalidator { } } } - // We need to check the .packages file too since it is not used in compilation. + // We need to check the .dart_tool/package_config.json file too since it is + // not used in compilation. final File packageFile = _fileSystem.file(packagesPath); final Uri packageUri = packageFile.uri; final DateTime updatedAt = packageFile.statSync().modified; if (updatedAt.isAfter(lastCompiled)) { invalidatedFiles.add(packageUri); - packageConfig = await _createPackageConfig(packagesPath); - // The frontend_server might be monitoring the package_config.json file, - // Pub should always produce both files. - // TODO(zanderso): remove after https://github.com/flutter/flutter/issues/55249 - if (_fileSystem.path.basename(packagesPath) == '.packages') { - final File packageConfigFile = _fileSystem.file(packagesPath) - .parent.childDirectory('.dart_tool') - .childFile('package_config.json'); - if (packageConfigFile.existsSync()) { - invalidatedFiles.add(packageConfigFile.uri); - } - } } _logger.printTrace( @@ -1652,13 +1641,6 @@ class ProjectFileInvalidator { return !(_platform.isWindows && uri.path.contains(_pubCachePathWindows)) && !uri.path.contains(_pubCachePathLinuxAndMac); } - - Future _createPackageConfig(String packagesPath) { - return loadPackageConfigWithLogging( - _fileSystem.file(packagesPath), - logger: _logger, - ); - } } /// Additional serialization logic for a hot reload response. @@ -1719,6 +1701,7 @@ abstract class HotRunnerNativeAssetsBuilder { required Uri projectUri, required FileSystem fileSystem, required List flutterDevices, + required String packageConfigPath, required PackageConfig packageConfig, required 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 9be18ca99e..4cebe8e7bc 100644 --- a/packages/flutter_tools/lib/src/runner/flutter_command.dart +++ b/packages/flutter_tools/lib/src/runner/flutter_command.dart @@ -1083,15 +1083,19 @@ abstract class FlutterCommand extends Command { BuildMode defaultBuildMode = BuildMode.debug; BuildMode getBuildMode() { - // No debug when _excludeDebug is true. - // If debug is not excluded, then take the command line flag. - final bool debugResult = !_excludeDebug && boolArg('debug'); - final bool jitReleaseResult = !_excludeRelease && boolArg('jit-release'); - final bool releaseResult = !_excludeRelease && boolArg('release'); + // No debug when _excludeDebug is true. If debug is not excluded, then take + // the command line flag (if such exists for this command). + bool argIfDefined(String flagName, bool ifNotDefined) { + return argParser.options.containsKey(flagName) ? boolArg(flagName) : ifNotDefined; + } + final bool debugResult = !_excludeDebug && argIfDefined('debug', false); + final bool jitReleaseResult = !_excludeRelease && argIfDefined('jit-release', false); + final bool releaseResult = !_excludeRelease && argIfDefined('release', false); + final bool profileResult = argIfDefined('profile', false); final List modeFlags = [ debugResult, + profileResult, jitReleaseResult, - boolArg('profile'), releaseResult, ]; if (modeFlags.where((bool flag) => flag).length > 1) { @@ -1101,7 +1105,7 @@ abstract class FlutterCommand extends Command { if (debugResult) { return BuildMode.debug; } - if (boolArg('profile')) { + if (profileResult) { return BuildMode.profile; } if (releaseResult) { @@ -1184,6 +1188,19 @@ abstract class FlutterCommand extends Command { /// if `pubspec.yaml` or `example/pubspec.yaml` is invalid. FlutterProject get project => FlutterProject.current(); + /// The path to the package config for the current project. + /// + /// If an explicit argument is given, that is returned. Otherwise the file + /// system is searched for the package config. For projects in pub workspaces + /// the package config might be located in a parent directory. + /// + /// If none is found `.dart_tool/package_config.json` is returned. + String packageConfigPath() { + final String? packagesPath = this.packagesPath; + return packagesPath ?? + findPackageConfigFileOrDefault(project.directory).path; + } + /// Compute the [BuildInfo] for the current flutter command. /// /// Commands that build multiple build modes can pass in a [forcedBuildMode] @@ -1203,7 +1220,8 @@ abstract class FlutterCommand extends Command { ? stringArg('build-number') : null; - final File packageConfigFile = globals.fs.file(packagesPath ?? project.packageConfigFile.path); + final File packageConfigFile = globals.fs.file(packageConfigPath()); + final PackageConfig packageConfig = await loadPackageConfigWithLogging( packageConfigFile, logger: globals.logger, @@ -1750,21 +1768,22 @@ Run 'flutter -h' (or 'flutter -h') for available flutter commands and usage: globals.flutterUsage, analytics: analytics, projectDir: project.directory, + packageConfigPath: packageConfigPath(), generateDartPluginRegistry: true, ); - await generateLocalizationsSyntheticPackage( - environment: environment, - buildSystem: globals.buildSystem, - buildTargets: globals.buildTargets, - ); - await pub.get( context: PubContext.getVerifyContext(name), project: project, checkUpToDate: cachePubGet, ); + await generateLocalizationsSyntheticPackage( + environment: environment, + buildSystem: globals.buildSystem, + buildTargets: globals.buildTargets, + ); + // null implicitly means all plugins are allowed List? allowedPlugins; if (stringArg(FlutterGlobalOptions.kDeviceIdOption, global: true) == 'preview') { diff --git a/packages/flutter_tools/lib/src/runner/local_engine.dart b/packages/flutter_tools/lib/src/runner/local_engine.dart index 3bda70dceb..6140c9a93b 100644 --- a/packages/flutter_tools/lib/src/runner/local_engine.dart +++ b/packages/flutter_tools/lib/src/runner/local_engine.dart @@ -125,8 +125,7 @@ class LocalEngineLocator { Future _findEngineSourceByPackageConfig(String? packagePath) async { final PackageConfig packageConfig = await loadPackageConfigWithLogging( _fileSystem.file( - // TODO(zanderso): update to package_config - packagePath ?? _fileSystem.path.join('.packages'), + packagePath ?? findPackageConfigFileOrDefault(_fileSystem.currentDirectory), ), logger: _logger, throwOnError: false, diff --git a/packages/flutter_tools/lib/src/web/compile.dart b/packages/flutter_tools/lib/src/web/compile.dart index cfc050fe21..aa0fec8030 100644 --- a/packages/flutter_tools/lib/src/web/compile.dart +++ b/packages/flutter_tools/lib/src/web/compile.dart @@ -102,6 +102,7 @@ class WebBuilder { kServiceWorkerStrategy: serviceWorkerStrategy.cliName, ...buildInfo.toBuildSystemEnvironment(), }, + packageConfigPath: buildInfo.packageConfigPath, artifacts: globals.artifacts!, fileSystem: _fileSystem, logger: _logger, diff --git a/packages/flutter_tools/test/commands.shard/hermetic/build_macos_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/build_macos_test.dart index 057f16a3c0..c7e9cdce5f 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/build_macos_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/build_macos_test.dart @@ -95,7 +95,7 @@ void main() { // Sets up the minimal mock project files necessary to look like a Flutter project. void createCoreMockProjectFiles() { fileSystem.file('pubspec.yaml').createSync(); - fileSystem.file('.packages').createSync(); + fileSystem.file('.dart_tool/package_config.json').createSync(recursive: true); fileSystem.file(fileSystem.path.join('lib', 'main.dart')).createSync(recursive: true); } diff --git a/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart index bfe67bab6b..1c3cbb2b62 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/clean_test.dart @@ -75,7 +75,7 @@ void main() { expect(projectUnderTest.flutterPluginsFile, isNot(exists)); expect(projectUnderTest.flutterPluginsDependenciesFile, isNot(exists)); - expect(projectUnderTest.packagesFile, isNot(exists)); + expect(projectUnderTest.directory.childFile('.packages'), isNot(exists)); expect(xcodeProjectInterpreter.workspaces, const [ CleanWorkspaceCall('/ios/Runner.xcworkspace', 'Runner', false), @@ -231,7 +231,7 @@ FlutterProject setupProjectUnderTest(Directory currentDirectory, bool setupXcode projectUnderTest.macos.hostAppRoot.childDirectory('Runner.xcworkspace').createSync(recursive: true); } projectUnderTest.dartTool.createSync(recursive: true); - projectUnderTest.packagesFile.createSync(recursive: true); + projectUnderTest.directory.childFile('.packages').createSync(recursive: true); projectUnderTest.android.ephemeralDirectory.createSync(recursive: true); projectUnderTest.ios.ephemeralDirectory.createSync(recursive: true); diff --git a/packages/flutter_tools/test/commands.shard/hermetic/pub_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/pub_test.dart index 0f637b6645..48dff38615 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/pub_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/pub_test.dart @@ -117,8 +117,9 @@ void main() { await commandRunner.run(['get', targetDirectory.path]); final FlutterProject rootProject = FlutterProject.fromDirectory(targetDirectory); - expect(rootProject.packageConfigFile.existsSync(), true); - expect(await rootProject.packageConfigFile.readAsString(), '{"configVersion":2,"packages":[]}'); + final File packageConfigFile = rootProject.dartTool.childFile('package_config.json'); + expect(packageConfigFile.existsSync(), true); + expect(packageConfigFile.readAsStringSync(), '{"configVersion":2,"packages":[]}'); }, overrides: { Pub: () => pub, ProcessManager: () => FakeProcessManager.any(), diff --git a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart index ae5e5820d9..f589ba4fd0 100644 --- a/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart +++ b/packages/flutter_tools/test/commands.shard/hermetic/run_test.dart @@ -72,7 +72,7 @@ void main() { testUsingContext('does not support --no-sound-null-safety by default', () async { fileSystem.file('lib/main.dart').createSync(recursive: true); fileSystem.file('pubspec.yaml').createSync(); - fileSystem.file('.packages').createSync(); + fileSystem.file('.dart_tool/package_config.json').createSync(recursive: true); final TestRunCommandThatOnlyValidates command = TestRunCommandThatOnlyValidates(); await expectLater( @@ -96,7 +96,7 @@ void main() { testUsingContext('supports --no-sound-null-safety with an overridden NonNullSafeBuilds', () async { fileSystem.file('lib/main.dart').createSync(recursive: true); fileSystem.file('pubspec.yaml').createSync(); - fileSystem.file('.packages').createSync(); + fileSystem.file('.dart_tool/package_config.json').createSync(recursive: true); final FakeDevice device = FakeDevice(isLocalEmulator: true, platformType: PlatformType.android); @@ -118,7 +118,7 @@ void main() { testUsingContext('does not support "--use-application-binary" and "--fast-start"', () async { fileSystem.file('lib/main.dart').createSync(recursive: true); fileSystem.file('pubspec.yaml').createSync(); - fileSystem.file('.packages').createSync(); + fileSystem.file('.dart_tool/package_config.json').createSync(recursive: true); final RunCommand command = RunCommand(); await expectLater( @@ -143,8 +143,14 @@ void main() { testUsingContext('Walks upward looking for a pubspec.yaml and succeeds if found', () async { fileSystem.file('pubspec.yaml').createSync(); - fileSystem.file('.packages') - .writeAsStringSync('\n'); + fileSystem.file('.dart_tool/package_config.json') + ..createSync(recursive: true) + ..writeAsStringSync(''' +{ + "packages": [], + "configVersion": 2 +} +'''); fileSystem.file('lib/main.dart') .createSync(recursive: true); fileSystem.currentDirectory = fileSystem.directory('a/b/c') @@ -208,8 +214,16 @@ void main() { fs.currentDirectory.childFile('pubspec.yaml') .writeAsStringSync('name: flutter_app'); - fs.currentDirectory.childFile('.packages') - .writeAsStringSync('# Generated by pub on 2019-11-25 12:38:01.801784.'); + fs.currentDirectory + .childDirectory('.dart_tool') + .childFile('package_config.json') + ..createSync(recursive: true) + ..writeAsStringSync(''' +{ + "packages": [], + "configVersion": 2 +} +'''); final Directory libDir = fs.currentDirectory.childDirectory('lib'); libDir.createSync(); final File mainFile = libDir.childFile('main.dart'); @@ -904,7 +918,14 @@ void main() { setUp(() { fileSystem.file('lib/main.dart').createSync(recursive: true); fileSystem.file('pubspec.yaml').createSync(); - fileSystem.file('.packages').createSync(); + fileSystem.file('.dart_tool/package_config.json') + ..createSync(recursive: true) + ..writeAsStringSync(''' +{ + "packages": [], + "configVersion": 2 +} +'''); final FakeDevice device = FakeDevice(isLocalEmulator: true, platformType: PlatformType.android); testDeviceManager.devices = [device]; }); @@ -951,7 +972,7 @@ void main() { testUsingContext('throws a ToolExit when value includes delimiter characters', () async { fileSystem.file('lib/main.dart').createSync(recursive: true); fileSystem.file('pubspec.yaml').createSync(); - fileSystem.file('.packages').createSync(); + fileSystem.file('.dart_tool/package_config.json').createSync(recursive: true); final RunCommand command = RunCommand(); await expectLater( diff --git a/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart b/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart index 7b30df4366..5a91cc445d 100644 --- a/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart +++ b/packages/flutter_tools/test/commands.shard/permeable/packages_test.dart @@ -24,7 +24,9 @@ import 'package:flutter_tools/src/commands/packages.dart'; import 'package:flutter_tools/src/dart/pub.dart'; import 'package:flutter_tools/src/globals.dart' as globals; import 'package:unified_analytics/unified_analytics.dart'; +import 'package:yaml/yaml.dart'; +import '../../integration.shard/test_utils.dart'; import '../../src/common.dart'; import '../../src/context.dart'; import '../../src/fake_process_manager.dart'; @@ -315,6 +317,68 @@ flutter: ), }); + testUsingContext('get fetches packages for a workspace', () async { + tempDir.childFile('pubspec.yaml').writeAsStringSync(''' +name: workspace +environment: + sdk: ^3.5.0-0 +workspace: + - flutter_project +'''); + final String projectPath = await createProject(tempDir, + arguments: ['--no-pub', '--template=module']); + final File pubspecFile = fileSystem.file( + fileSystem.path.join( + projectPath, + 'pubspec.yaml', + ), + ); + final YamlMap pubspecYaml = loadYaml(pubspecFile.readAsStringSync()) as YamlMap; + final Map pubspec = { + ...pubspecYaml.value.cast(), + 'resolution': 'workspace', + 'environment': { + ...(pubspecYaml['environment'] as YamlMap).value.cast(), + 'sdk': '^3.5.0-0', + } + }; + pubspecFile.writeAsStringSync(jsonEncode(pubspec)); + await runCommandIn(projectPath, 'get'); + + expect(mockStdio.stdout.writes.map(utf8.decode), + allOf( + // The output of pub changed, adding backticks around the directory name. + // These regexes are tolerant of the backticks being present or absent. + contains(matches(RegExp(r'Resolving dependencies in .+' + RegExp.escape(tempDir.basename) + r'`?\.\.\.'))), + contains(matches(RegExp(r'\+ flutter 0\.0\.0 from sdk flutter'))), + contains(matches(RegExp(r'Changed \d+ dependencies in .+' + RegExp.escape(tempDir.basename) + r'`?!'))), + ), + ); + expectDependenciesResolved(tempDir.path); + expectZeroPluginsInjected(projectPath); + expect( + analyticsTimingEventExists( + sentEvents: fakeAnalytics.sentEvents, + workflow: 'pub', + variableName: 'get', + label: 'success', + ), + true, + ); + }, overrides: { + Stdio: () => mockStdio, + Pub: () => Pub.test( + fileSystem: globals.fs, + logger: globals.logger, + processManager: globals.processManager, + usage: globals.flutterUsage, + botDetector: globals.botDetector, + platform: globals.platform, + stdio: mockStdio, + ), + Analytics: () => fakeAnalytics, + }); + testUsingContext('get generates normal files when l10n.yaml has synthetic-package: false', () async { final String projectPath = await createProject(tempDir, arguments: ['--no-pub', '--template=module']); diff --git a/packages/flutter_tools/test/general.shard/asset_bundle_flavors_test.dart b/packages/flutter_tools/test/general.shard/asset_bundle_flavors_test.dart index 9a5eeb8697..d4797fda5a 100644 --- a/packages/flutter_tools/test/general.shard/asset_bundle_flavors_test.dart +++ b/packages/flutter_tools/test/general.shard/asset_bundle_flavors_test.dart @@ -32,7 +32,7 @@ void main() { ); await bundle.build( - packagesPath: '.packages', + packageConfigPath: '.packages', flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), flavor: flavor, ); diff --git a/packages/flutter_tools/test/general.shard/asset_bundle_package_fonts_test.dart b/packages/flutter_tools/test/general.shard/asset_bundle_package_fonts_test.dart index febaa31742..d317a353f5 100644 --- a/packages/flutter_tools/test/general.shard/asset_bundle_package_fonts_test.dart +++ b/packages/flutter_tools/test/general.shard/asset_bundle_package_fonts_test.dart @@ -59,7 +59,7 @@ $fontsSection String expectedAssetManifest, ) async { final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); for (final String packageName in packages) { for (final String packageFont in packageFonts) { @@ -110,7 +110,7 @@ $fontsSection writePubspecFile('p/p/pubspec.yaml', 'test_package'); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); expect(bundle.entries.keys, unorderedEquals(['AssetManifest.bin', 'AssetManifest.json', 'FontManifest.json', 'NOTICES.Z'])); }, overrides: { diff --git a/packages/flutter_tools/test/general.shard/asset_bundle_package_test.dart b/packages/flutter_tools/test/general.shard/asset_bundle_package_test.dart index cc7f68a0a0..cbc10a2cf9 100644 --- a/packages/flutter_tools/test/general.shard/asset_bundle_package_test.dart +++ b/packages/flutter_tools/test/general.shard/asset_bundle_package_test.dart @@ -78,7 +78,7 @@ $assetsSection ) async { final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); for (final String packageName in packages) { for (final String asset in assets) { @@ -138,7 +138,7 @@ $assetsSection writePubspecFile('p/p/pubspec.yaml', 'test_package'); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); expect(bundle.entries.keys, unorderedEquals( ['NOTICES.Z', 'AssetManifest.json', 'AssetManifest.bin', 'FontManifest.json'])); const String expectedAssetManifest = '{}'; @@ -164,7 +164,7 @@ $assetsSection writeAssets('p/p/', assets); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); expect(bundle.entries.keys, unorderedEquals( ['NOTICES.Z', 'AssetManifest.json', 'AssetManifest.bin', 'FontManifest.json'])); const String expectedAssetManifest = '{}'; @@ -618,7 +618,7 @@ $assetsSection writeAssets('p/p/', assetsOnDisk); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); expect(bundle.entries['AssetManifest.json'], isNull, reason: 'Invalid pubspec.yaml should not generate AssetManifest.json' ); @@ -698,7 +698,7 @@ $assetsSection ); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); }, overrides: { FileSystem: () => testFileSystem, ProcessManager: () => FakeProcessManager.any(), diff --git a/packages/flutter_tools/test/general.shard/asset_bundle_test.dart b/packages/flutter_tools/test/general.shard/asset_bundle_test.dart index 8a2953ee87..095ff179ff 100644 --- a/packages/flutter_tools/test/general.shard/asset_bundle_test.dart +++ b/packages/flutter_tools/test/general.shard/asset_bundle_test.dart @@ -39,7 +39,7 @@ void main() { testUsingContext('nonempty', () async { final AssetBundle ab = AssetBundleFactory.instance.createBundle(); - expect(await ab.build(packagesPath: '.packages'), 0); + expect(await ab.build(packageConfigPath: '.packages'), 0); expect(ab.entries.length, greaterThan(0)); }, overrides: { FileSystem: () => testFileSystem, @@ -53,7 +53,7 @@ void main() { ..writeAsStringSync(''); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); expect(bundle.entries.keys, unorderedEquals(['AssetManifest.json', 'AssetManifest.bin']) ); @@ -104,7 +104,7 @@ flutter: } final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); expect(bundle.entries.keys, unorderedEquals([ 'AssetManifest.json', @@ -132,7 +132,7 @@ flutter: - assets/foo/ '''); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); expect(bundle.entries.keys, unorderedEquals(['AssetManifest.json', 'AssetManifest.bin', 'FontManifest.json', 'NOTICES.Z', 'assets/foo/bar.txt'])); // Simulate modifying the files by updating the filestat time manually. @@ -141,7 +141,7 @@ flutter: ..setLastModifiedSync(packageFile.lastModifiedSync().add(const Duration(hours: 1))); expect(bundle.needsBuild(), true); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); expect(bundle.entries.keys, unorderedEquals(['AssetManifest.json', 'AssetManifest.bin', 'FontManifest.json', 'NOTICES.Z', 'assets/foo/bar.txt', 'assets/foo/fizz.txt'])); @@ -163,7 +163,7 @@ flutter: '''); globals.fs.file('.packages').createSync(); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); expect(bundle.entries.keys, unorderedEquals(['AssetManifest.json', 'AssetManifest.bin', 'FontManifest.json', 'NOTICES.Z', 'assets/foo/bar.txt'])); expect(bundle.needsBuild(), false); @@ -185,7 +185,7 @@ name: example''') // asset manifest and not updated. This is due to the devfs not // supporting file deletion. expect(bundle.needsBuild(), true); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); expect(bundle.entries.keys, unorderedEquals(['AssetManifest.json', 'AssetManifest.bin', 'FontManifest.json', 'NOTICES.Z', 'assets/foo/bar.txt'])); }, overrides: { @@ -210,7 +210,7 @@ flutter: '''); globals.fs.file('.packages').createSync(); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); expect(bundle.entries.keys, unorderedEquals(['AssetManifest.json', 'AssetManifest.bin', 'FontManifest.json', 'NOTICES.Z', 'assets/foo/bar.txt'])); expect(bundle.needsBuild(), false); @@ -244,7 +244,7 @@ flutter: platform: globals.platform, splitDeferredAssets: true, ).createBundle(); - await bundle.build(packagesPath: '.packages', deferredComponentsEnabled: true); + await bundle.build(packageConfigPath: '.packages', deferredComponentsEnabled: true); expect(bundle.entries.keys, unorderedEquals(['AssetManifest.json', 'AssetManifest.bin', 'FontManifest.json', 'NOTICES.Z', 'assets/foo/bar.txt'])); expect(bundle.deferredComponentsEntries.length, 1); @@ -275,7 +275,7 @@ flutter: - assets/wild/ '''); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); expect(bundle.entries.keys, unorderedEquals(['assets/foo/bar.txt', 'assets/bar/barbie.txt', 'assets/wild/dash.txt', 'AssetManifest.json', 'AssetManifest.bin', 'FontManifest.json', 'NOTICES.Z'])); @@ -311,7 +311,7 @@ flutter: platform: globals.platform, splitDeferredAssets: true, ).createBundle(); - await bundle.build(packagesPath: '.packages', deferredComponentsEnabled: true); + await bundle.build(packageConfigPath: '.packages', deferredComponentsEnabled: true); expect(bundle.entries.keys, unorderedEquals(['assets/foo/bar.txt', 'AssetManifest.json', 'AssetManifest.bin', 'FontManifest.json', 'NOTICES.Z'])); expect(bundle.deferredComponentsEntries.length, 1); @@ -324,7 +324,7 @@ flutter: ..setLastModifiedSync(packageFile.lastModifiedSync().add(const Duration(hours: 1))); expect(bundle.needsBuild(), true); - await bundle.build(packagesPath: '.packages', deferredComponentsEnabled: true); + await bundle.build(packageConfigPath: '.packages', deferredComponentsEnabled: true); expect(bundle.entries.keys, unorderedEquals(['assets/foo/bar.txt', 'AssetManifest.json', 'AssetManifest.bin', 'FontManifest.json', 'NOTICES.Z'])); @@ -366,7 +366,7 @@ flutter: expect( () => bundle.build( - packagesPath: '.packages', + packageConfigPath: '.packages', flutterProject: FlutterProject.fromDirectoryTest( fileSystem.currentDirectory, ), @@ -418,7 +418,7 @@ flutter: expect( () => bundle.build( - packagesPath: '.packages', + packageConfigPath: '.packages', flutterProject: FlutterProject.fromDirectoryTest( fileSystem.currentDirectory, ), @@ -459,7 +459,7 @@ flutter: ); await bundle.build( - packagesPath: '.packages', + packageConfigPath: '.packages', flutterProject: FlutterProject.fromDirectoryTest( fileSystem.currentDirectory, ), @@ -468,7 +468,7 @@ flutter: expect(bundle.entries['my-asset.txt']!.content.isModified, isTrue); await bundle.build( - packagesPath: '.packages', + packageConfigPath: '.packages', flutterProject: FlutterProject.fromDirectoryTest( fileSystem.currentDirectory, ), @@ -487,7 +487,7 @@ flutter: '''); await bundle.build( - packagesPath: '.packages', + packageConfigPath: '.packages', flutterProject: FlutterProject.fromDirectoryTest( fileSystem.currentDirectory, ), @@ -513,7 +513,7 @@ flutter: ..writeAsStringSync(''); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages', targetPlatform: TargetPlatform.web_javascript); + await bundle.build(packageConfigPath: '.packages', targetPlatform: TargetPlatform.web_javascript); expect(bundle.entries.keys, unorderedEquals([ @@ -552,7 +552,7 @@ flutter: ).createSync(recursive: true); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages', targetPlatform: TargetPlatform.web_javascript); + await bundle.build(packageConfigPath: '.packages', targetPlatform: TargetPlatform.web_javascript); expect(bundle.entries.keys, unorderedEquals([ @@ -629,13 +629,13 @@ assets: - assets/foo/bar.txt '''); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); final AssetBundleEntry? assetManifest = bundle.entries['AssetManifest.json']; final AssetBundleEntry? fontManifest = bundle.entries['FontManifest.json']; final AssetBundleEntry? license = bundle.entries['NOTICES']; - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); expect(assetManifest, bundle.entries['AssetManifest.json']); expect(fontManifest, bundle.entries['FontManifest.json']); @@ -660,7 +660,7 @@ flutter: '''); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - expect(await bundle.build(packagesPath: '.packages'), 0); + expect(await bundle.build(packageConfigPath: '.packages'), 0); expect(bundle.additionalDependencies.single.path, contains('DOES_NOT_EXIST_RERUN_FOR_WILDCARD')); }, overrides: { FileSystem: () => MemoryFileSystem.test(), @@ -682,7 +682,7 @@ flutter: '''); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - expect(await bundle.build(packagesPath: '.packages'), 0); + expect(await bundle.build(packageConfigPath: '.packages'), 0); expect(bundle.additionalDependencies, isEmpty); }, overrides: { FileSystem: () => MemoryFileSystem.test(), @@ -726,7 +726,7 @@ flutter: '''); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - expect(await bundle.build(packagesPath: '.packages'), 0); + expect(await bundle.build(packageConfigPath: '.packages'), 0); await writeBundle( output, @@ -779,7 +779,7 @@ flutter: '''); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - expect(await bundle.build(packagesPath: '.packages', targetPlatform: TargetPlatform.web_javascript), 0); + expect(await bundle.build(packageConfigPath: '.packages', targetPlatform: TargetPlatform.web_javascript), 0); await writeBundle( output, @@ -867,7 +867,7 @@ flutter: '''); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - expect(await bundle.build(packagesPath: '.packages', targetPlatform: TargetPlatform.web_javascript), 0); + expect(await bundle.build(packageConfigPath: '.packages', targetPlatform: TargetPlatform.web_javascript), 0); await writeBundle( output, @@ -916,7 +916,7 @@ flutter: final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); globals.fs.file('foo/bar/fizz.txt').createSync(recursive: true); - expect(await bundle.build(packagesPath: '.packages'), 0); + expect(await bundle.build(packageConfigPath: '.packages'), 0); expect(bundle.additionalDependencies, isEmpty); }, overrides: { FileSystem: () => MemoryFileSystem.test(), @@ -950,7 +950,7 @@ flutter: final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); globals.fs.file('foo/bar/fizz.txt').createSync(recursive: true); - await bundle.build(packagesPath: '.packages'); + await bundle.build(packageConfigPath: '.packages'); expect(bundle.entries.keys, unorderedEquals(['packages/foo/bar/fizz.txt', 'AssetManifest.json', 'AssetManifest.bin', 'FontManifest.json', 'NOTICES.Z'])); @@ -993,7 +993,7 @@ flutter: '''); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - expect(await bundle.build(packagesPath: '.packages'), 1); + expect(await bundle.build(packageConfigPath: '.packages'), 1); expect(testLogger.errorText, contains('This asset was included from package foo')); }, overrides: { FileSystem: () => MemoryFileSystem.test(), @@ -1016,7 +1016,7 @@ flutter: '''); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - expect(await bundle.build(packagesPath: '.packages'), 1); + expect(await bundle.build(packageConfigPath: '.packages'), 1); expect(testLogger.errorText, isNot(contains('This asset was included from'))); }, overrides: { FileSystem: () => MemoryFileSystem.test(), @@ -1050,7 +1050,7 @@ flutter: '''); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - expect(await bundle.build(packagesPath: '.packages'), 0); + expect(await bundle.build(packageConfigPath: '.packages'), 0); expect((bundle.entries['FontManifest.json']!.content as DevFSStringContent).string, '[]'); expect((bundle.entries['AssetManifest.json']!.content as DevFSStringContent).string, '{}'); expect(testLogger.errorText, contains( @@ -1087,7 +1087,7 @@ flutter: final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - expect(await bundle.build(packagesPath: '.packages'), 0); + expect(await bundle.build(packageConfigPath: '.packages'), 0); expect(bundle.entries.keys, unorderedEquals(['assets/foo.txt', 'AssetManifest.json', 'AssetManifest.bin', 'FontManifest.json', 'NOTICES.Z'])); }, overrides: { @@ -1122,7 +1122,7 @@ flutter: globals.fs.file('assets/zebra.jpg').createSync(); final AssetBundle bundle = AssetBundleFactory.instance.createBundle(); - expect(await bundle.build(packagesPath: '.packages'), 0); + expect(await bundle.build(packageConfigPath: '.packages'), 0); expect((bundle.entries['FontManifest.json']!.content as DevFSStringContent).string, '[]'); // The assets from deferred components and regular assets // are both included in alphabetical order diff --git a/packages/flutter_tools/test/general.shard/asset_bundle_variant_test.dart b/packages/flutter_tools/test/general.shard/asset_bundle_variant_test.dart index cef1729880..c26d635abc 100644 --- a/packages/flutter_tools/test/general.shard/asset_bundle_variant_test.dart +++ b/packages/flutter_tools/test/general.shard/asset_bundle_variant_test.dart @@ -99,7 +99,7 @@ ${assets.map((String entry) => ' - $entry').join('\n')} ); await bundle.build( - packagesPath: '.packages', + packageConfigPath: '.packages', flutterProject: FlutterProject.fromDirectoryTest(fs.currentDirectory), ); @@ -154,7 +154,7 @@ ${assets.map((String entry) => ' - $entry').join('\n')} ); await bundle.build( - packagesPath: '.packages', + packageConfigPath: '.packages', flutterProject: FlutterProject.fromDirectoryTest(fs.currentDirectory), ); @@ -210,7 +210,7 @@ ${assets.map((String entry) => ' - $entry').join('\n')} ); await bundle.build( - packagesPath: '.packages', + packageConfigPath: '.packages', flutterProject: FlutterProject.fromDirectoryTest(fs.currentDirectory), ); @@ -256,7 +256,7 @@ ${assets.map((String entry) => ' - $entry').join('\n')} ); await bundle.build( - packagesPath: '.packages', + packageConfigPath: '.packages', flutterProject: FlutterProject.fromDirectoryTest(fs.currentDirectory), ); @@ -328,7 +328,7 @@ flutter: ); await bundle.build( - packagesPath: '.packages', + packageConfigPath: '.packages', flutterProject: FlutterProject.fromDirectoryTest(fs.currentDirectory), ); diff --git a/packages/flutter_tools/test/general.shard/asset_test.dart b/packages/flutter_tools/test/general.shard/asset_test.dart index 4fc4a116d5..aef7fa5325 100644 --- a/packages/flutter_tools/test/general.shard/asset_test.dart +++ b/packages/flutter_tools/test/general.shard/asset_test.dart @@ -115,7 +115,7 @@ dependencies: '''); await assetBundle.build( - packagesPath: packagesPath, + packageConfigPath: packagesPath, manifestPath: manifestPath, flutterProject: FlutterProject.fromDirectoryTest(fileSystem.directory('main')), ); @@ -155,7 +155,7 @@ dependencies: await assetBundle.build( manifestPath: manifestPath, // file doesn't exist - packagesPath: packagesPath, + packageConfigPath: packagesPath, flutterProject: FlutterProject.fromDirectoryTest(fileSystem.file(manifestPath).parent), ); @@ -203,7 +203,7 @@ dependencies: ); await assetBundle.build( - packagesPath: '.packages', + packageConfigPath: '.packages', targetPlatform: TargetPlatform.android_arm, flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), ); @@ -248,7 +248,7 @@ dependencies: ); await assetBundle.build( - packagesPath: '.packages', + packageConfigPath: '.packages', targetPlatform: TargetPlatform.web_javascript, flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory), ); 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 e14f4614ae..d5c9a5a7e5 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 @@ -33,7 +33,7 @@ const List _kDart2WasmLinuxArgs = [ 'Artifact.engineDartBinary.TargetPlatform.web_javascript', 'compile', 'wasm', - '--packages=.dart_tool/package_config.json', + '--packages=/.dart_tool/package_config.json', '--extra-compiler-option=--platform=HostArtifact.webPlatformKernelFolder/dart2wasm_platform.dill', '--extra-compiler-option=--delete-tostring-package-uri=dart:ui', '--extra-compiler-option=--delete-tostring-package-uri=package:flutter', @@ -53,9 +53,21 @@ void main() { setUp(() { testbed = Testbed(setup: () { - globals.fs.file('.packages') + globals.fs.directory('.dart_tool').childFile('package_config.json') ..createSync(recursive: true) - ..writeAsStringSync('foo:foo/lib/\n'); + ..writeAsStringSync(''' +{ + "configVersion": 2, + "packages": [ + { + "name": "foo", + "rootUri": "../foo/", + "packageUri": "lib/", + "languageVersion": "2.7" + } + ] +} +'''); globals.fs.currentDirectory.childDirectory('bar').createSync(); processManager = FakeProcessManager.empty(); globals.fs.file('bin/cache/flutter_web_sdk/flutter_js/flutter.js') @@ -395,7 +407,7 @@ void main() { '--no-source-maps', '-o', environment.buildDir.childFile('app.dill').absolute.path, - '--packages=.dart_tool/package_config.json', + '--packages=/.dart_tool/package_config.json', '--cfe-only', environment.buildDir.childFile('main.dart').absolute.path, ] @@ -440,7 +452,7 @@ void main() { '--no-source-maps', '-o', environment.buildDir.childFile('app.dill').absolute.path, - '--packages=.dart_tool/package_config.json', + '--packages=/.dart_tool/package_config.json', '--cfe-only', environment.buildDir.childFile('main.dart').absolute.path, ] @@ -484,7 +496,7 @@ void main() { '--no-source-maps', '-o', environment.buildDir.childFile('app.dill').absolute.path, - '--packages=.dart_tool/package_config.json', + '--packages=/.dart_tool/package_config.json', '--cfe-only', environment.buildDir.childFile('main.dart').absolute.path, ] @@ -527,7 +539,7 @@ void main() { '--no-source-maps', '-o', environment.buildDir.childFile('app.dill').absolute.path, - '--packages=.dart_tool/package_config.json', + '--packages=/.dart_tool/package_config.json', '--cfe-only', environment.buildDir.childFile('main.dart').absolute.path, ] @@ -569,7 +581,7 @@ void main() { '--no-source-maps', '-o', environment.buildDir.childFile('app.dill').absolute.path, - '--packages=.dart_tool/package_config.json', + '--packages=/.dart_tool/package_config.json', '--cfe-only', environment.buildDir.childFile('main.dart').absolute.path, ] @@ -612,7 +624,7 @@ void main() { '--no-source-maps', '-o', environment.buildDir.childFile('app.dill').absolute.path, - '--packages=.dart_tool/package_config.json', + '--packages=/.dart_tool/package_config.json', '--cfe-only', environment.buildDir.childFile('main.dart').absolute.path, ] @@ -655,7 +667,7 @@ void main() { '--no-source-maps', '-o', environment.buildDir.childFile('app.dill').absolute.path, - '--packages=.dart_tool/package_config.json', + '--packages=/.dart_tool/package_config.json', '--cfe-only', environment.buildDir.childFile('main.dart').absolute.path, ] @@ -697,7 +709,7 @@ void main() { '--no-source-maps', '-o', environment.buildDir.childFile('app.dill').absolute.path, - '--packages=.dart_tool/package_config.json', + '--packages=/.dart_tool/package_config.json', '--cfe-only', environment.buildDir.childFile('main.dart').absolute.path, ], onRun: (_) { @@ -751,7 +763,7 @@ void main() { '--no-source-maps', '-o', environment.buildDir.childFile('app.dill').absolute.path, - '--packages=.dart_tool/package_config.json', + '--packages=/.dart_tool/package_config.json', '--cfe-only', environment.buildDir.childFile('main.dart').absolute.path, ] @@ -794,7 +806,7 @@ void main() { '-DFLUTTER_WEB_CANVASKIT_URL=https://www.gstatic.com/flutter-canvaskit/abcdefghijklmnopqrstuvwxyz/', '-o', environment.buildDir.childFile('app.dill').absolute.path, - '--packages=.dart_tool/package_config.json', + '--packages=/.dart_tool/package_config.json', '--cfe-only', environment.buildDir.childFile('main.dart').absolute.path, ] @@ -836,7 +848,7 @@ void main() { '--no-source-maps', '-o', environment.buildDir.childFile('app.dill').absolute.path, - '--packages=.dart_tool/package_config.json', + '--packages=/.dart_tool/package_config.json', '--cfe-only', environment.buildDir.childFile('main.dart').absolute.path, ] @@ -883,7 +895,7 @@ void main() { '--enable-asserts', '-o', environment.buildDir.childFile('app.dill').absolute.path, - '--packages=.dart_tool/package_config.json', + '--packages=/.dart_tool/package_config.json', '--cfe-only', environment.buildDir.childFile('main.dart').absolute.path, ] @@ -929,7 +941,7 @@ void main() { '--no-source-maps', '-o', environment.buildDir.childFile('app.dill').absolute.path, - '--packages=.dart_tool/package_config.json', + '--packages=/.dart_tool/package_config.json', '--cfe-only', environment.buildDir.childFile('main.dart').absolute.path, ] @@ -974,7 +986,7 @@ void main() { '--no-source-maps', '-o', environment.buildDir.childFile('app.dill').absolute.path, - '--packages=.dart_tool/package_config.json', + '--packages=/.dart_tool/package_config.json', '--cfe-only', environment.buildDir.childFile('main.dart').absolute.path, ] diff --git a/packages/flutter_tools/test/general.shard/dart_plugin_test.dart b/packages/flutter_tools/test/general.shard/dart_plugin_test.dart index 4e094070e5..dc4e8e4816 100644 --- a/packages/flutter_tools/test/general.shard/dart_plugin_test.dart +++ b/packages/flutter_tools/test/general.shard/dart_plugin_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:convert'; + import 'package:file/file.dart'; import 'package:file/memory.dart'; import 'package:flutter_tools/src/dart/package_map.dart'; @@ -34,7 +36,10 @@ void main() { ..flutterPluginsFile = directory.childFile('.flutter-plugins') ..flutterPluginsDependenciesFile = directory.childFile('.flutter-plugins-dependencies') ..dartPluginRegistrant = directory.childFile('dart_plugin_registrant.dart'); - flutterProject.directory.childFile('.packages').createSync(recursive: true); + flutterProject.directory + .childDirectory('.dart_tool') + .childFile('package_config.json') + .createSync(recursive: true); }); group('resolvePlatformImplementation', () { @@ -1492,6 +1497,26 @@ void main() { }); } +void addToPackageConfig( + FlutterProject project, + String name, + Directory packageDir) { + final File packageConfigFile = project.directory + .childDirectory('.dart_tool') + .childFile('package_config.json'); + + final Map packageConfig = + jsonDecode(packageConfigFile.readAsStringSync()) as Map; + + (packageConfig['packages']! as List).add({ + 'name': name, + 'rootUri': packageDir.uri.toString(), + 'packageUri': 'lib/', + }); + + packageConfigFile.writeAsStringSync(jsonEncode(packageConfig)); +} + void createFakeDartPlugins( FakeFlutterProject flutterProject, FakeFlutterManifest flutterManifest, @@ -1499,20 +1524,23 @@ void createFakeDartPlugins( Map plugins, ) { final Directory fakePubCache = fs.systemTempDirectory.childDirectory('cache'); - final File packagesFile = flutterProject.directory - .childFile('.packages'); - if (packagesFile.existsSync()) { - packagesFile.deleteSync(); - } - packagesFile.createSync(recursive: true); + + flutterProject.directory + .childDirectory('.dart_tool') + .childFile('package_config.json') + ..deleteSync(recursive: true) + ..createSync(recursive: true) + ..writeAsStringSync(''' +{ + "packages": [], + "configVersion": 2 +} +'''); for (final MapEntry entry in plugins.entries) { final String name = fs.path.basename(entry.key); final Directory pluginDirectory = fakePubCache.childDirectory(name); - packagesFile.writeAsStringSync( - '$name:file://${pluginDirectory.childFile('lib').uri}\n', - mode: FileMode.writeOnlyAppend, - ); + addToPackageConfig(flutterProject, name, pluginDirectory); pluginDirectory.childFile('pubspec.yaml') ..createSync(recursive: true) ..writeAsStringSync(entry.value); diff --git a/packages/flutter_tools/test/general.shard/devfs_test.dart b/packages/flutter_tools/test/general.shard/devfs_test.dart index ddff7c6ec9..8ab44c8114 100644 --- a/packages/flutter_tools/test/general.shard/devfs_test.dart +++ b/packages/flutter_tools/test/general.shard/devfs_test.dart @@ -948,7 +948,7 @@ class FakeBundle extends AssetBundle { Future build({ String manifestPath = defaultManifestPath, String? assetDirPath, - String? packagesPath, + String? packageConfigPath, bool deferredComponentsEnabled = false, TargetPlatform? targetPlatform, String? flavor, diff --git a/packages/flutter_tools/test/general.shard/ios/mac_test.dart b/packages/flutter_tools/test/general.shard/ios/mac_test.dart index a21455357c..d52a979f23 100644 --- a/packages/flutter_tools/test/general.shard/ios/mac_test.dart +++ b/packages/flutter_tools/test/general.shard/ios/mac_test.dart @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:convert'; + import 'package:file/file.dart'; import 'package:file/memory.dart'; import 'package:flutter_tools/src/artifacts.dart'; @@ -756,6 +758,27 @@ duplicate symbol '_$s29plugin_1_name23PluginNamePluginC9setDouble3key5valueySS_S }); } + void addToPackageConfig( + FlutterProject flutterProject, + String name, + Directory packageDir, + ) { + final File packageConfigFile = flutterProject.directory + .childDirectory('.dart_tool') + .childFile('package_config.json'); + + final Map packageConfig = + jsonDecode(packageConfigFile.readAsStringSync()) as Map; + + (packageConfig['packages']! as List).add({ + 'name': name, + 'rootUri': packageDir.uri.toString(), + 'packageUri': 'lib/', + }); + + packageConfigFile.writeAsStringSync(jsonEncode(packageConfig)); + } + void createFakePlugins( FlutterProject flutterProject, FileSystem fileSystem, @@ -772,13 +795,17 @@ void createFakePlugins( '''; final Directory fakePubCache = fileSystem.systemTempDirectory.childDirectory('cache'); - final File packagesFile = flutterProject.directory.childFile('.packages') - ..createSync(recursive: true); + flutterProject.directory.childDirectory('.dart_tool').childFile('package_config.json') + ..createSync(recursive: true) + ..writeAsStringSync(''' +{ + "packages": [], + "configVersion": 2 +} +'''); for (final String name in pluginNames) { final Directory pluginDirectory = fakePubCache.childDirectory(name); - packagesFile.writeAsStringSync( - '$name:${pluginDirectory.childFile('lib').uri}\n', - mode: FileMode.writeOnlyAppend); + addToPackageConfig(flutterProject, name, pluginDirectory); pluginDirectory.childFile('pubspec.yaml') ..createSync(recursive: true) ..writeAsStringSync(pluginYamlTemplate.replaceAll('PLUGIN_CLASS', name)); diff --git a/packages/flutter_tools/test/general.shard/isolated/fake_native_assets_build_runner.dart b/packages/flutter_tools/test/general.shard/isolated/fake_native_assets_build_runner.dart index 395e26e5d4..20bf8d1e1c 100644 --- a/packages/flutter_tools/test/general.shard/isolated/fake_native_assets_build_runner.dart +++ b/packages/flutter_tools/test/general.shard/isolated/fake_native_assets_build_runner.dart @@ -165,6 +165,7 @@ class FakeHotRunnerNativeAssetsBuilder implements HotRunnerNativeAssetsBuilder { required Uri projectUri, required FileSystem fileSystem, required List flutterDevices, + required String packageConfigPath, required PackageConfig packageConfig, required Logger logger, }) { diff --git a/packages/flutter_tools/test/general.shard/isolated/linux/native_assets_test.dart b/packages/flutter_tools/test/general.shard/isolated/linux/native_assets_test.dart index c1a1aaae23..dac1d72bca 100644 --- a/packages/flutter_tools/test/general.shard/isolated/linux/native_assets_test.dart +++ b/packages/flutter_tools/test/general.shard/isolated/linux/native_assets_test.dart @@ -469,18 +469,18 @@ void main() { await fileSystem.file('/some/path/to/llvm-ar').create(); await fileSystem.file('/some/path/to/ld.lld').create(); - final File packagesFile = fileSystem + final File packageConfigFile = fileSystem .directory(projectUri) .childDirectory('.dart_tool') .childFile('package_config.json'); - await packagesFile.parent.create(); - await packagesFile.create(); + await packageConfigFile.parent.create(); + await packageConfigFile.create(); final PackageConfig packageConfig = await loadPackageConfigWithLogging( - packagesFile, + packageConfigFile, logger: environment.logger, ); final NativeAssetsBuildRunner runner = - NativeAssetsBuildRunnerImpl(projectUri, packageConfig, fileSystem, logger); + NativeAssetsBuildRunnerImpl(projectUri, packageConfigFile.path, packageConfig, fileSystem, logger); final CCompilerConfigImpl result = await runner.cCompilerConfig; expect(result.compiler, Uri.file('/some/path/to/clang')); }); diff --git a/packages/flutter_tools/test/general.shard/isolated/macos/native_assets_test.dart b/packages/flutter_tools/test/general.shard/isolated/macos/native_assets_test.dart index 011ac0b92d..accfcd463c 100644 --- a/packages/flutter_tools/test/general.shard/isolated/macos/native_assets_test.dart +++ b/packages/flutter_tools/test/general.shard/isolated/macos/native_assets_test.dart @@ -497,18 +497,19 @@ InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault return; } - final File packagesFile = fileSystem + final File packageConfigFile = fileSystem .directory(projectUri) .childDirectory('.dart_tool') .childFile('package_config.json'); - await packagesFile.parent.create(); - await packagesFile.create(); + await packageConfigFile.parent.create(); + await packageConfigFile.create(); final PackageConfig packageConfig = await loadPackageConfigWithLogging( - packagesFile, + packageConfigFile, logger: environment.logger, ); final NativeAssetsBuildRunner runner = NativeAssetsBuildRunnerImpl( projectUri, + packageConfigFile.path, packageConfig, fileSystem, logger, diff --git a/packages/flutter_tools/test/general.shard/isolated/windows/native_assets_test.dart b/packages/flutter_tools/test/general.shard/isolated/windows/native_assets_test.dart index 454608ea5f..2eada062d9 100644 --- a/packages/flutter_tools/test/general.shard/isolated/windows/native_assets_test.dart +++ b/packages/flutter_tools/test/general.shard/isolated/windows/native_assets_test.dart @@ -491,18 +491,19 @@ void main() { fileSystem.directory(r'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.35.32215\bin\Hostx64\x64'); await msvcBinDir.create(recursive: true); - final File packagesFile = fileSystem + final File packageConfigFile = fileSystem .directory(projectUri) .childDirectory('.dart_tool') .childFile('package_config.json'); - await packagesFile.parent.create(); - await packagesFile.create(); + await packageConfigFile.parent.create(); + await packageConfigFile.create(); final PackageConfig packageConfig = await loadPackageConfigWithLogging( - packagesFile, + packageConfigFile, logger: environment.logger, ); final NativeAssetsBuildRunner runner = NativeAssetsBuildRunnerImpl( projectUri, + packageConfigFile.path, packageConfig, fileSystem, logger, diff --git a/packages/flutter_tools/test/general.shard/macos/cocoapod_utils_test.dart b/packages/flutter_tools/test/general.shard/macos/cocoapod_utils_test.dart index 0a12510e8e..454222d247 100644 --- a/packages/flutter_tools/test/general.shard/macos/cocoapod_utils_test.dart +++ b/packages/flutter_tools/test/general.shard/macos/cocoapod_utils_test.dart @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +import 'dart:convert'; import 'package:file/file.dart'; import 'package:file/memory.dart'; @@ -35,7 +36,14 @@ void main() { ..web = FakeWebProject() ..windows = FakeWindowsProject() ..linux = FakeLinuxProject(); - flutterProject.directory.childFile('.packages').createSync(recursive: true); + flutterProject.directory.childDirectory('.dart_tool').childFile('package_config.json') + ..createSync(recursive: true) + ..writeAsStringSync(''' +{ + "packages": [], + "configVersion": 2 +} +'''); } setUp(() async { @@ -60,17 +68,25 @@ void main() { '''; final Directory fakePubCache = fileSystem.systemTempDirectory.childDirectory('cache'); - final File packagesFile = flutterProject.directory.childFile('.packages') + final File packageConfigFile = flutterProject.directory.childDirectory('.dart_tool').childFile('package_config.json') ..createSync(recursive: true); + final Map packageConfig = { + 'packages': [], + 'configVersion': 2, + }; for (final String name in pluginNames) { final Directory pluginDirectory = fakePubCache.childDirectory(name); - packagesFile.writeAsStringSync( - '$name:${pluginDirectory.childFile('lib').uri}\n', - mode: FileMode.writeOnlyAppend); + (packageConfig['packages']! as List).add({ + 'name': name, + 'rootUri': pluginDirectory.uri.toString(), + 'packageUri': 'lib/', + }); pluginDirectory.childFile('pubspec.yaml') ..createSync(recursive: true) ..writeAsStringSync(pluginYamlTemplate.replaceAll('PLUGIN_CLASS', name)); } + + packageConfigFile.writeAsStringSync(jsonEncode(packageConfig)); } group('for iOS', () { diff --git a/packages/flutter_tools/test/general.shard/macos/cocoapods_test.dart b/packages/flutter_tools/test/general.shard/macos/cocoapods_test.dart index adf87359d2..16d64d78ad 100644 --- a/packages/flutter_tools/test/general.shard/macos/cocoapods_test.dart +++ b/packages/flutter_tools/test/general.shard/macos/cocoapods_test.dart @@ -330,12 +330,13 @@ void main() { group('Update xcconfig', () { testUsingContext('includes Pod config in xcconfig files, if the user manually added Pod dependencies without using Flutter plugins', () async { final FlutterProject projectUnderTest = setupProjectUnderTest(); - fileSystem.file(fileSystem.path.join('project', 'foo', '.packages')) - ..createSync(recursive: true) - ..writeAsStringSync('\n'); + final File packageConfigFile = fileSystem.file( + fileSystem.path.join('project', '.dart_tool', 'package_config.json'), + ); + packageConfigFile.createSync(recursive: true); + packageConfigFile.writeAsStringSync('{"configVersion":2,"packages":[]}'); projectUnderTest.ios.podfile..createSync()..writeAsStringSync('Custom Podfile'); projectUnderTest.ios.podfileLock..createSync()..writeAsStringSync('Podfile.lock from user executed `pod install`'); - projectUnderTest.packagesFile..createSync()..writeAsStringSync(''); projectUnderTest.ios.xcodeConfigFor('Debug') ..createSync(recursive: true) ..writeAsStringSync('Existing debug config'); diff --git a/packages/flutter_tools/test/general.shard/plugins_test.dart b/packages/flutter_tools/test/general.shard/plugins_test.dart index 68a4548680..f7f00d2f80 100644 --- a/packages/flutter_tools/test/general.shard/plugins_test.dart +++ b/packages/flutter_tools/test/general.shard/plugins_test.dart @@ -175,9 +175,33 @@ void main() { // Add basic properties to the Flutter project and subprojects setUpProject(fs); - flutterProject.directory.childFile('.packages').createSync(recursive: true); + flutterProject.directory.childDirectory('.dart_tool').childFile('package_config.json') + ..createSync(recursive: true) + ..writeAsStringSync(''' +{ + "packages": [], + "configVersion": 2 +} +'''); }); + void addToPackageConfig(String name, Directory packageDir) { + final File packageConfigFile = flutterProject.directory + .childDirectory('.dart_tool') + .childFile('package_config.json'); + + final Map packageConfig = + jsonDecode(packageConfigFile.readAsStringSync()) as Map; + + (packageConfig['packages']! as List).add({ + 'name': name, + 'rootUri': packageDir.uri.toString(), + 'packageUri': 'lib/', + }); + + packageConfigFile.writeAsStringSync(jsonEncode(packageConfig)); + } + // Makes fake plugin packages for each plugin, adds them to flutterProject, // and returns their directories. // @@ -208,16 +232,20 @@ void main() { final List directories = []; final Directory fakePubCache = fileSystem.systemTempDirectory.childDirectory('cache'); - final File packagesFile = flutterProject.directory.childFile('.packages') - ..createSync(recursive: true); + flutterProject.directory.childDirectory('.dart_tool').childFile('package_config.json') + ..createSync(recursive: true) + ..writeAsStringSync(''' +{ + "packages": [], + "configVersion": 2 +} +'''); for (final String nameOrPath in pluginNamesOrPaths) { final String name = fileSystem.path.basename(nameOrPath); final Directory pluginDirectory = (nameOrPath == name) ? fakePubCache.childDirectory(name) : fileSystem.directory(nameOrPath); - packagesFile.writeAsStringSync( - '$name:${pluginDirectory.childFile('lib').uri}\n', - mode: FileMode.writeOnlyAppend); + addToPackageConfig(name, pluginDirectory); pluginDirectory.childFile('pubspec.yaml') ..createSync(recursive: true) ..writeAsStringSync(pluginYamlTemplate.replaceAll('PLUGIN_CLASS', sentenceCase(camelCase(name)))); @@ -231,6 +259,8 @@ void main() { return createFakePlugins(fileSystem, ['some_plugin'])[0]; } + + void createNewJavaPlugin1() { final Directory pluginUsingJavaAndNewEmbeddingDir = fs.systemTempDirectory.createTempSync('flutter_plugin_using_java_and_new_embedding_dir.'); @@ -251,13 +281,7 @@ flutter: .childFile('UseNewEmbedding.java') ..createSync(recursive: true) ..writeAsStringSync('import io.flutter.embedding.engine.plugins.FlutterPlugin;'); - - flutterProject.directory - .childFile('.packages') - .writeAsStringSync( - 'plugin1:${pluginUsingJavaAndNewEmbeddingDir.childDirectory('lib').uri}\n', - mode: FileMode.append, - ); + addToPackageConfig('plugin1', pluginUsingJavaAndNewEmbeddingDir); } Directory createPluginWithInvalidAndroidPackage() { @@ -282,12 +306,7 @@ flutter: ..createSync(recursive: true) ..writeAsStringSync('import io.flutter.embedding.engine.plugins.FlutterPlugin;'); - flutterProject.directory - .childFile('.packages') - .writeAsStringSync( - 'plugin1:${pluginUsingJavaAndNewEmbeddingDir.childDirectory('lib').uri}\n', - mode: FileMode.append, - ); + addToPackageConfig('plugin1', pluginUsingJavaAndNewEmbeddingDir); return pluginUsingJavaAndNewEmbeddingDir; } @@ -316,12 +335,7 @@ flutter: 'registerWith(Irrelevant registrar)\n' ); - flutterProject.directory - .childFile('.packages') - .writeAsStringSync( - 'plugin4:${pluginUsingJavaAndNewEmbeddingDir.childDirectory('lib').uri}', - mode: FileMode.append, - ); + addToPackageConfig('plugin4', pluginUsingJavaAndNewEmbeddingDir); } Directory createLegacyPluginWithDependencies({ @@ -345,12 +359,7 @@ dependencies: .childFile('pubspec.yaml') .writeAsStringSync(' $dependency:\n', mode: FileMode.append); } - flutterProject.directory - .childFile('.packages') - .writeAsStringSync( - '$name:${pluginDirectory.childDirectory('lib').uri}\n', - mode: FileMode.append, - ); + addToPackageConfig(name, pluginDirectory); return pluginDirectory; } @@ -381,12 +390,7 @@ dependencies: .childFile('pubspec.yaml') .writeAsStringSync(' $dependency:\n', mode: FileMode.append); } - flutterProject.directory - .childFile('.packages') - .writeAsStringSync( - '$name:${pluginDirectory.childDirectory('lib').uri}\n', - mode: FileMode.append, - ); + addToPackageConfig(name, pluginDirectory); return pluginDirectory; } @@ -912,11 +916,7 @@ dependencies: .childFile('web_plugin.dart') .createSync(recursive: true); - flutterProject.directory - .childFile('.packages') - .writeAsStringSync(''' -web_plugin_with_nested:${webPluginWithNestedFile.childDirectory('lib').uri} -'''); + addToPackageConfig('web_plugin_with_nested', webPluginWithNestedFile); final Directory destination = flutterProject.directory.childDirectory('lib'); await injectBuildTimePluginFiles(flutterProject, webPlatform: true, destination: destination); diff --git a/packages/flutter_tools/test/general.shard/project_file_invalidator_test.dart b/packages/flutter_tools/test/general.shard/project_file_invalidator_test.dart index 35c12cabf6..c92e2846eb 100644 --- a/packages/flutter_tools/test/general.shard/project_file_invalidator_test.dart +++ b/packages/flutter_tools/test/general.shard/project_file_invalidator_test.dart @@ -7,7 +7,6 @@ import 'package:flutter_tools/src/base/file_system.dart'; import 'package:flutter_tools/src/base/logger.dart'; import 'package:flutter_tools/src/base/multi_root_file_system.dart'; import 'package:flutter_tools/src/base/platform.dart'; -import 'package:flutter_tools/src/convert.dart'; import 'package:flutter_tools/src/run_hot.dart'; import 'package:package_config/package_config.dart'; @@ -25,13 +24,20 @@ void main() { platform: FakePlatform(), logger: BufferLogger.test(), ); - fileSystem.file('.packages').writeAsStringSync('\n'); + fileSystem.file('.dart_tool/package_config.json') + ..createSync(recursive: true) + ..writeAsStringSync(''' +{ + "packages": [], + "configVersion": 2 +} +'''); expect( (await projectFileInvalidator.findInvalidated( lastCompiled: null, urisToMonitor: [], - packagesPath: '.packages', + packagesPath: '.dart_tool/package_config.json', asyncScanning: asyncScanning, packageConfig: PackageConfig.empty, )).uris, @@ -46,13 +52,20 @@ void main() { platform: FakePlatform(), logger: BufferLogger.test(), ); - fileSystem.file('.packages').writeAsStringSync('\n'); + fileSystem.file('.dart_tool/package_config.json') + ..createSync(recursive: true) + ..writeAsStringSync(''' +{ + "packages": [], + "configVersion": 2 +} +'''); expect( (await projectFileInvalidator.findInvalidated( lastCompiled: inFuture, urisToMonitor: [], - packagesPath: '.packages', + packagesPath: '.dart_tool/package_config.json', asyncScanning: asyncScanning, packageConfig: PackageConfig.empty, )).uris, @@ -67,13 +80,20 @@ void main() { platform: FakePlatform(), logger: BufferLogger.test(), ); - fileSystem.file('.packages').writeAsStringSync('\n'); + fileSystem.file('.dart_tool/package_config.json') + ..createSync(recursive: true) + ..writeAsStringSync(''' +{ + "packages": [], + "configVersion": 2 +} +'''); expect( (await projectFileInvalidator.findInvalidated( lastCompiled: inFuture, urisToMonitor: [Uri.parse('/not-there-anymore'),], - packagesPath: '.packages', + packagesPath: '.dart_tool/package_config.json', asyncScanning: asyncScanning, packageConfig: PackageConfig.empty, )).uris, @@ -81,89 +101,6 @@ void main() { ); }); - testWithoutContext('Picks up changes to the .packages file and updates package_config.json, asyncScanning: $asyncScanning', () async { - final DateTime past = DateTime.now().subtract(const Duration(seconds: 1)); - final FileSystem fileSystem = MemoryFileSystem.test(); - const PackageConfig packageConfig = PackageConfig.empty; - final ProjectFileInvalidator projectFileInvalidator = ProjectFileInvalidator( - fileSystem: fileSystem, - platform: FakePlatform(), - logger: BufferLogger.test(), - ); - fileSystem.file('.packages') - .writeAsStringSync('\n'); - fileSystem.file('.dart_tool/package_config.json') - ..createSync(recursive: true) - ..writeAsStringSync(json.encode({ - 'configVersion': 2, - 'packages': [], - })); - - final InvalidationResult invalidationResult = await projectFileInvalidator.findInvalidated( - lastCompiled: null, - urisToMonitor: [], - packagesPath: '.packages', - asyncScanning: asyncScanning, - packageConfig: packageConfig, - ); - expect(invalidationResult.uris, isEmpty); - fileSystem.file('.packages').setLastModifiedSync(DateTime.now()); - - final InvalidationResult secondInvalidation = await projectFileInvalidator.findInvalidated( - lastCompiled: past, - urisToMonitor: [], - packagesPath: '.packages', - asyncScanning: asyncScanning, - packageConfig: packageConfig, - ); - expect(secondInvalidation.uris, unorderedEquals([ - Uri.parse('.packages'), - Uri.parse('.dart_tool/package_config.json'), - ])); - }); - - testWithoutContext('Picks up changes to the .packages file and updates PackageConfig, asyncScanning: $asyncScanning', () async { - final FileSystem fileSystem = MemoryFileSystem.test(); - const PackageConfig packageConfig = PackageConfig.empty; - final ProjectFileInvalidator projectFileInvalidator = ProjectFileInvalidator( - fileSystem: fileSystem, - platform: FakePlatform(), - logger: BufferLogger.test(), - ); - fileSystem.file('.packages') - .writeAsStringSync('\n'); - - final InvalidationResult invalidationResult = await projectFileInvalidator.findInvalidated( - lastCompiled: null, - urisToMonitor: [], - packagesPath: '.packages', - asyncScanning: asyncScanning, - packageConfig: packageConfig, - ); - - // Initial package config is re-used. - expect(invalidationResult.packageConfig, packageConfig); - - fileSystem.file('.packages') - .writeAsStringSync('foo:lib/\n'); - final DateTime packagesUpdated = fileSystem.statSync('.packages') - .modified; - - final InvalidationResult nextInvalidationResult = await projectFileInvalidator - .findInvalidated( - lastCompiled: packagesUpdated.subtract(const Duration(seconds: 1)), - urisToMonitor: [], - packagesPath: '.packages', - asyncScanning: asyncScanning, - packageConfig: PackageConfig.empty, - ); - - expect(nextInvalidationResult.uris, contains(Uri.parse('.packages'))); - // The PackageConfig should have been recreated too - expect(nextInvalidationResult.packageConfig, - isNot(invalidationResult.packageConfig)); - }); - testWithoutContext('Works with MultiRootFileSystem uris, asyncScanning: $asyncScanning', () async { final FileSystem fileSystem = MemoryFileSystem.test(); final FileSystem multiRootFileSystem = MultiRootFileSystem( @@ -187,7 +124,7 @@ void main() { Uri.parse('file:///file2'), Uri.parse('scheme:///file3'), ], - packagesPath: '.packages', + packagesPath: '.dart_tool/package_config.json', asyncScanning: asyncScanning, packageConfig: PackageConfig.empty, )).uris, diff --git a/packages/flutter_tools/test/src/test_flutter_command_runner.dart b/packages/flutter_tools/test/src/test_flutter_command_runner.dart index a29274f67b..9ce2dad4c1 100644 --- a/packages/flutter_tools/test/src/test_flutter_command_runner.dart +++ b/packages/flutter_tools/test/src/test_flutter_command_runner.dart @@ -35,8 +35,6 @@ Future createProject(Directory temp, { List? arguments }) async final CreateCommand command = CreateCommand(); final CommandRunner runner = createTestCommandRunner(command); await runner.run(['create', ...arguments, projectPath]); - // Create `.packages` since it's not created when the flag `--no-pub` is passed. - globals.fs.file(globals.fs.path.join(projectPath, '.packages')).createSync(); return projectPath; }