1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
// 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.
import java.nio.file.Paths
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.publish.maven.MavenPublication
void configureProject(Project project, String outputDir) {
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", "")
if (project.hasProperty("buildNumber")) {
project.version = project.property("buildNumber")
}
project.components.forEach { component ->
if (component.name != "all") {
addAarTask(project, component)
}
}
project.publishing {
repositories {
maven {
url = uri("file://${outputDir}/outputs/repo")
}
}
}
if (!project.property("is-plugin").toBoolean()) {
return
}
String storageUrl = System.getenv('FLUTTER_STORAGE_BASE_URL') ?: "https://storage.googleapis.com"
// 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 {
url "$storageUrl/download.flutter.io"
}
}
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
}
}
}
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)
}
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, component) {
String variantName = component.name.capitalize()
String taskName = "assembleAar$variantName"
project.tasks.create(name: taskName) {
// This check is required to be able to configure the archives before `publish` runs.
if (!project.gradle.startParameter.taskNames.contains(taskName)) {
return
}
// Create a default MavenPublication for the variant (except "all" since that is used to publish artifacts in the new way)
project.publishing.publications.create(component.name, MavenPublication) { pub ->
groupId = "${pub.groupId}"
artifactId = "${pub.artifactId}_${pub.name}"
version = "${pub.version}"
from component
}
// Generate the Maven artifacts.
finalizedBy "publish"
}
}
// 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`
allprojects {
apply plugin: "maven-publish"
}
projectsEvaluated {
assert rootProject.hasProperty("is-plugin")
if (rootProject.property("is-plugin").toBoolean()) {
assert rootProject.hasProperty("output-dir")
// In plugin projects, the root project is the plugin.
configureProject(rootProject, rootProject.property("output-dir"))
return
}
// 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 ->
configurePlugin(pluginProject, moduleProject.property("output-dir"))
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"))
}
}
}