[Android] Actually remove dev dependencies from release builds (#161343)
Revises https://github.com/flutter/flutter/pull/158026 to fix https://github.com/flutter/flutter/issues/160407. Makes a number of fixes: - Fixes Groovy logic that attempted to remove dev dependencies from release builds to use `<buildType>Api` versus `api` and loop to configure the project dependencies per build type - Adds back dependency on embedding to plugin projects since this is needed regardless (the plugin may not be included in a particularly typed build but it still needs it for where it's included) - Fixes integration test to throw and error upon failure, check right APK for the release build it's testing, and configure the flag need for `.flutter-plugin-dependencies` to mark plugins as dev dependencies as expected - Uses @matanlurey's [patch](https://github.com/flutter/flutter/issues/160407#issuecomment-2547546038) to remove dev dependency from the `GeneratedPluginRegistrant` in release mode ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [ ] All existing and new tests are passing. <!-- Links --> [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
parent
0369b35640
commit
818133b8b0
@ -15,6 +15,9 @@ Future<void> main() async {
|
|||||||
await task(() async {
|
await task(() async {
|
||||||
try {
|
try {
|
||||||
await runProjectTest((FlutterProject flutterProject) async {
|
await runProjectTest((FlutterProject flutterProject) async {
|
||||||
|
// Enable plugins being marked as dev dependncies in the .flutter-plugins-dependencies file.
|
||||||
|
await flutter('config', options: <String>['--explicit-package-dependencies']);
|
||||||
|
|
||||||
// Create dev_dependency plugin to use for test.
|
// Create dev_dependency plugin to use for test.
|
||||||
final Directory tempDir = Directory.systemTemp.createTempSync(
|
final Directory tempDir = Directory.systemTemp.createTempSync(
|
||||||
'android_release_builds_exclude_dev_dependencies_test.',
|
'android_release_builds_exclude_dev_dependencies_test.',
|
||||||
@ -50,7 +53,7 @@ Future<void> main() async {
|
|||||||
'app',
|
'app',
|
||||||
'outputs',
|
'outputs',
|
||||||
'flutter-apk',
|
'flutter-apk',
|
||||||
'app-debug.apk',
|
'app-$buildMode.apk',
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (!apk.existsSync()) {
|
if (!apk.existsSync()) {
|
||||||
@ -66,7 +69,7 @@ Future<void> main() async {
|
|||||||
final bool apkIncludesDevDependencyAsExpected =
|
final bool apkIncludesDevDependencyAsExpected =
|
||||||
isTestingReleaseMode ? !apkIncludesDevDependency : apkIncludesDevDependency;
|
isTestingReleaseMode ? !apkIncludesDevDependency : apkIncludesDevDependency;
|
||||||
if (!apkIncludesDevDependencyAsExpected) {
|
if (!apkIncludesDevDependencyAsExpected) {
|
||||||
return TaskResult.failure(
|
throw TaskResult.failure(
|
||||||
'Expected to${isTestingReleaseMode ? ' not' : ''} find dev_dependency_plugin in APK built with debug mode but did${isTestingReleaseMode ? '' : ' not'}.',
|
'Expected to${isTestingReleaseMode ? ' not' : ''} find dev_dependency_plugin in APK built with debug mode but did${isTestingReleaseMode ? '' : ' not'}.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -738,13 +738,12 @@ class FlutterPlugin implements Plugin<Project> {
|
|||||||
// compile/target/min sdk values.
|
// compile/target/min sdk values.
|
||||||
pluginProject.extensions.create("flutter", FlutterExtension)
|
pluginProject.extensions.create("flutter", FlutterExtension)
|
||||||
|
|
||||||
// Add plugin dependency to the app project.
|
// Add plugin dependency to the app project. We only want to add dependency
|
||||||
project.android.buildTypes.each { buildType ->
|
// for dev dependencies in non-release builds.
|
||||||
String flutterBuildMode = buildModeFor(buildType)
|
project.afterEvaluate {
|
||||||
if (flutterBuildMode != "release" || !pluginObject.dev_dependency) {
|
project.android.buildTypes.all { buildType ->
|
||||||
// Only add dependency on dev dependencies in non-release builds.
|
if (!pluginObject.dev_dependency || buildType.name != 'release') {
|
||||||
project.dependencies {
|
project.dependencies.add("${buildType.name}Api", pluginProject)
|
||||||
api(pluginProject)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -760,12 +759,6 @@ class FlutterPlugin implements Plugin<Project> {
|
|||||||
if (!pluginProject.hasProperty("android")) {
|
if (!pluginProject.hasProperty("android")) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (flutterBuildMode == "release" && pluginObject.dev_dependency) {
|
|
||||||
// This plugin is a dev dependency and will not be included in
|
|
||||||
// the release build, so no need to add the embedding
|
|
||||||
// dependency to it.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
// Copy build types from the app to the plugin.
|
// Copy build types from the app to the plugin.
|
||||||
// This allows to build apps with plugins and custom build types or flavors.
|
// This allows to build apps with plugins and custom build types or flavors.
|
||||||
pluginProject.android.buildTypes {
|
pluginProject.android.buildTypes {
|
||||||
|
@ -356,18 +356,27 @@ public final class GeneratedPluginRegistrant {
|
|||||||
}
|
}
|
||||||
''';
|
''';
|
||||||
|
|
||||||
List<Map<String, Object?>> _extractPlatformMaps(List<Plugin> plugins, String type) {
|
List<Map<String, Object?>> _extractPlatformMaps(Iterable<Plugin> plugins, String type) {
|
||||||
return <Map<String, Object?>>[
|
return <Map<String, Object?>>[
|
||||||
for (final Plugin plugin in plugins)
|
for (final Plugin plugin in plugins)
|
||||||
if (plugin.platforms[type] case final PluginPlatform platformPlugin) platformPlugin.toMap(),
|
if (plugin.platforms[type] case final PluginPlatform platformPlugin) platformPlugin.toMap(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _writeAndroidPluginRegistrant(FlutterProject project, List<Plugin> plugins) async {
|
Future<void> _writeAndroidPluginRegistrant(
|
||||||
final List<Plugin> methodChannelPlugins = _filterMethodChannelPlugins(
|
FlutterProject project,
|
||||||
|
List<Plugin> plugins, {
|
||||||
|
required bool releaseMode,
|
||||||
|
}) async {
|
||||||
|
Iterable<Plugin> methodChannelPlugins = _filterMethodChannelPlugins(
|
||||||
plugins,
|
plugins,
|
||||||
AndroidPlugin.kConfigKey,
|
AndroidPlugin.kConfigKey,
|
||||||
);
|
);
|
||||||
|
// TODO(camsim99): Remove dev dependencies from release builds for all platforms. See https://github.com/flutter/flutter/issues/161348.
|
||||||
|
if (releaseMode) {
|
||||||
|
methodChannelPlugins = methodChannelPlugins.where((Plugin p) => !p.isDevDependency);
|
||||||
|
}
|
||||||
|
|
||||||
final List<Map<String, Object?>> androidPlugins = _extractPlatformMaps(
|
final List<Map<String, Object?>> androidPlugins = _extractPlatformMaps(
|
||||||
methodChannelPlugins,
|
methodChannelPlugins,
|
||||||
AndroidPlugin.kConfigKey,
|
AndroidPlugin.kConfigKey,
|
||||||
@ -1214,6 +1223,7 @@ Future<void> injectPlugins(
|
|||||||
bool windowsPlatform = false,
|
bool windowsPlatform = false,
|
||||||
Iterable<String>? allowedPlugins,
|
Iterable<String>? allowedPlugins,
|
||||||
DarwinDependencyManagement? darwinDependencyManagement,
|
DarwinDependencyManagement? darwinDependencyManagement,
|
||||||
|
bool? releaseMode,
|
||||||
}) async {
|
}) async {
|
||||||
final List<Plugin> plugins = await findPlugins(project);
|
final List<Plugin> plugins = await findPlugins(project);
|
||||||
final Map<String, List<Plugin>> pluginsByPlatform = _resolvePluginImplementations(
|
final Map<String, List<Plugin>> pluginsByPlatform = _resolvePluginImplementations(
|
||||||
@ -1222,7 +1232,11 @@ Future<void> injectPlugins(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (androidPlatform) {
|
if (androidPlatform) {
|
||||||
await _writeAndroidPluginRegistrant(project, pluginsByPlatform[AndroidPlugin.kConfigKey]!);
|
await _writeAndroidPluginRegistrant(
|
||||||
|
project,
|
||||||
|
pluginsByPlatform[AndroidPlugin.kConfigKey]!,
|
||||||
|
releaseMode: releaseMode ?? false,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (iosPlatform) {
|
if (iosPlatform) {
|
||||||
await _writeIOSPluginRegistrant(project, pluginsByPlatform[IOSPlugin.kConfigKey]!);
|
await _writeIOSPluginRegistrant(project, pluginsByPlatform[IOSPlugin.kConfigKey]!);
|
||||||
|
@ -332,6 +332,7 @@ class FlutterProject {
|
|||||||
Future<void> regeneratePlatformSpecificTooling({
|
Future<void> regeneratePlatformSpecificTooling({
|
||||||
DeprecationBehavior deprecationBehavior = DeprecationBehavior.none,
|
DeprecationBehavior deprecationBehavior = DeprecationBehavior.none,
|
||||||
Iterable<String>? allowedPlugins,
|
Iterable<String>? allowedPlugins,
|
||||||
|
bool? releaseMode,
|
||||||
}) async {
|
}) async {
|
||||||
return ensureReadyForPlatformSpecificTooling(
|
return ensureReadyForPlatformSpecificTooling(
|
||||||
androidPlatform: android.existsSync(),
|
androidPlatform: android.existsSync(),
|
||||||
@ -344,6 +345,7 @@ class FlutterProject {
|
|||||||
webPlatform: featureFlags.isWebEnabled && web.existsSync(),
|
webPlatform: featureFlags.isWebEnabled && web.existsSync(),
|
||||||
deprecationBehavior: deprecationBehavior,
|
deprecationBehavior: deprecationBehavior,
|
||||||
allowedPlugins: allowedPlugins,
|
allowedPlugins: allowedPlugins,
|
||||||
|
releaseMode: releaseMode,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,6 +360,7 @@ class FlutterProject {
|
|||||||
bool webPlatform = false,
|
bool webPlatform = false,
|
||||||
DeprecationBehavior deprecationBehavior = DeprecationBehavior.none,
|
DeprecationBehavior deprecationBehavior = DeprecationBehavior.none,
|
||||||
Iterable<String>? allowedPlugins,
|
Iterable<String>? allowedPlugins,
|
||||||
|
bool? releaseMode,
|
||||||
}) async {
|
}) async {
|
||||||
if (!directory.existsSync() || isPlugin) {
|
if (!directory.existsSync() || isPlugin) {
|
||||||
return;
|
return;
|
||||||
@ -389,6 +392,7 @@ class FlutterProject {
|
|||||||
macOSPlatform: macOSPlatform,
|
macOSPlatform: macOSPlatform,
|
||||||
windowsPlatform: windowsPlatform,
|
windowsPlatform: windowsPlatform,
|
||||||
allowedPlugins: allowedPlugins,
|
allowedPlugins: allowedPlugins,
|
||||||
|
releaseMode: releaseMode,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1907,7 +1907,10 @@ Run 'flutter -h' (or 'flutter <command> -h') for available flutter commands and
|
|||||||
// The preview device does not currently support any plugins.
|
// The preview device does not currently support any plugins.
|
||||||
allowedPlugins = PreviewDevice.supportedPubPlugins;
|
allowedPlugins = PreviewDevice.supportedPubPlugins;
|
||||||
}
|
}
|
||||||
await project.regeneratePlatformSpecificTooling(allowedPlugins: allowedPlugins);
|
await project.regeneratePlatformSpecificTooling(
|
||||||
|
allowedPlugins: allowedPlugins,
|
||||||
|
releaseMode: featureFlags.isExplicitPackageDependenciesEnabled && getBuildMode().isRelease,
|
||||||
|
);
|
||||||
if (reportNullSafety) {
|
if (reportNullSafety) {
|
||||||
await _sendNullSafetyAnalyticsEvents(project);
|
await _sendNullSafetyAnalyticsEvents(project);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user