|
14 | 14 |
|
15 | 15 | package com.google.firebase.gradle.plugins.publish
|
16 | 16 |
|
| 17 | +import com.google.firebase.gradle.plugins.ci.AffectedProjectFinder |
17 | 18 | import com.google.firebase.gradle.plugins.FirebaseLibraryExtension
|
18 | 19 | import digital.wup.android_maven_publish.AndroidMavenPublishPlugin
|
19 | 20 | import org.gradle.api.Plugin
|
20 | 21 | import org.gradle.api.Project
|
| 22 | +import org.gradle.api.artifacts.ProjectDependency |
21 | 23 | import org.gradle.api.publish.maven.MavenPublication
|
22 | 24 | import org.gradle.api.tasks.bundling.Jar
|
23 | 25 | import org.gradle.api.tasks.bundling.Zip
|
| 26 | +import org.json.JSONArray |
| 27 | +import org.json.JSONObject |
24 | 28 |
|
25 | 29 | /**
|
26 | 30 | * Enables releasing of the SDKs.
|
@@ -83,9 +87,16 @@ class PublishingPlugin implements Plugin<Project> {
|
83 | 87 |
|
84 | 88 | def publishAllToLocal = project.task('publishAllToLocal')
|
85 | 89 | def publishAllToBuildDir = project.task('publishAllToBuildDir')
|
| 90 | + def publishChangedToBuildDir = project.task('publishChangedToBuildDir') |
86 | 91 | def firebasePublish = project.task('firebasePublish')
|
87 | 92 |
|
88 | 93 | project.getGradle().projectsEvaluated {
|
| 94 | + // These three variables are used for generating the JSON file that lists the artifacts |
| 95 | + // affected by the latest commit. This is generally useful only on CI builds. |
| 96 | + def changedProjects = getChangedProjects(project) |
| 97 | + def changedArtifacts = new HashSet<String>() |
| 98 | + def allArtifacts = new HashSet<String>() |
| 99 | + |
89 | 100 | project.subprojects { Project sub ->
|
90 | 101 | if (!sub.plugins.hasPlugin('firebase-library')) {
|
91 | 102 | return
|
@@ -121,11 +132,40 @@ class PublishingPlugin implements Plugin<Project> {
|
121 | 132 | publisher.decorate(sub, it)
|
122 | 133 | }
|
123 | 134 | }
|
| 135 | + |
124 | 136 | publishAllToLocal.dependsOn "$sub.path:publishMavenAarPublicationToMavenLocal"
|
125 | 137 | publishAllToBuildDir.dependsOn "$sub.path:publishMavenAarPublicationToBuildDirRepository"
|
126 | 138 |
|
| 139 | + // Update the changed and all sets each time an artifact is published. This is |
| 140 | + // used to build the JSON file of affected targets. |
| 141 | + sub.tasks.getByName("publishMavenAarPublicationToBuildDirRepository").doLast { |
| 142 | + def artifact = "$sub.group:$sub.name:$sub.version-SNAPSHOT" |
| 143 | + allArtifacts.add(artifact) |
| 144 | + |
| 145 | + if (changedProjects.contains(sub)) { |
| 146 | + changedArtifacts.add(artifact) |
| 147 | + } |
| 148 | + } |
127 | 149 | }
|
| 150 | + |
| 151 | + } |
| 152 | + |
| 153 | + // Build the JSON file of affected targets after all artifacts have been published. |
| 154 | + publishAllToBuildDir.doLast { |
| 155 | + def changed = new JSONArray() |
| 156 | + changedArtifacts.each { changed.put(it) } |
| 157 | + |
| 158 | + def all = new JSONArray() |
| 159 | + allArtifacts.each { all.put(it) } |
| 160 | + |
| 161 | + def json = new JSONObject() |
| 162 | + json.put("all", all) |
| 163 | + json.put("changed", changed) |
| 164 | + |
| 165 | + def path = project.buildDir.toPath() |
| 166 | + path.resolve("m2repository/changed-artifacts.json").write(json.toString()) |
128 | 167 | }
|
| 168 | + |
129 | 169 | project.task('publishProjectsToMavenLocal') {
|
130 | 170 | projectsToPublish.each { projectToPublish ->
|
131 | 171 | dependsOn getPublishTask(projectToPublish, 'MavenLocal')
|
@@ -155,6 +195,36 @@ class PublishingPlugin implements Plugin<Project> {
|
155 | 195 | }
|
156 | 196 | }
|
157 | 197 |
|
| 198 | + private static Set<Project> getChangedProjects(Project p) { |
| 199 | + Set<Project> roots = new AffectedProjectFinder(p, []).find() |
| 200 | + HashSet<Project> changed = new HashSet<>() |
| 201 | + |
| 202 | + getChangedProjectsLoop(roots, changed) |
| 203 | + return changed |
| 204 | + } |
| 205 | + |
| 206 | + private static void getChangedProjectsLoop(Collection<Project> projects, Set<Project> changed) { |
| 207 | + for (Project p : projects) { |
| 208 | + // Skip project if it is not a Firebase library. |
| 209 | + if (p.extensions.findByType(FirebaseLibraryExtension) == null) { |
| 210 | + continue; |
| 211 | + } |
| 212 | + |
| 213 | + // Skip processing and recursion if this project has already been added to the set. |
| 214 | + if (!changed.add(p)) { |
| 215 | + continue; |
| 216 | + } |
| 217 | + |
| 218 | + // Find all (head) dependencies to other projects in this respository. |
| 219 | + def all = p.configurations.releaseRuntimeClasspath.allDependencies |
| 220 | + def affected = |
| 221 | + all.findAll { it instanceof ProjectDependency }.collect { it.getDependencyProject() } |
| 222 | + |
| 223 | + // Recurse with the new dependencies. |
| 224 | + getChangedProjectsLoop(affected, changed) |
| 225 | + } |
| 226 | + } |
| 227 | + |
158 | 228 | private static String getPublishTask(Project p, String repoName) {
|
159 | 229 | return "${p.path}:publishMavenAarPublicationTo$repoName"
|
160 | 230 | }
|
|
0 commit comments