From 46969e531b9026346aa923b5479cf3c2f19f0195 Mon Sep 17 00:00:00 2001 From: Matan Lurey Date: Tue, 25 Mar 2025 07:54:22 -0700 Subject: [PATCH] Allow `generate: true` as long as synthetic packages are not being used. (#165838) Closes https://github.com/flutter/flutter/issues/164864. --- packages/flutter_tools/lib/src/dart/pub.dart | 27 ++--- .../test/general.shard/dart/pub_get_test.dart | 109 +++++++++++++++++- 2 files changed, 121 insertions(+), 15 deletions(-) diff --git a/packages/flutter_tools/lib/src/dart/pub.dart b/packages/flutter_tools/lib/src/dart/pub.dart index 5455d41fd7..5d01157463 100644 --- a/packages/flutter_tools/lib/src/dart/pub.dart +++ b/packages/flutter_tools/lib/src/dart/pub.dart @@ -19,6 +19,7 @@ import '../base/process.dart'; import '../cache.dart'; import '../convert.dart'; import '../dart/package_map.dart'; +import '../features.dart'; import '../project.dart'; import '../version.dart'; @@ -760,24 +761,24 @@ class _DefaultPub implements Pub { .childFile('package_config_subset') .writeAsStringSync(_computePackageConfigSubset(packageConfig, _fileSystem)); - // TODO(matanlurey): Remove this once flutter_gen is removed. - // - // This is actually incorrect logic; the presence of a `generate: true` - // does *NOT* mean that we need to add `flutter_gen` to the package config, - // and never did, but the name of the manifest field was labeled and - // described incorrectly. - // - // Tracking removal: https://github.com/flutter/flutter/issues/102983. + // If we aren't generating localizations, short-circuit. if (!project.manifest.generateLocalizations) { return; } - // TODO(matanlurey): Remove this once flutter_gen is removed. - // - // See https://github.com/dart-lang/pub/issues/4471. - if (!_fileSystem.path.equals(packageConfigFile.parent.parent.path, project.directory.path)) { - throwToolExit('`generate: true` is not supported within workspaces.'); + // Workaround for https://github.com/flutter/flutter/issues/164864. + // If this flag is set, synthetic packages cannot be used, so we short-circut. + if (featureFlags.isExplicitPackageDependenciesEnabled) { + return; } + + if (!_fileSystem.path.equals(packageConfigFile.parent.parent.path, project.directory.path)) { + throwToolExit( + '`generate: true` is not supported within workspaces unless flutter config ' + '--explicit-package-dependencies is set.', + ); + } + if (packageConfig.packages.any((Package package) => package.name == 'flutter_gen')) { return; } diff --git a/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart b/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart index 365102fb21..e379bd3e7a 100644 --- a/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart +++ b/packages/flutter_tools/test/general.shard/dart/pub_get_test.dart @@ -12,9 +12,11 @@ import 'package:flutter_tools/src/base/platform.dart'; import 'package:flutter_tools/src/cache.dart'; import 'package:flutter_tools/src/convert.dart'; import 'package:flutter_tools/src/dart/pub.dart'; +import 'package:flutter_tools/src/features.dart'; import 'package:flutter_tools/src/project.dart'; import '../../src/common.dart'; +import '../../src/context.dart'; import '../../src/fake_process_manager.dart'; import '../../src/fakes.dart'; import '../../src/package_config.dart'; @@ -986,7 +988,7 @@ exit code: 66 expect(processManager, hasNoRemainingExpectations); }); - testWithoutContext( + testUsingContext( 'package_config_subset file is generated from packages and not timestamp', () async { final FileSystem fileSystem = MemoryFileSystem.test(); @@ -1001,7 +1003,12 @@ exit code: 66 ), ); fileSystem.file('version').createSync(); - fileSystem.file('pubspec.yaml').createSync(); + fileSystem.file('pubspec.yaml') + ..createSync() + ..writeAsStringSync(''' + flutter: + generate: true + '''); fileSystem.file('.dart_tool/package_config.json') ..createSync(recursive: true) ..writeAsStringSync(''' @@ -1029,6 +1036,104 @@ exit code: 66 '2\n', ); }, + overrides: { + // ignore: avoid_redundant_argument_values + FeatureFlags: () => TestFeatureFlags(isExplicitPackageDependenciesEnabled: false), + }, + ); + + testUsingContext( + 'cannot use `generate: true` with a workspace without --explicit-package-dependencies', + () async { + final FileSystem fileSystem = MemoryFileSystem.test(); + final Pub pub = Pub.test( + fileSystem: fileSystem, + logger: BufferLogger.test(), + processManager: FakeProcessManager.any(), + botDetector: const FakeBotDetector(false), + stdio: FakeStdio(), + platform: FakePlatform( + environment: const {'PUB_CACHE': 'custom/pub-cache/path'}, + ), + ); + + final Directory pkg = fileSystem.directory('workspace_pkg')..createSync(recursive: true); + fileSystem.file('version').createSync(); + pkg.childFile('pubspec.yaml') + ..createSync() + ..writeAsStringSync(''' + flutter: + generate: true + '''); + fileSystem.file('.dart_tool/package_config.json') + ..createSync(recursive: true) + ..writeAsStringSync(''' + {"configVersion": 2,"packages": [ + { + "name": "flutter_tools", + "rootUri": "../", + "packageUri": "lib/", + "languageVersion": "2.7" + } + ],"generated":"some-time"} +'''); + + await expectLater( + pub.get(project: FlutterProject.fromDirectoryTest(pkg), context: PubContext.flutterTests), + throwsToolExit(message: '`generate: true` is not supported within workspaces unless'), + ); + }, + overrides: { + // ignore: avoid_redundant_argument_values + FeatureFlags: () => TestFeatureFlags(isExplicitPackageDependenciesEnabled: false), + }, + ); + + testUsingContext( + 'can use `generate: true` with a workspace with --explicit-package-dependencies', + () async { + final FileSystem fileSystem = MemoryFileSystem.test(); + final Pub pub = Pub.test( + fileSystem: fileSystem, + logger: BufferLogger.test(), + processManager: FakeProcessManager.any(), + botDetector: const FakeBotDetector(false), + stdio: FakeStdio(), + platform: FakePlatform( + environment: const {'PUB_CACHE': 'custom/pub-cache/path'}, + ), + ); + + final Directory pkg = fileSystem.directory('workspace_pkg')..createSync(recursive: true); + fileSystem.file('version').createSync(); + pkg.childFile('pubspec.yaml') + ..createSync() + ..writeAsStringSync(''' + flutter: + generate: true + '''); + fileSystem.file('.dart_tool/package_config.json') + ..createSync(recursive: true) + ..writeAsStringSync(''' + {"configVersion": 2,"packages": [ + { + "name": "flutter_tools", + "rootUri": "../", + "packageUri": "lib/", + "languageVersion": "2.7" + } + ],"generated":"some-time"} +'''); + + await expectLater( + pub.get(project: FlutterProject.fromDirectoryTest(pkg), context: PubContext.flutterTests), + completes, + ); + }, + overrides: { + // ignore: avoid_redundant_argument_values + FeatureFlags: () => TestFeatureFlags(isExplicitPackageDependenciesEnabled: true), + }, ); testWithoutContext('Pub error handling', () async {