Skip to content

Commit

Permalink
Integrate japicmp (#418)
Browse files Browse the repository at this point in the history
* Integrate japicmp

* Detect Android libraries via plugin presence

* Enable binary compatibility check on CI

* Minor fixes

* Ignore BuildConfig false positive
  • Loading branch information
jbarr21 committed Mar 25, 2021
1 parent 6adb832 commit 7c48b52
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:

script:
- cd android
- ./gradlew spotlessCheck build
- ./gradlew spotlessCheck build checkBinaryCompatibility

env:
- secure: "X1BegtP1L5RJwLKsb198RanMxXjHz0q9ta5GGqmRSuROI3sunp2tJFzQHxiYKbHNJ6t98a5tEGgX+rboQKvRA6zWZWXnGRiVZ2fBW/uIxI55yNPo5tRssjbzVUhllo9ffd/NONtFRJ7pS4csDqQtW/AvLTIl5JXj3K3ciBSc1ErLgnh7T0ycmivwoIgGVj3rI8/KVrD9QJ95p2T39UR3DdMseAUymrCeHpYxZqPhEHxWfPWWw2YVTd7tDoywALy2KFo2zGjsltqkRl4AICJE+c9DBGl4K4zrhDUGEfbqbtL1I+jnfhCjiB4AhqW2ysQNdSLRldpRVgi8hn3tWyIfuLOFD7kk99cHRCZEI1H3hqH+GveEC05y6N2JpI/UFBJ7bl4Vcz3P1xKIMxLauS+tg6yXIebia3ca7f8Kih5B8pyuFW2D3sUsmU6nFIT203WDZzYs/QOpplWUYXd6QqJqUPQk8Yi3WVxYlyIuY3M6aat0Uj1TMMWmrtFSe/SFXC7foZLKJNtgJ/FE+g6kt4IJSMW5M7Ecbgqds/d803k9A7/Qjf94bTgqFhb6E5mIEszI5mtb03GYc6rPJsNGiojvhil9szn3DDqlKZAmgyV2/RBFXwUcOK61KIU5/B+KS8dEAD3CWPaFvkIwcUrjd+JiYWhNFzxTbuqWqCMt1aG+wrI="
Expand Down
17 changes: 5 additions & 12 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,6 @@ buildscript {
}
}

Set<String> androidLibraryProjects = [
"rib-android",
"rib-android-test",
"rib-screen-stack-base",
"rib-workflow",
"rib-workflow-test"
]
Set<String> useErrorProneProjects = [
"memory-leaks",
"tutorial1",
Expand Down Expand Up @@ -91,11 +84,11 @@ subprojects {
}
}

boolean isAndroidLibrary = project.name in androidLibraryProjects
boolean isSample = project.path.startsWith(":demos:") || project.path.startsWith(":tutorials:")
boolean usesErrorProne = project.name in useErrorProneProjects

afterEvaluate {
boolean isAndroidLibrary = project.plugins.hasPlugin("com.android.library")
boolean isSample = project.path.startsWith(":demos:") || project.path.startsWith(":tutorials:")
boolean usesErrorProne = project.name in useErrorProneProjects

if ((isAndroidLibrary || isSample) && usesErrorProne) {
def configurer = { variant ->
variant.getJavaCompileProvider().configure {
Expand Down Expand Up @@ -151,4 +144,4 @@ task clean(type: Delete) {
delete rootProject.buildDir
}

apply from: 'gradle/dependencies.gradle'
apply from: rootProject.file('gradle/japicmp.gradle')
3 changes: 2 additions & 1 deletion android/gradle/dependencies.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,10 @@ def build = [
nullAway: 'com.uber.nullaway:nullaway:0.9.0',
gradlePlugins: [
android: 'com.android.tools.build:gradle:3.6.2',
apt: "net.ltgt.gradle:gradle-apt-plugin:0.21",
errorprone: "net.ltgt.gradle:gradle-errorprone-plugin:1.3.0",
japicmp: 'me.champeau.gradle:japicmp-gradle-plugin:0.2.8',
nullaway: "net.ltgt.gradle:gradle-nullaway-plugin:1.0.2",
apt: "net.ltgt.gradle:gradle-apt-plugin:0.21",
spotless: "com.diffplug.spotless:spotless-plugin-gradle:${versions.spotless}"
]
]
Expand Down
97 changes: 97 additions & 0 deletions android/gradle/japicmp.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import me.champeau.gradle.japicmp.JapicmpTask

ext.javaBaselineVersion = "0.10.1"

buildscript {
repositories {
maven {
url deps.build.gradlePluginsUrl
}
}
dependencies {
classpath deps.build.gradlePlugins.japicmp
classpath deps.build.guavaJre // https://github.com/melix/japicmp-gradle-plugin/issues/36
}
}

task checkBinaryCompatibility {
description = 'Generates binary compatibility reports'
}

def isAndroidLibrary(Project project) {
return project.plugins.hasPlugin("com.android.library")
}

def unpackAarDir(Project project) {
return "$buildDir/tmp/japicmp/$project.name"
}

def baselineArtifact(Project project) {
def group = project.property("GROUP")
def artifactId = project.property("POM_ARTIFACT_ID")
def artifactExtension = isAndroidLibrary(project) ? "aar" : "jar"
try {
String artifactName = "$artifactId-${javaBaselineVersion}.$artifactExtension"
project.group = 'virtual_group_for_japicmp' // Prevent it from resolving the current version.
def dependency = project.dependencies.create("$group:$artifactId:$javaBaselineVersion@$artifactExtension")
return project.configurations
.detachedConfiguration(dependency).files
.find { it.name == artifactName }
} finally {
project.group = group
}
}

def outputJar(Project project) {
if (isAndroidLibrary(project)) {
return "${project.buildDir}/intermediates/aar_main_jar/release/classes.jar"
} else {
return "${project.buildDir}/libs/${project.name}-${project.property("VERSION_NAME")}.jar"
}
}

def createUnpackAarTask(Project project, String baselineArtifact) {
return project.tasks.create(name: 'unpackBaselineAar', type: Copy) {
from zipTree(file(baselineArtifact))
into file(unpackAarDir(project))
}
}

def createJapicmpTask(Project project, String baselineJar, String outputJar) {
return project.tasks.create(name: 'japicmp', type: JapicmpTask) {
oldClasspath = files(baselineJar)
newClasspath = files(outputJar)
classExcludes = [
'com.uber.assert.BuildConfig',
'com.uber.rib.android.BuildConfig',
'com.uber.rib.android.core.BuildConfig',
'com.uber.rib.workflow.BuildConfig',
'com.uber.rib.workflow.test.BuildConfig',
'com.ubercab.core.screenstack.base.BuildConfig'
]
onlyBinaryIncompatibleModified = true
failOnModification = true
txtOutputFile = file("$buildDir/reports/japi.txt")
ignoreMissingClasses = true
includeSynthetic = true
}
}

allprojects { project ->
afterEvaluate {
if (project.path.startsWith(':libraries:')) {
String baselineArtifact = baselineArtifact(project)
String baselineJar = baselineArtifact.endsWith('.aar')
? "${unpackAarDir(project)}/classes.jar"
: baselineArtifact

def japicmpTask = createJapicmpTask(project, baselineJar, outputJar(project))
if (baselineArtifact.endsWith('.aar')) {
def unpackAarTask = createUnpackAarTask(project, baselineArtifact)
japicmpTask.dependsOn(unpackAarTask)
}
japicmpTask.dependsOn("$project.path:assemble")
checkBinaryCompatibility.dependsOn(japicmpTask)
}
}
}

0 comments on commit 7c48b52

Please sign in to comment.