Reland "Load parent package config" (#153754)

Reverts flutter/flutter#153752
Relands https://github.com/flutter/flutter/pull/150850

Now with attached g3fix
This commit is contained in:
Sigurd Meldgaard 2024-08-20 15:30:46 +02:00 committed by GitHub
parent 990b80aafd
commit a9daf58829
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
55 changed files with 615 additions and 393 deletions

View File

@ -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<void> writeAssetFile(libfs.File outputFile, AssetBundleEntry asset) async
Future<void> run(List<String> 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<void> run(List<String> 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.
);

View File

@ -125,7 +125,7 @@ abstract class AssetBundle {
/// Returns 0 for success; non-zero for failure.
Future<int> 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<int> 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,

View File

@ -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.

View File

@ -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(),

View File

@ -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<Depfile> 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,

View File

@ -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,

View File

@ -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<Source> get inputs => <Source>[
const Source.pattern('{PROJECT_DIR}/.dart_tool/package_config_subset'),
const Source.pattern('{WORKSPACE_DIR}/.dart_tool/package_config_subset'),
];
@override

View File

@ -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<Source> get inputs => const <Source>[
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
];

View File

@ -54,10 +54,10 @@ class WebEntrypointTarget extends Target {
Future<void> 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',

View File

@ -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<AssetBundle?> 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,
);

View File

@ -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(),

View File

@ -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(),

View File

@ -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(),

View File

@ -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,

View File

@ -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);

View File

@ -571,6 +571,7 @@ abstract class CreateBase extends FlutterCommand {
usage: globals.flutterUsage,
analytics: globals.analytics,
projectDir: project.directory,
packageConfigPath: packageConfigPath(),
generateDartPluginRegistry: true,
);

View File

@ -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,
);

View File

@ -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.

View File

@ -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) {

View File

@ -16,6 +16,46 @@ Future<PackageConfig> 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.
///

View File

@ -258,21 +258,58 @@ 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'));
// 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 (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 = _fileSystem.file(
_fileSystem.path.join(directory, 'pubspec.lock')
);
final File pubLockFile = workspaceRoot.childFile('pubspec.lock');
if (shouldSkipThirdPartyGenerator && project.packageConfigFile.existsSync()) {
if (shouldSkipThirdPartyGenerator) {
Map<String, Object?> packageConfigMap;
try {
packageConfigMap = jsonDecode(
project.packageConfigFile.readAsStringSync(),
packageConfigMap = jsonDecode(packageConfigFile.readAsStringSync(),
) as Map<String, Object?>;
} on FormatException {
packageConfigMap = <String, Object?>{};
@ -294,7 +331,6 @@ class _DefaultPub implements Pub {
// 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()) &&
@ -303,6 +339,7 @@ class _DefaultPub implements Pub {
_logger.printTrace('Skipping pub get: version match.');
return;
}
}
final String command = upgrade ? 'upgrade' : 'get';
final bool verbose = _logger.isVerbose;
@ -645,19 +682,24 @@ class _DefaultPub implements Pub {
/// This should be called after pub invocations that are expected to update
/// the packageConfig.
Future<void> _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<void> _updatePackageConfig(FlutterProject project) async {
final File packageConfigFile = project.packageConfigFile;
Future<void> _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;
}

View File

@ -82,12 +82,9 @@ Future<Plugin?> _pluginFromPackage(String name, Uri packageRoot, Set<String> app
Future<List<Plugin>> findPlugins(FlutterProject project, { bool throwOnError = true}) async {
final List<Plugin> plugins = <Plugin>[];
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,
);

View File

@ -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<FlutterDevice> flutterDevices,
required String packageConfigPath,
required PackageConfig packageConfig,
required Logger logger,
}) async {
final NativeAssetsBuildRunner buildRunner = NativeAssetsBuildRunnerImpl(
projectUri,
packageConfigPath,
packageConfig,
fileSystem,
globals.logger,

View File

@ -32,6 +32,7 @@ Future<Uri?> testCompilerBuildNativeAssets(BuildInfo buildInfo) async {
final Uri projectUri = FlutterProject.current().directory.uri;
final NativeAssetsBuildRunner buildRunner = NativeAssetsBuildRunnerImpl(
projectUri,
buildInfo.packageConfigPath,
buildInfo.packageConfig,
globals.fs,
globals.logger,

View File

@ -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) {

View File

@ -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');

View File

@ -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: <String, String>{
// Needed for Dart plugin registry generation.

View File

@ -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<PackageConfig> _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<FlutterDevice> flutterDevices,
required String packageConfigPath,
required PackageConfig packageConfig,
required Logger logger,
});

View File

@ -1083,15 +1083,19 @@ abstract class FlutterCommand extends Command<void> {
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<bool> modeFlags = <bool>[
debugResult,
profileResult,
jitReleaseResult,
boolArg('profile'),
releaseResult,
];
if (modeFlags.where((bool flag) => flag).length > 1) {
@ -1101,7 +1105,7 @@ abstract class FlutterCommand extends Command<void> {
if (debugResult) {
return BuildMode.debug;
}
if (boolArg('profile')) {
if (profileResult) {
return BuildMode.profile;
}
if (releaseResult) {
@ -1184,6 +1188,19 @@ abstract class FlutterCommand extends Command<void> {
/// 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<void> {
? 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 <command> -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<String>? allowedPlugins;
if (stringArg(FlutterGlobalOptions.kDeviceIdOption, global: true) == 'preview') {

View File

@ -125,8 +125,7 @@ class LocalEngineLocator {
Future<String?> _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,

View File

@ -102,6 +102,7 @@ class WebBuilder {
kServiceWorkerStrategy: serviceWorkerStrategy.cliName,
...buildInfo.toBuildSystemEnvironment(),
},
packageConfigPath: buildInfo.packageConfigPath,
artifacts: globals.artifacts!,
fileSystem: _fileSystem,
logger: _logger,

View File

@ -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);
}

View File

@ -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>[
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);

View File

@ -117,8 +117,9 @@ void main() {
await commandRunner.run(<String>['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: <Type, Generator>{
Pub: () => pub,
ProcessManager: () => FakeProcessManager.any(),

View File

@ -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>[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(

View File

@ -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: <String>['--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<String, Object?> pubspec = <String, Object?>{
...pubspecYaml.value.cast<String, Object?>(),
'resolution': 'workspace',
'environment': <String, Object?>{
...(pubspecYaml['environment'] as YamlMap).value.cast<String, Object?>(),
'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: <Type, Generator>{
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: <String>['--no-pub', '--template=module']);

View File

@ -32,7 +32,7 @@ void main() {
);
await bundle.build(
packagesPath: '.packages',
packageConfigPath: '.packages',
flutterProject: FlutterProject.fromDirectoryTest(fileSystem.currentDirectory),
flavor: flavor,
);

View File

@ -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(<String>['AssetManifest.bin',
'AssetManifest.json', 'FontManifest.json', 'NOTICES.Z']));
}, overrides: <Type, Generator>{

View File

@ -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(
<String>['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(
<String>['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: <Type, Generator>{
FileSystem: () => testFileSystem,
ProcessManager: () => FakeProcessManager.any(),

View File

@ -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: <Type, Generator>{
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(<String>['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(<String>[
'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(<String>['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(<String>['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(<String>['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(<String>['AssetManifest.json',
'AssetManifest.bin', 'FontManifest.json', 'NOTICES.Z', 'assets/foo/bar.txt']));
}, overrides: <Type, Generator>{
@ -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(<String>['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(<String>['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(<String>['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(<String>['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(<String>['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(<String>[
@ -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(<String>[
@ -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: <Type, Generator>{
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: <Type, Generator>{
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: <Type, Generator>{
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(<String>['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: <Type, Generator>{
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: <Type, Generator>{
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(<String>['assets/foo.txt',
'AssetManifest.json', 'AssetManifest.bin', 'FontManifest.json', 'NOTICES.Z']));
}, overrides: <Type, Generator>{
@ -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

View File

@ -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),
);

View File

@ -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),
);

View File

@ -33,7 +33,7 @@ const List<String> _kDart2WasmLinuxArgs = <String> [
'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,
]

View File

@ -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<String, Object?> packageConfig =
jsonDecode(packageConfigFile.readAsStringSync()) as Map<String, Object?>;
(packageConfig['packages']! as List<Object?>).add(<String, Object?>{
'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<String, String> plugins,
) {
final Directory fakePubCache = fs.systemTempDirectory.childDirectory('cache');
final File packagesFile = flutterProject.directory
.childFile('.packages');
if (packagesFile.existsSync()) {
packagesFile.deleteSync();
flutterProject.directory
.childDirectory('.dart_tool')
.childFile('package_config.json')
..deleteSync(recursive: true)
..createSync(recursive: true)
..writeAsStringSync('''
{
"packages": [],
"configVersion": 2
}
packagesFile.createSync(recursive: true);
''');
for (final MapEntry<String, String> 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);

View File

@ -948,7 +948,7 @@ class FakeBundle extends AssetBundle {
Future<int> build({
String manifestPath = defaultManifestPath,
String? assetDirPath,
String? packagesPath,
String? packageConfigPath,
bool deferredComponentsEnabled = false,
TargetPlatform? targetPlatform,
String? flavor,

View File

@ -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<String, Object?> packageConfig =
jsonDecode(packageConfigFile.readAsStringSync()) as Map<String, Object?>;
(packageConfig['packages']! as List<Object?>).add(<String, Object?>{
'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));

View File

@ -165,6 +165,7 @@ class FakeHotRunnerNativeAssetsBuilder implements HotRunnerNativeAssetsBuilder {
required Uri projectUri,
required FileSystem fileSystem,
required List<FlutterDevice> flutterDevices,
required String packageConfigPath,
required PackageConfig packageConfig,
required Logger logger,
}) {

View File

@ -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'));
});

View File

@ -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,

View File

@ -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,

View File

@ -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<String, Object?> packageConfig = <String, Object?>{
'packages': <Object?>[],
'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<Object?>).add(<String, Object?>{
'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', () {

View File

@ -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');

View File

@ -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<String, Object?> packageConfig =
jsonDecode(packageConfigFile.readAsStringSync()) as Map<String, Object?>;
(packageConfig['packages']! as List<Object?>).add(<String, Object?>{
'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<Directory> directories = <Directory>[];
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, <String>['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);

View File

@ -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: <Uri>[],
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: <Uri>[],
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>[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(<String, Object>{
'configVersion': 2,
'packages': <Object>[],
}));
final InvalidationResult invalidationResult = await projectFileInvalidator.findInvalidated(
lastCompiled: null,
urisToMonitor: <Uri>[],
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: <Uri>[],
packagesPath: '.packages',
asyncScanning: asyncScanning,
packageConfig: packageConfig,
);
expect(secondInvalidation.uris, unorderedEquals(<Uri>[
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: <Uri>[],
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: <Uri>[],
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,

View File

@ -35,8 +35,6 @@ Future<String> createProject(Directory temp, { List<String>? arguments }) async
final CreateCommand command = CreateCommand();
final CommandRunner<void> runner = createTestCommandRunner(command);
await runner.run(<String>['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;
}