[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 {
|
||||
try {
|
||||
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.
|
||||
final Directory tempDir = Directory.systemTemp.createTempSync(
|
||||
'android_release_builds_exclude_dev_dependencies_test.',
|
||||
@ -50,7 +53,7 @@ Future<void> main() async {
|
||||
'app',
|
||||
'outputs',
|
||||
'flutter-apk',
|
||||
'app-debug.apk',
|
||||
'app-$buildMode.apk',
|
||||
),
|
||||
);
|
||||
if (!apk.existsSync()) {
|
||||
@ -66,7 +69,7 @@ Future<void> main() async {
|
||||
final bool apkIncludesDevDependencyAsExpected =
|
||||
isTestingReleaseMode ? !apkIncludesDevDependency : apkIncludesDevDependency;
|
||||
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'}.',
|
||||
);
|
||||
}
|
||||
|
@ -738,13 +738,12 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
// compile/target/min sdk values.
|
||||
pluginProject.extensions.create("flutter", FlutterExtension)
|
||||
|
||||
// Add plugin dependency to the app project.
|
||||
project.android.buildTypes.each { buildType ->
|
||||
String flutterBuildMode = buildModeFor(buildType)
|
||||
if (flutterBuildMode != "release" || !pluginObject.dev_dependency) {
|
||||
// Only add dependency on dev dependencies in non-release builds.
|
||||
project.dependencies {
|
||||
api(pluginProject)
|
||||
// Add plugin dependency to the app project. We only want to add dependency
|
||||
// for dev dependencies in non-release builds.
|
||||
project.afterEvaluate {
|
||||
project.android.buildTypes.all { buildType ->
|
||||
if (!pluginObject.dev_dependency || buildType.name != 'release') {
|
||||
project.dependencies.add("${buildType.name}Api", pluginProject)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -760,12 +759,6 @@ class FlutterPlugin implements Plugin<Project> {
|
||||
if (!pluginProject.hasProperty("android")) {
|
||||
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.
|
||||
// This allows to build apps with plugins and custom build types or flavors.
|
||||
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?>>[
|
||||
for (final Plugin plugin in plugins)
|
||||
if (plugin.platforms[type] case final PluginPlatform platformPlugin) platformPlugin.toMap(),
|
||||
];
|
||||
}
|
||||
|
||||
Future<void> _writeAndroidPluginRegistrant(FlutterProject project, List<Plugin> plugins) async {
|
||||
final List<Plugin> methodChannelPlugins = _filterMethodChannelPlugins(
|
||||
Future<void> _writeAndroidPluginRegistrant(
|
||||
FlutterProject project,
|
||||
List<Plugin> plugins, {
|
||||
required bool releaseMode,
|
||||
}) async {
|
||||
Iterable<Plugin> methodChannelPlugins = _filterMethodChannelPlugins(
|
||||
plugins,
|
||||
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(
|
||||
methodChannelPlugins,
|
||||
AndroidPlugin.kConfigKey,
|
||||
@ -1214,6 +1223,7 @@ Future<void> injectPlugins(
|
||||
bool windowsPlatform = false,
|
||||
Iterable<String>? allowedPlugins,
|
||||
DarwinDependencyManagement? darwinDependencyManagement,
|
||||
bool? releaseMode,
|
||||
}) async {
|
||||
final List<Plugin> plugins = await findPlugins(project);
|
||||
final Map<String, List<Plugin>> pluginsByPlatform = _resolvePluginImplementations(
|
||||
@ -1222,7 +1232,11 @@ Future<void> injectPlugins(
|
||||
);
|
||||
|
||||
if (androidPlatform) {
|
||||
await _writeAndroidPluginRegistrant(project, pluginsByPlatform[AndroidPlugin.kConfigKey]!);
|
||||
await _writeAndroidPluginRegistrant(
|
||||
project,
|
||||
pluginsByPlatform[AndroidPlugin.kConfigKey]!,
|
||||
releaseMode: releaseMode ?? false,
|
||||
);
|
||||
}
|
||||
if (iosPlatform) {
|
||||
await _writeIOSPluginRegistrant(project, pluginsByPlatform[IOSPlugin.kConfigKey]!);
|
||||
|
@ -332,6 +332,7 @@ class FlutterProject {
|
||||
Future<void> regeneratePlatformSpecificTooling({
|
||||
DeprecationBehavior deprecationBehavior = DeprecationBehavior.none,
|
||||
Iterable<String>? allowedPlugins,
|
||||
bool? releaseMode,
|
||||
}) async {
|
||||
return ensureReadyForPlatformSpecificTooling(
|
||||
androidPlatform: android.existsSync(),
|
||||
@ -344,6 +345,7 @@ class FlutterProject {
|
||||
webPlatform: featureFlags.isWebEnabled && web.existsSync(),
|
||||
deprecationBehavior: deprecationBehavior,
|
||||
allowedPlugins: allowedPlugins,
|
||||
releaseMode: releaseMode,
|
||||
);
|
||||
}
|
||||
|
||||
@ -358,6 +360,7 @@ class FlutterProject {
|
||||
bool webPlatform = false,
|
||||
DeprecationBehavior deprecationBehavior = DeprecationBehavior.none,
|
||||
Iterable<String>? allowedPlugins,
|
||||
bool? releaseMode,
|
||||
}) async {
|
||||
if (!directory.existsSync() || isPlugin) {
|
||||
return;
|
||||
@ -389,6 +392,7 @@ class FlutterProject {
|
||||
macOSPlatform: macOSPlatform,
|
||||
windowsPlatform: windowsPlatform,
|
||||
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.
|
||||
allowedPlugins = PreviewDevice.supportedPubPlugins;
|
||||
}
|
||||
await project.regeneratePlatformSpecificTooling(allowedPlugins: allowedPlugins);
|
||||
await project.regeneratePlatformSpecificTooling(
|
||||
allowedPlugins: allowedPlugins,
|
||||
releaseMode: featureFlags.isExplicitPackageDependenciesEnabled && getBuildMode().isRelease,
|
||||
);
|
||||
if (reportNullSafety) {
|
||||
await _sendNullSafetyAnalyticsEvents(project);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user