Skip to content

Properly handle pom dependencies. #461

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ package com.google.firebase.gradle.plugins.publish

import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.publish.maven.MavenPublication

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

Publisher(Mode mode, Set<Project> projectsToPublish) {
this.mode = mode
Expand All @@ -37,6 +40,7 @@ class Publisher {
publication.pom.withXml {
def rootNode = asNode()
validatePomXml(project, rootNode)
processDependencies(project, rootNode)
}
}

Expand All @@ -51,7 +55,7 @@ class Publisher {
return UNRELEASED_VERSION
}

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

private static void processDependencies(Project project, Node pom) {
def deps = getDependencyTypes(project)

pom.dependencies.dependency.each {
// remove multidex as it is supposed to be added by final applications and is needed for
// some libraries only for instrumentation tests to build.
if (it.groupId.text() in ['com.android.support', 'androidx'] && it.artifactId.text() == 'multidex') {
it.parent().remove(it)
}
it.appendNode('type', [:], deps["${it.groupId.text()}:${it.artifactId.text()}"])

// change scope to compile to preserve existing behavior
it.scope.replaceNode {
createNode('scope', 'compile')
}
}
}

private static Map<String, String> getDependencyTypes(Project project) {
def dummyDependencyConfiguration = project.configurations.create('publisherDummyConfig')
def nonProjectDependencies = project.configurations.releaseRuntimeClasspath.allDependencies.findAll {
!(it instanceof ProjectDependency)
}
dummyDependencyConfiguration.dependencies.addAll(nonProjectDependencies)
try {
return project.configurations.releaseRuntimeClasspath.getAllDependencies().collectEntries {
[("$it.group:$it.name" as String): getType(dummyDependencyConfiguration, it)]
}
} finally {
project.configurations.remove(dummyDependencyConfiguration)
}

}

private static String getType(Configuration config, Dependency d) {
if (d instanceof ProjectDependency) {
// we currently only support aar libraries to be produced in this repository
return 'aar'
}
String path = config.find {
it.absolutePath.matches(".*\\Q$d.group/$d.name/$d.version/\\E[a-zA-Z0-9]+/\\Q$d.name-$d.version.\\E[aj]ar")
}?.absolutePath
if (path && path.endsWith (".aar")) {
return "aar"
} else {
return "jar"
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ class PublishingPluginSpec extends Specification {
}
dependencies {
<%dependencies.each { println "implementation project(':$it.name')" } %>
<%externalDependencies.each { println "implementation '$it'" } %>
}
'''
String name
String group = 'com.example'
String version = 'undefined'
String latestReleasedVersion = ''
Set<Project> projectDependencies = []
Set<String> externalDependencies = []
Project releaseWith = null
String customizePom = null

Expand All @@ -60,6 +62,7 @@ class PublishingPluginSpec extends Specification {
group: group,
version: version,
dependencies: projectDependencies,
externalDependencies: externalDependencies,
releaseWith: releaseWith,
latestReleasedVersion: latestReleasedVersion,
customizePom: customizePom,
Expand Down Expand Up @@ -253,6 +256,42 @@ licenses {
dependency.version == project1.version
}

def "Publish project should correctly set dependency types"() {
Project project1 = new Project(name: 'childProject1', version: '1.0', latestReleasedVersion: '0.8')
Project project2 = new Project(
name: 'childProject2',
version: '0.9',
projectDependencies: [project1],
externalDependencies: [
'com.google.dagger:dagger:2.22',
'com.google.dagger:dagger-android-support:2.22',
'com.android.support:multidex:1.0.3'
])

when: "publishFirebase invoked"
subprojectsDefined(project1, project2)
def result = publish(Mode.RELEASE, project2)
then: 'poms exist'
def pom1 = project1.getPublishedPom("$testProjectDir.root/build/m2repository")
def pom2 = project2.getPublishedPom("$testProjectDir.root/build/m2repository")
assert !pom1.isPresent()
assert pom2.isPresent()

and: 'versions and dependency types are valid'

def xml2 = new XmlSlurper().parseText(pom2.get().text)
xml2.version == project2.version
def dependencies = xml2.dependencies.dependency.collect {
"${it.groupId.text()}:${it.artifactId.text()}:${it.version.text()}:${it.type.text()}:${it.scope.text()}"
} as Set<String>
dependencies == [
"$project1.group:$project1.name:$project1.latestReleasedVersion:aar:compile",
'com.google.dagger:dagger:2.22:jar:compile',
'com.google.dagger:dagger-android-support:2.22:aar:compile'
] as Set<String>

}

private BuildResult build(String... args) {
GradleRunner.create()
.withProjectDir(testProjectDir.root)
Expand Down