Skip to content

Commit ccdf2da

Browse files
authored
Properly handle pom dependencies. (#461)
* Properly handle pom dependencies. Namely: * Exclude multidex from POMs * Set dependency scope to compile * Properly set dependency type(jar, aar) based on resolved artifact name * Address review comments, fix test * Fix
1 parent e5bab1b commit ccdf2da

File tree

2 files changed

+94
-2
lines changed

2 files changed

+94
-2
lines changed

buildSrc/src/main/groovy/com/google/firebase/gradle/plugins/publish/Publisher.groovy

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ package com.google.firebase.gradle.plugins.publish
1616

1717
import org.gradle.api.GradleException
1818
import org.gradle.api.Project
19+
import org.gradle.api.artifacts.Configuration
20+
import org.gradle.api.artifacts.Dependency
21+
import org.gradle.api.artifacts.ProjectDependency
1922
import org.gradle.api.publish.maven.MavenPublication
2023

2124
/** Handles publication versioning and pom validation upon release. */
@@ -26,7 +29,7 @@ class Publisher {
2629
SNAPSHOT
2730
}
2831
private final Mode mode;
29-
private final Set<Project> projectsToPublish;
32+
private final Set<Project> projectsToPublish
3033

3134
Publisher(Mode mode, Set<Project> projectsToPublish) {
3235
this.mode = mode
@@ -37,6 +40,7 @@ class Publisher {
3740
publication.pom.withXml {
3841
def rootNode = asNode()
3942
validatePomXml(project, rootNode)
43+
processDependencies(project, rootNode)
4044
}
4145
}
4246

@@ -51,7 +55,7 @@ class Publisher {
5155
return UNRELEASED_VERSION
5256
}
5357

54-
private void validatePomXml(Project p, Node pom) {
58+
private static void validatePomXml(Project p, Node pom) {
5559
def unreleased = pom.dependencies.dependency.findAll { it.version.text() == UNRELEASED_VERSION }
5660
.collect { "${it.groupId.text()}:${it.artifactId.text()}"}
5761
if(unreleased) {
@@ -63,4 +67,53 @@ class Publisher {
6367
return "${baseVersion}${mode == Mode.SNAPSHOT ? '-SNAPSHOT' : ''}"
6468
}
6569

70+
private static void processDependencies(Project project, Node pom) {
71+
def deps = getDependencyTypes(project)
72+
73+
pom.dependencies.dependency.each {
74+
// remove multidex as it is supposed to be added by final applications and is needed for
75+
// some libraries only for instrumentation tests to build.
76+
if (it.groupId.text() in ['com.android.support', 'androidx'] && it.artifactId.text() == 'multidex') {
77+
it.parent().remove(it)
78+
}
79+
it.appendNode('type', [:], deps["${it.groupId.text()}:${it.artifactId.text()}"])
80+
81+
// change scope to compile to preserve existing behavior
82+
it.scope.replaceNode {
83+
createNode('scope', 'compile')
84+
}
85+
}
86+
}
87+
88+
private static Map<String, String> getDependencyTypes(Project project) {
89+
def dummyDependencyConfiguration = project.configurations.create('publisherDummyConfig')
90+
def nonProjectDependencies = project.configurations.releaseRuntimeClasspath.allDependencies.findAll {
91+
!(it instanceof ProjectDependency)
92+
}
93+
dummyDependencyConfiguration.dependencies.addAll(nonProjectDependencies)
94+
try {
95+
return project.configurations.releaseRuntimeClasspath.getAllDependencies().collectEntries {
96+
[("$it.group:$it.name" as String): getType(dummyDependencyConfiguration, it)]
97+
}
98+
} finally {
99+
project.configurations.remove(dummyDependencyConfiguration)
100+
}
101+
102+
}
103+
104+
private static String getType(Configuration config, Dependency d) {
105+
if (d instanceof ProjectDependency) {
106+
// we currently only support aar libraries to be produced in this repository
107+
return 'aar'
108+
}
109+
String path = config.find {
110+
it.absolutePath.matches(".*\\Q$d.group/$d.name/$d.version/\\E[a-zA-Z0-9]+/\\Q$d.name-$d.version.\\E[aj]ar")
111+
}?.absolutePath
112+
if (path && path.endsWith (".aar")) {
113+
return "aar"
114+
} else {
115+
return "jar"
116+
}
117+
}
118+
66119
}

buildSrc/src/test/groovy/com/google/firebase/gradle/plugins/publish/PublishingPluginSpec.groovy

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,15 @@ class PublishingPluginSpec extends Specification {
4444
}
4545
dependencies {
4646
<%dependencies.each { println "implementation project(':$it.name')" } %>
47+
<%externalDependencies.each { println "implementation '$it'" } %>
4748
}
4849
'''
4950
String name
5051
String group = 'com.example'
5152
String version = 'undefined'
5253
String latestReleasedVersion = ''
5354
Set<Project> projectDependencies = []
55+
Set<String> externalDependencies = []
5456
Project releaseWith = null
5557
String customizePom = null
5658

@@ -60,6 +62,7 @@ class PublishingPluginSpec extends Specification {
6062
group: group,
6163
version: version,
6264
dependencies: projectDependencies,
65+
externalDependencies: externalDependencies,
6366
releaseWith: releaseWith,
6467
latestReleasedVersion: latestReleasedVersion,
6568
customizePom: customizePom,
@@ -253,6 +256,42 @@ licenses {
253256
dependency.version == project1.version
254257
}
255258

259+
def "Publish project should correctly set dependency types"() {
260+
Project project1 = new Project(name: 'childProject1', version: '1.0', latestReleasedVersion: '0.8')
261+
Project project2 = new Project(
262+
name: 'childProject2',
263+
version: '0.9',
264+
projectDependencies: [project1],
265+
externalDependencies: [
266+
'com.google.dagger:dagger:2.22',
267+
'com.google.dagger:dagger-android-support:2.22',
268+
'com.android.support:multidex:1.0.3'
269+
])
270+
271+
when: "publishFirebase invoked"
272+
subprojectsDefined(project1, project2)
273+
def result = publish(Mode.RELEASE, project2)
274+
then: 'poms exist'
275+
def pom1 = project1.getPublishedPom("$testProjectDir.root/build/m2repository")
276+
def pom2 = project2.getPublishedPom("$testProjectDir.root/build/m2repository")
277+
assert !pom1.isPresent()
278+
assert pom2.isPresent()
279+
280+
and: 'versions and dependency types are valid'
281+
282+
def xml2 = new XmlSlurper().parseText(pom2.get().text)
283+
xml2.version == project2.version
284+
def dependencies = xml2.dependencies.dependency.collect {
285+
"${it.groupId.text()}:${it.artifactId.text()}:${it.version.text()}:${it.type.text()}:${it.scope.text()}"
286+
} as Set<String>
287+
dependencies == [
288+
"$project1.group:$project1.name:$project1.latestReleasedVersion:aar:compile",
289+
'com.google.dagger:dagger:2.22:jar:compile',
290+
'com.google.dagger:dagger-android-support:2.22:aar:compile'
291+
] as Set<String>
292+
293+
}
294+
256295
private BuildResult build(String... args) {
257296
GradleRunner.create()
258297
.withProjectDir(testProjectDir.root)

0 commit comments

Comments
 (0)