[FGP conversion] Port FlutterExtension from Groovy to Kotlin (#165143)

Ports `FlutterExtension` from groovy to kotlin.

Fixes https://github.com/flutter/flutter/issues/162105

## 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

---------

Co-authored-by: Gray Mackall <mackall@google.com>
This commit is contained in:
Gray Mackall 2025-03-13 16:10:24 -07:00 committed by GitHub
parent c2bb3accba
commit 6806015866
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 119 additions and 71 deletions

View File

@ -13,6 +13,7 @@ import com.android.builder.model.BuildType
import com.flutter.gradle.BaseApplicationNameHandler
import com.flutter.gradle.Deeplink
import com.flutter.gradle.DependencyVersionChecker
import com.flutter.gradle.FlutterExtension
import com.flutter.gradle.IntentFilterCheck
import com.flutter.gradle.VersionUtils
import groovy.xml.QName
@ -42,77 +43,6 @@ import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.Jar
import org.gradle.internal.os.OperatingSystem
/**
* For apps only. Provides the flutter extension used in the app-level Gradle
* build file (app/build.gradle or app/build.gradle.kts).
*
* The versions specified here should match the values in
* packages/flutter_tools/lib/src/android/gradle_utils.dart, so when bumping,
* make sure to update the versions specified there.
*
* Learn more about extensions in Gradle:
* * https://docs.gradle.org/8.0.2/userguide/custom_plugins.html#sec:getting_input_from_the_build
*/
class FlutterExtension {
/** Sets the compileSdkVersion used by default in Flutter app projects. */
public final int compileSdkVersion = 35
/** Sets the minSdkVersion used by default in Flutter app projects. */
public final int minSdkVersion = 21
/**
* Sets the targetSdkVersion used by default in Flutter app projects.
* targetSdkVersion should always be the latest available stable version.
*
* See https://developer.android.com/guide/topics/manifest/uses-sdk-element.
*/
public final int targetSdkVersion = 35
/**
* Sets the ndkVersion used by default in Flutter app projects.
* Chosen as default version of the AGP version below as found in
* https://developer.android.com/studio/projects/install-ndk#default-ndk-per-agp.
*/
public final String ndkVersion = "26.3.11579264"
/**
* Specifies the relative directory to the Flutter project directory.
* In an app project, this is ../.. since the app's Gradle build file is under android/app.
*/
String source = "../.."
/** Allows to override the target file. Otherwise, the target is lib/main.dart. */
String target
/** The versionCode that was read from app's local.properties. */
public String flutterVersionCode = null
/** The versionName that was read from app's local.properties. */
public String flutterVersionName = null
/** Returns flutterVersionCode as an integer with error handling. */
Integer getVersionCode() {
if (flutterVersionCode == null) {
throw new GradleException("flutterVersionCode must not be null.")
}
if (!flutterVersionCode.isNumber()) {
throw new GradleException("flutterVersionCode must be an integer.")
}
return flutterVersionCode.toInteger()
}
/** Returns flutterVersionName with error handling. */
String getVersionName() {
if (flutterVersionName == null) {
throw new GradleException("flutterVersionName must not be null.")
}
return flutterVersionName
}
}
class FlutterPlugin implements Plugin<Project> {

View File

@ -0,0 +1,77 @@
package com.flutter.gradle
import org.gradle.api.GradleException
/**
* For apps only. Provides the flutter extension used in the app-level Gradle
* build file (app/build.gradle or app/build.gradle.kts).
*
* The versions specified here should match the values in
* packages/flutter_tools/lib/src/android/gradle_utils.dart, so when bumping,
* make sure to update the versions specified there.
*
* Learn more about extensions in Gradle:
* * https://docs.gradle.org/8.0.2/userguide/custom_plugins.html#sec:getting_input_from_the_build
*/
open class FlutterExtension {
/** Sets the compileSdkVersion used by default in Flutter app projects. */
val compileSdkVersion: Int = 35
/** Sets the minSdkVersion used by default in Flutter app projects. */
val minSdkVersion: Int = 21
/**
* Sets the targetSdkVersion used by default in Flutter app projects.
* targetSdkVersion should always be the latest available stable version.
*
* See https://developer.android.com/guide/topics/manifest/uses-sdk-element.
*/
val targetSdkVersion: Int = 35
/**
* Sets the ndkVersion used by default in Flutter app projects.
* Chosen as default version of the AGP version below as found in
* https://developer.android.com/studio/projects/install-ndk#default-ndk-per-agp.
*/
val ndkVersion: String = "26.3.11579264"
/**
* Specifies the relative directory to the Flutter project directory.
* In an app project, this is ../.. since the app's Gradle build file is under android/app.
*/
var source: String = "../.."
/** Allows to override the target file. Otherwise, the target is lib/main.dart. */
var target: String? = null
/** The versionCode that was read from app's local.properties. */
var flutterVersionCode: String? = null
/** The versionName that was read from app's local.properties. */
var flutterVersionName: String? = null
/** Returns flutterVersionCode as an integer with error handling. */
fun getVersionCode(): Int {
val versionCode =
flutterVersionCode
?: throw GradleException("flutterVersionCode must not be null.")
return versionCode.toIntOrNull()
?: throw GradleException("flutterVersionCode must be an integer.")
}
/** Returns flutterVersionName with error handling. */
fun getVersionName(): String =
flutterVersionName
?: throw GradleException("flutterVersionName must not be null.")
// The default getter name that Kotlin creates conflicts with the above methods.
@get:JvmName("getVersionCodeProperty")
val versionCode: Int
get() = getVersionCode()
// The default getter name that Kotlin creates conflicts with the above methods.
@get:JvmName("getVersionNameProperty")
val versionName: String
get() = getVersionName()
}

View File

@ -0,0 +1,41 @@
package com.flutter.gradle
import org.gradle.api.GradleException
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
class FlutterExtensionTest {
@Test
fun `getVersionCode() throws GradleException when flutterVersion is not set`() {
val flutterExtension: FlutterExtension = FlutterExtension()
assertFailsWith<GradleException> { flutterExtension.getVersionCode() }
}
@Test
fun `getVersionCode() throws GradleException when flutterVersion is not an integer`() {
val flutterExtension: FlutterExtension = FlutterExtension()
flutterExtension.flutterVersionCode = "not an integer"
assertFailsWith<GradleException> { flutterExtension.getVersionCode() }
}
@Test
fun `getVersionCode() returns flutterVersion without error when set and is a number`() {
val flutterExtension: FlutterExtension = FlutterExtension()
flutterExtension.flutterVersionCode = "123"
assertEquals(123, flutterExtension.getVersionCode())
}
@Test
fun `getVersionName() throws GradleException when flutterVersionName is not set`() {
val flutterExtension: FlutterExtension = FlutterExtension()
assertFailsWith<GradleException> { flutterExtension.getVersionName() }
}
@Test
fun `getVersionName() returns flutterVersionName without error when set`() {
val flutterExtension: FlutterExtension = FlutterExtension()
flutterExtension.flutterVersionName = "1.2.3"
assertEquals("1.2.3", flutterExtension.getVersionName())
}
}