aar_init_script.gradle 6.74 KB
Newer Older
1 2 3 4 5
// This script is used to initialize the build in a module or plugin project.
// During this phase, the script applies the Maven plugin and configures the
// destination of the local repository.
// The local repository will contain the AAR and POM files.

6
import java.nio.file.Paths
7 8
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
9
import org.gradle.api.publish.maven.MavenPublication
10

11
void configureProject(Project project, String outputDir) {
12 13 14 15 16 17 18 19 20 21 22 23 24
    if (!project.hasProperty("android")) {
        throw new GradleException("Android property not found.")
    }
    if (!project.android.hasProperty("libraryVariants")) {
        throw new GradleException("Can't generate AAR on a non Android library project.");
    }

    // Snapshot versions include the timestamp in the artifact name.
    // Therefore, remove the snapshot part, so new runs of `flutter build aar` overrides existing artifacts.
    // This version isn't relevant in Flutter since the pub version is used
    // to resolve dependencies.
    project.version = project.version.replace("-SNAPSHOT", "")

25 26 27 28 29 30 31
    if (project.hasProperty("buildNumber")) {
        project.version = project.property("buildNumber")
    }

    project.android.libraryVariants.all { variant ->
        addAarTask(project, variant)
    }
32

33
    project.publishing {
34
        repositories {
35 36 37 38 39 40 41 42 43 44 45 46 47 48
            maven {
                url = uri("file://${outputDir}/outputs/repo")
            }
        }
    }

    // Some extra work to have alternative publications with the same format as the old maven plugin.
    // Instead of using classifiers for the variants, the old maven plugin appended `_{variant}` to the artifactId

    // First, create a default MavenPublication for each variant (except "all" since that is used to publish artifacts in the new way)
    project.components.forEach { component ->
        if (component.name != "all") {
            project.publishing.publications.create(component.name, MavenPublication) {
                from component
49 50 51
            }
        }
    }
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

    // then, rename the artifactId to include the variant and make sure to remove any classifier
    // data tha gradle has set, as well as adding a <relocation> tag pointing to the new coordinates
    project.publishing.publications.forEach { pub ->
        def relocationArtifactId = pub.artifactId
        pub.artifactId = "${relocationArtifactId}_${pub.name}"
        pub.alias = true

        pub.pom.distributionManagement {
            relocation {
                // New artifact coordinates
                groupId = "${pub.groupId}"
                artifactId = "${relocationArtifactId}"
                version = "${pub.version}"
                message = "Use classifiers rather than _variant for new publish plugin"
            }
        }

    }

    // also publish the artifacts in the new way, using one set of coordinates with classifiers
    project.publishing.publications.create("all", MavenPublication) {
        from project.components.all
        alias false
    }

78 79 80
    if (!project.property("is-plugin").toBoolean()) {
        return
    }
81

82
    String storageUrl = System.getenv('FLUTTER_STORAGE_BASE_URL') ?: "https://storage.googleapis.com"
83 84 85 86
    // This is a Flutter plugin project. Plugin projects don't apply the Flutter Gradle plugin,
    // as a result, add the dependency on the embedding.
    project.repositories {
        maven {
87
            url "$storageUrl/download.flutter.io"
88 89 90 91 92 93 94 95 96 97
        }
    }
    String engineVersion = Paths.get(getFlutterRoot(project), "bin", "internal", "engine.version")
        .toFile().text.trim()
    project.dependencies {
        // Add the embedding dependency.
        compileOnly ("io.flutter:flutter_embedding_release:1.0.0-$engineVersion") {
            // We only need to expose io.flutter.plugin.*
            // No need for the embedding transitive dependencies.
            transitive = false
98 99 100 101
        }
    }
}

102 103 104 105 106 107 108 109
void configurePlugin(Project project, String outputDir) {
    if (!project.hasProperty("android")) {
        // A plugin doesn't support the Android platform when this property isn't defined in the plugin.
        return
    }
    configureProject(project, outputDir)
}

110 111 112 113 114 115 116 117 118
String getFlutterRoot(Project project) {
    if (!project.hasProperty("flutter-root")) {
        throw new GradleException("The `-Pflutter-root` flag must be specified.")
    }
    return project.property("flutter-root")
}

void addAarTask(Project project, variant) {
    String variantName = variant.name.capitalize()
119
    String taskName = "assembleAar$variantName"
120
    project.tasks.create(name: taskName) {
121
        // This check is required to be able to configure the archives before `publish` runs.
122 123 124 125
        if (!project.gradle.startParameter.taskNames.contains(taskName)) {
            return
        }
        // Generate the Maven artifacts.
126
        finalizedBy "publish"
127 128 129
    }
}

130 131 132
// maven-publish has to be applied _before_ the project gets evaluated, but some of the code in
// `configureProject` requires the project to be evaluated. Apply the maven plugin to all projects, but
// only configure it if it matches the conditions in `projectsEvaluated`
133

134 135
allprojects {
   apply plugin: "maven-publish"
136 137
}

138
projectsEvaluated {
139
    assert rootProject.hasProperty("is-plugin")
140
    if (rootProject.property("is-plugin").toBoolean()) {
141
        assert rootProject.hasProperty("output-dir")
142
        // In plugin projects, the root project is the plugin.
143
        configureProject(rootProject, rootProject.property("output-dir"))
144 145
        return
    }
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
    // The module project is the `:flutter` subproject.
    Project moduleProject = rootProject.subprojects.find { it.name == "flutter" }
    assert moduleProject != null
    assert moduleProject.hasProperty("output-dir")
    configureProject(moduleProject, moduleProject.property("output-dir"))

    // Gets the plugin subprojects.
    Set<Project> modulePlugins = rootProject.subprojects.findAll {
        it.name != "flutter" && it.name != "app"
    }
    // When a module is built as a Maven artifacts, plugins must also be built this way
    // because the module POM's file will include a dependency on the plugin Maven artifact.
    // This is due to the Android Gradle Plugin expecting all library subprojects to be published
    // as Maven artifacts.
    modulePlugins.each { pluginProject ->
161
        configurePlugin(pluginProject, moduleProject.property("output-dir"))
162 163 164 165 166 167 168 169
        moduleProject.android.libraryVariants.all { variant ->
            // Configure the `assembleAar<variantName>` task for each plugin's projects and make
            // the module's equivalent task depend on the plugin's task.
            String variantName = variant.name.capitalize()
            moduleProject.tasks.findByPath("assembleAar$variantName")
                .dependsOn(pluginProject.tasks.findByPath("assembleAar$variantName"))
        }
    }
170
}