Skip to content

Commit 2f72db6

Browse files
auto-submit[bot]auto-submit[bot]
andauthored
Reverts "Convert the Flutter Gradle Plugin entirely to Kotlin source (flutter#166114)" (flutter#166666)
<!-- start_original_pr_link --> Reverts: flutter#166114 <!-- end_original_pr_link --> <!-- start_initiating_author --> Initiated by: gmackall <!-- end_initiating_author --> <!-- start_revert_reason --> Reason for reverting: a failing postsubmit <!-- end_revert_reason --> <!-- start_original_pr_author --> Original PR Author: gmackall <!-- end_original_pr_author --> <!-- start_reviewers --> Reviewed By: {bartekpacia, reidbaker} <!-- end_reviewers --> <!-- start_revert_body --> This change reverts the following previous change: Finishes the conversion of the Flutter Gradle plugin from Groovy to Kotlin. Fixes flutter#121541. Fixes flutter#166287. ## 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. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. <!-- 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 <!-- end_revert_body --> Co-authored-by: auto-submit[bot] <[email protected]>
1 parent b281986 commit 2f72db6

26 files changed

+1121
-1745
lines changed

packages/flutter_tools/gradle/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ gradlePlugin {
3434
// The "flutterPlugin" name isn't used anywhere.
3535
create("flutterPlugin") {
3636
id = "dev.flutter.flutter-gradle-plugin"
37-
implementationClass = "com.flutter.gradle.FlutterPlugin"
37+
implementationClass = "FlutterPlugin"
3838
}
3939
// The "flutterAppPluginLoaderPlugin" name isn't used anywhere.
4040
create("flutterAppPluginLoaderPlugin") {

packages/flutter_tools/gradle/src/main/groovy/flutter.groovy

Lines changed: 722 additions & 0 deletions
Large diffs are not rendered by default.

packages/flutter_tools/gradle/src/main/kotlin/tasks/BaseFlutterTask.kt renamed to packages/flutter_tools/gradle/src/main/kotlin/BaseFlutterTask.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
package com.flutter.gradle.tasks
5+
package com.flutter.gradle
66

77
import org.gradle.api.DefaultTask
88
import org.gradle.api.tasks.Input

packages/flutter_tools/gradle/src/main/kotlin/tasks/BaseFlutterTaskHelper.kt renamed to packages/flutter_tools/gradle/src/main/kotlin/BaseFlutterTaskHelper.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
package com.flutter.gradle.tasks
5+
package com.flutter.gradle
66

77
import androidx.annotation.VisibleForTesting
88
import org.gradle.api.Action

packages/flutter_tools/gradle/src/main/kotlin/FlutterPlugin.kt

Lines changed: 0 additions & 741 deletions
This file was deleted.

packages/flutter_tools/gradle/src/main/kotlin/FlutterPluginConstants.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ object FlutterPluginConstants {
2525
const val INTERMEDIATES_DIR = "intermediates"
2626
const val FLUTTER_STORAGE_BASE_URL = "FLUTTER_STORAGE_BASE_URL"
2727
const val DEFAULT_MAVEN_HOST = "https://storage.googleapis.com"
28+
const val WEBSITE_DEPLOYMENT_ANDROID_BUILD_CONFIG = "https://flutter.dev/to/review-gradle-config"
2829

2930
/** Maps platforms to ABI architectures. */
3031
@JvmStatic val PLATFORM_ARCH_MAP =
@@ -41,7 +42,7 @@ object FlutterPluginConstants {
4142
* Otherwise, the Play Store will complain that the APK variants have the same version.
4243
*/
4344
@JvmStatic val ABI_VERSION =
44-
mapOf<String, Int>(
45+
mapOf<String, Int>( // Explicit type for clarity, though inferred
4546
ARCH_ARM32 to 1,
4647
ARCH_ARM64 to 2,
4748
ARCH_X86 to 3,

packages/flutter_tools/gradle/src/main/kotlin/FlutterPluginUtils.kt

Lines changed: 157 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import com.android.build.gradle.api.ApplicationVariant
1010
import com.android.build.gradle.api.BaseVariantOutput
1111
import com.android.build.gradle.tasks.ProcessAndroidResources
1212
import com.android.builder.model.BuildType
13-
import com.flutter.gradle.plugins.PluginHandler
1413
import groovy.lang.Closure
1514
import groovy.util.Node
1615
import groovy.util.XmlParser
@@ -140,6 +139,19 @@ object FlutterPluginUtils {
140139

141140
// TODO(54566): Can remove this function and its call sites once resolved.
142141

142+
/**
143+
* Returns `true` if the given project is a plugin project having an `android` directory
144+
* containing a `build.gradle` or `build.gradle.kts` file.
145+
*/
146+
@JvmStatic
147+
@JvmName("pluginSupportsAndroidPlatform")
148+
internal fun pluginSupportsAndroidPlatform(project: Project): Boolean {
149+
val buildGradle = File(File(project.projectDir.parentFile, "android"), "build.gradle")
150+
val buildGradleKts =
151+
File(File(project.projectDir.parentFile, "android"), "build.gradle.kts")
152+
return buildGradle.exists() || buildGradleKts.exists()
153+
}
154+
143155
/**
144156
* Returns the Gradle settings script for the build. When both Groovy and
145157
* Kotlin variants exist, then Groovy (settings.gradle) is preferred over
@@ -394,7 +406,7 @@ object FlutterPluginUtils {
394406
return project.property(PROP_LOCAL_ENGINE_BUILD_MODE) == flutterBuildMode
395407
}
396408

397-
internal fun getAndroidExtension(project: Project): BaseExtension {
409+
private fun getAndroidExtension(project: Project): BaseExtension {
398410
// Common supertype of the android extension types.
399411
// But maybe this should be https://developer.android.com/reference/tools/gradle-api/8.7/com/android/build/api/dsl/TestedExtension.
400412
return project.extensions.findByType(BaseExtension::class.java)!!
@@ -599,7 +611,7 @@ object FlutterPluginUtils {
599611

600612
// Otherwise, point to an empty CMakeLists.txt, and ignore associated warnings.
601613
gradleProjectAndroidExtension.externalNativeBuild.cmake.path(
602-
"$flutterSdkRootPath/packages/flutter_tools/gradle/src/main/scripts/CMakeLists.txt"
614+
"$flutterSdkRootPath/packages/flutter_tools/gradle/src/main/groovy/CMakeLists.txt"
603615
)
604616

605617
// AGP defaults to outputting build artifacts in `android/app/.cxx`. This directory is a
@@ -644,7 +656,7 @@ object FlutterPluginUtils {
644656
internal fun addFlutterDependencies(
645657
project: Project,
646658
buildType: BuildType,
647-
pluginHandler: PluginHandler,
659+
pluginList: List<Map<String?, Any?>>,
648660
engineVersion: String
649661
) {
650662
val flutterBuildMode: String = buildModeFor(buildType)
@@ -664,9 +676,11 @@ object FlutterPluginUtils {
664676
// embedding.
665677
val pluginsThatIncludeFlutterEmbeddingAsTransitiveDependency: List<Map<String?, Any?>> =
666678
if (flutterBuildMode == "release") {
667-
pluginHandler.getPluginListWithoutDevDependencies()
679+
getPluginListWithoutDevDependencies(
680+
pluginList
681+
)
668682
} else {
669-
pluginHandler.getPluginList()
683+
pluginList
670684
}
671685

672686
if (!isFlutterAppProject(project) || pluginsThatIncludeFlutterEmbeddingAsTransitiveDependency.isEmpty()) {
@@ -688,6 +702,143 @@ object FlutterPluginUtils {
688702
}
689703
}
690704

705+
/**
706+
* Gets the list of plugins (as map) that support the Android platform and are dependencies of the
707+
* Android project excluding dev dependencies.
708+
*
709+
* The map value contains either the plugins `name` (String),
710+
* its `path` (String), or its `dependencies` (List<String>).
711+
* See [NativePluginLoader#getPlugins] in packages/flutter_tools/gradle/src/main/scripts/native_plugin_loader.gradle.kts
712+
*/
713+
private fun getPluginListWithoutDevDependencies(pluginList: List<Map<String?, Any?>>): List<Map<String?, Any?>> =
714+
pluginList.filter { pluginObject -> pluginObject["dev_dependency"] == false }
715+
716+
/**
717+
* Add the dependencies on other plugin projects to the plugin project.
718+
* A plugin A can depend on plugin B. As a result, this dependency must be surfaced by
719+
* making the Gradle plugin project A depend on the Gradle plugin project B.
720+
*/
721+
@JvmStatic
722+
@JvmName("configurePluginDependencies")
723+
internal fun configurePluginDependencies(
724+
project: Project,
725+
pluginObject: Map<String?, Any?>
726+
) {
727+
val pluginName: String =
728+
requireNotNull(pluginObject["name"] as? String) {
729+
"Missing valid \"name\" property for plugin object: $pluginObject"
730+
}
731+
val pluginProject: Project = project.rootProject.findProject(":$pluginName") ?: return
732+
733+
getAndroidExtension(project).buildTypes.forEach { buildType ->
734+
val flutterBuildMode: String = buildModeFor(buildType)
735+
if (flutterBuildMode == "release" && (pluginObject["dev_dependency"] as? Boolean == true)) {
736+
// This plugin is a dev dependency will not be included in the
737+
// release build, so no need to add its dependencies.
738+
return@forEach
739+
}
740+
val dependencies = requireNotNull(pluginObject["dependencies"] as? List<*>)
741+
dependencies.forEach innerForEach@{ pluginDependencyName ->
742+
check(pluginDependencyName is String)
743+
if (pluginDependencyName.isEmpty()) {
744+
return@innerForEach
745+
}
746+
747+
val dependencyProject =
748+
project.rootProject.findProject(":$pluginDependencyName") ?: return@innerForEach
749+
pluginProject.afterEvaluate {
750+
pluginProject.dependencies.add("implementation", dependencyProject)
751+
}
752+
}
753+
}
754+
}
755+
756+
/**
757+
* Performs configuration related to the plugin's Gradle [Project], including
758+
* 1. Adding the plugin itself as a dependency to the main project.
759+
* 2. Adding the main project's build types to the plugin's build types.
760+
* 3. Adding a dependency on the Flutter embedding to the plugin.
761+
*
762+
* Should only be called on plugins that support the Android platform.
763+
*/
764+
@JvmStatic
765+
@JvmName("configurePluginProject")
766+
internal fun configurePluginProject(
767+
project: Project,
768+
pluginObject: Map<String?, Any?>,
769+
engineVersion: String
770+
) {
771+
// TODO(gmackall): should guard this with a pluginObject.contains().
772+
val pluginName =
773+
requireNotNull(pluginObject["name"] as? String) { "Plugin name must be a string for plugin object: $pluginObject" }
774+
val pluginProject: Project = project.rootProject.findProject(":$pluginName") ?: return
775+
776+
// Apply the "flutter" Gradle extension to plugins so that they can use it's vended
777+
// compile/target/min sdk values.
778+
pluginProject.extensions.create("flutter", FlutterExtension::class.java)
779+
780+
// Add plugin dependency to the app project. We only want to add dependency
781+
// for dev dependencies in non-release builds.
782+
project.afterEvaluate {
783+
getAndroidExtension(project).buildTypes.forEach { buildType ->
784+
if (!(pluginObject["dev_dependency"] as Boolean) || buildType.name != "release") {
785+
project.dependencies.add("${buildType.name}Api", pluginProject)
786+
}
787+
}
788+
}
789+
790+
// Wait until the Android plugin loaded.
791+
pluginProject.afterEvaluate {
792+
// Checks if there is a mismatch between the plugin compileSdkVersion and the project compileSdkVersion.
793+
val projectCompileSdkVersion: String = getCompileSdkFromProject(project)
794+
val pluginCompileSdkVersion: String = getCompileSdkFromProject(pluginProject)
795+
// TODO(gmackall): This is doing a string comparison, which is odd and also can be wrong
796+
// when comparing preview versions (against non preview, and also in the
797+
// case of alphabet reset which happened with "Baklava".
798+
if (pluginCompileSdkVersion > projectCompileSdkVersion) {
799+
project.logger.quiet("Warning: The plugin $pluginName requires Android SDK version $pluginCompileSdkVersion or higher.")
800+
project.logger.quiet(
801+
"For more information about build configuration, see ${FlutterPluginConstants.WEBSITE_DEPLOYMENT_ANDROID_BUILD_CONFIG}."
802+
)
803+
}
804+
805+
getAndroidExtension(project).buildTypes.forEach { buildType ->
806+
addEmbeddingDependencyToPlugin(project, pluginProject, buildType, engineVersion)
807+
}
808+
}
809+
}
810+
811+
private fun addEmbeddingDependencyToPlugin(
812+
project: Project,
813+
pluginProject: Project,
814+
buildType: BuildType,
815+
engineVersion: String
816+
) {
817+
val flutterBuildMode: String = buildModeFor(buildType)
818+
// TODO(gmackall): this should be safe to remove, as the minimum required AGP is well above
819+
// 3.5. We should try to remove it.
820+
// In AGP 3.5, the embedding must be added as an API implementation,
821+
// so java8 features are desugared against the runtime classpath.
822+
// For more, see https://github.com/flutter/flutter/issues/40126
823+
if (!supportsBuildMode(pluginProject, flutterBuildMode)) {
824+
return
825+
}
826+
if (!pluginProject.hasProperty("android")) {
827+
return
828+
}
829+
830+
// Copy build types from the app to the plugin.
831+
// This allows to build apps with plugins and custom build types or flavors.
832+
getAndroidExtension(pluginProject).buildTypes.addAll(getAndroidExtension(project).buildTypes)
833+
834+
// The embedding is API dependency of the plugin, so the AGP is able to desugar
835+
// default method implementations when the interface is implemented by a plugin.
836+
//
837+
// See https://issuetracker.google.com/139821726, and
838+
// https://github.com/flutter/flutter/issues/72185 for more details.
839+
addApiDependencies(pluginProject, buildType.name, "io.flutter:flutter_embedding_$flutterBuildMode:$engineVersion")
840+
}
841+
691842
// ------------------ Task adders (a subset of the above category)
692843

693844
// Add a task that can be called on flutter projects that prints the Java version used in Gradle.

packages/flutter_tools/gradle/src/main/kotlin/tasks/FlutterTask.kt renamed to packages/flutter_tools/gradle/src/main/kotlin/FlutterTask.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
package com.flutter.gradle.tasks
5+
package com.flutter.gradle
66

77
import org.gradle.api.file.CopySpec
88
import org.gradle.api.file.FileCollection

packages/flutter_tools/gradle/src/main/kotlin/tasks/FlutterTaskHelper.kt renamed to packages/flutter_tools/gradle/src/main/kotlin/FlutterTaskHelper.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file.
44

5-
package com.flutter.gradle.tasks
5+
package com.flutter.gradle
66

7-
import com.flutter.gradle.FlutterPluginConstants
87
import org.gradle.api.Project
98
import org.gradle.api.file.CopySpec
109
import org.gradle.api.file.FileCollection

0 commit comments

Comments
 (0)