Skip to content

Load "flutter loader plugin" using Gradle's plugins {} block, rather than imperative apply #125009

@bartekpacia

Description

@bartekpacia

Current situation

The default, flutter created app has the android/settings.gradle file with the following content:

include ":app"

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"

This line:

apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"

imperatively applies the app_plugin_loader.gradle script to load the Flutter plugins (that have Android implementation).

Preferred situation

We could create a new Gradle plugin (strictly speaking: a new Gradle settings plugin) to make the logic more declarative. I'm thinking about:

Note: this is a new default settings.gradle (with changes made in #123511):

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 {
        // Add the default Flutter Gradle Plugin
        id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false

        // Add the Flutter plugin loader Gradle Plugin
        id "dev.flutter.flutter-plugin-loader" version "1.0.0" apply false
    }
}

include ':app'

Docs

From Gradle docs (Developing Custom Gradle Plugins):

class GreetingPlugin : Plugin<Project> {
    override fun apply(project: Project) {
        project.task("hello") {
            doLast {
                println("Hello from the GreetingPlugin")
            }
        }
    }
}

// Apply the plugin
apply<GreetingPlugin>()

Note that the Plugin class is a generic type. This example has it receiving the Project type as a type parameter. A plugin can instead receive a parameter of type Settings, in which case the plugin can be applied in a settings script, or a parameter of type Gradle, in which case the plugin can be applied in an initialization script.

Use case

This doesn't have any immediate benefit to developers. It'll make us more compliant with best practices, though.

The biggest benefit that I see is that it'll allow us to migrate the app_plugin_loader from Groovy to Kotlin without users having to change the path in settings.gradle manually (somewhat related issue: #121541).

Other Gradle-related improvement issues:

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Important issues not at the top of the work listc: new featureNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to Flutterplatform-androidAndroid applications specificallyr: fixedIssue is closed as already fixed in a newer versiont: gradle"flutter build" and "flutter run" on Androidteam-androidOwned by Android platform teamtoolAffects the "flutter" command-line tool. See also t: labels.triaged-androidTriaged by Android platform team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions