Refactor Flutter Gradle Plugin so it can be applied using the declarative plugins {} block (#123511)

This PR aims to resolve #121552.

Resources used:
- [Developing Plugins](https://docs.gradle.org/current/userguide/custom_plugins.html)
- [Using Gradle Plugins](https://docs.gradle.org/current/userguide/plugins.html#sec:plugins_block)
- [Composite Builds Plugin Development Sample](https://docs.gradle.org/current/samples/sample_composite_builds_plugin_development.html)

This PR also paves way for #121541, because apps will no longer have:

```groovy
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
```

hardcoded. Instead, they'll use:

```groovy
plugins {
    // ...
    id "dev.flutter.flutter-gradle-plugin" // the exact name is tentative
}
```
This commit is contained in:
Bartek Pacia 2023-04-19 19:56:22 +02:00 committed by GitHub
parent 122dacfa1a
commit 51251f2e57
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 1446 additions and 1375 deletions

View file

@ -2,6 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
plugins {
id "com.android.application"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
@ -10,11 +15,6 @@ if (localPropertiesFile.exists()) {
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
@ -25,9 +25,6 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
namespace "io.flutter.examples.hello_world"
compileSdkVersion flutter.compileSdkVersion

View file

@ -6,16 +6,27 @@
// To update all the settings.gradle files in the Flutter repo,
// See dev/tools/bin/generate_gradle_lockfiles.dart.
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}
settings.ext.flutterSdkPath = flutterSdkPath()
// Flutter Gradle Plugin ships together with the Flutter SDK
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
plugins {
// Flutter Gradle Plugin's ID is defined in /packages/flutter_tools/gradle/build.gradle.kts.
// We set `apply false`, because we don't want to apply the plugin to
// the `android` root project, but only to the `app` subproject.
id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
}
}
include ':app'
enableFeaturePreview('ONE_LOCKFILE_PER_PROJECT')
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle"

View file

@ -0,0 +1,34 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
plugins {
`groovy-gradle-plugin`
}
repositories {
google()
mavenCentral()
}
group = "dev.flutter.plugin"
version = "1.0.0"
gradlePlugin {
plugins {
// The "flutterPlugin" name isn't used anywhere.
create("flutterPlugin") {
id = "dev.flutter.flutter-gradle-plugin"
implementationClass = "FlutterPlugin"
}
}
}
dependencies {
// When bumping, also update:
// * ndkVersion in FlutterExtension in packages/flutter_tools/gradle/src/main/flutter.groovy
// * AGP version constants in packages/flutter_tools/lib/src/android/gradle_utils.dart
// * AGP version in buildscript block in packages/flutter_tools/gradle/src/main/flutter.groovy
compileOnly("com.android.tools.build:gradle:7.3.0")
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -7,7 +7,6 @@ import 'package:process/process.dart';
import '../base/common.dart';
import '../base/file_system.dart';
import '../base/logger.dart';
import '../base/os.dart';
import '../base/platform.dart';
@ -33,7 +32,7 @@ const String templateAndroidGradlePluginVersion = '7.3.0';
const String templateDefaultGradleVersionForModule = '7.3.0';
const String templateKotlinGradlePluginVersion = '1.7.10';
// These versions should match the values in flutter.gradle (FlutterExtension).
// These versions should match the values in Flutter Gradle Plugin (FlutterExtension).
// The Flutter Gradle plugin is only applied to app projects, and modules that are built from source
// using (include_flutter.groovy).
// The remaining projects are: plugins, and modules compiled as AARs. In modules, the ephemeral directory

View file

@ -217,7 +217,7 @@ class BuildInfo {
String get modeName => mode.cliName;
String get friendlyModeName => getFriendlyModeName(mode);
/// the flavor name in the output apk files is lower-cased (see flutter.gradle),
/// the flavor name in the output apk files is lower-cased (see Flutter Gradle Plugin),
/// so the lower cased flavor name is used to compute the output file name
String? get lowerCasedFlavor => flavor?.toLowerCase();

View file

@ -442,7 +442,8 @@ class AndroidProject extends FlutterProjectPlatform {
static final RegExp _androidNamespacePattern = RegExp('android {[\\S\\s]+namespace[\\s]+[\'"](.+)[\'"]');
static final RegExp _applicationIdPattern = RegExp('^\\s*applicationId\\s+[\'"](.*)[\'"]\\s*\$');
static final RegExp _kotlinPluginPattern = RegExp('^\\s*apply plugin\\:\\s+[\'"]kotlin-android[\'"]\\s*\$');
static final RegExp _imperativeKotlinPluginPattern = RegExp('^\\s*apply plugin\\:\\s+[\'"]kotlin-android[\'"]\\s*\$');
static final RegExp _declarativeKotlinPluginPattern = RegExp('^\\s*id\\s+[\'"]kotlin-android[\'"]\\s*\$');
static final RegExp _groupPattern = RegExp('^\\s*group\\s+[\'"](.*)[\'"]\\s*\$');
/// The Gradle root directory of the Android host app. This is the directory
@ -495,8 +496,10 @@ class AndroidProject extends FlutterProjectPlatform {
return false;
}
for (final String line in appGradle.readAsLinesSync()) {
if (line.contains(RegExp(r'apply from: .*/flutter.gradle')) ||
line.contains("def flutterPluginVersion = 'managed'")) {
final bool fileBasedApply = line.contains(RegExp(r'apply from: .*/flutter.gradle'));
final bool declarativeApply = line.contains('dev.flutter.flutter-gradle-plugin');
final bool managed = line.contains("def flutterPluginVersion = 'managed'");
if (fileBasedApply || declarativeApply || managed) {
return true;
}
}
@ -506,7 +509,9 @@ class AndroidProject extends FlutterProjectPlatform {
/// True, if the app project is using Kotlin.
bool get isKotlin {
final File gradleFile = hostAppGradleRoot.childDirectory('app').childFile('build.gradle');
return firstMatchInFile(gradleFile, _kotlinPluginPattern) != null;
final bool imperativeMatch = firstMatchInFile(gradleFile, _imperativeKotlinPluginPattern) != null;
final bool declarativeMatch = firstMatchInFile(gradleFile, _declarativeKotlinPluginPattern) != null;
return imperativeMatch || declarativeMatch;
}
File get appManifestFile {

View file

@ -1,3 +1,9 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
@ -21,10 +22,6 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
namespace "{{androidIdentifier}}"
compileSdkVersion flutter.compileSdkVersion

View file

@ -1,3 +1,9 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
@ -6,11 +12,6 @@ if (localPropertiesFile.exists()) {
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
@ -21,10 +22,6 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
namespace "{{androidIdentifier}}"
compileSdkVersion flutter.compileSdkVersion

View file

@ -1,11 +1,20 @@
include ':app'
pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}
settings.ext.flutterSdkPath = flutterSdkPath()
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle")
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
plugins {
id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false
}
}
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
include ":app"
apply from: "${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle/app_plugin_loader.gradle"