Skip to content

ejuste/japicmp-gradle-plugin

 
 

Repository files navigation

JApicmp Gradle Plugin

Build Status

The japicmp-gradle-plugin provides binary compatibility reporting through JApicmp using Gradle.

Installation

Use the following snippet inside a Gradle build file:

build.gradle
buildscript {
    repositories {
        jcenter()
    }

    dependencies {
        classpath 'me.champeau.gradle:japicmp-gradle-plugin:0.1.1'
        // UNCOMMENT THE NEXT LINE ONLY IF YOU ARE USING GRADLE 1.X
        // classpath 'org.codehaus.groovy:groovy-backports-compat23:2.3.6'
    }
}
apply plugin: 'me.champeau.gradle.japicmp'

Configuration

The plugin provides a new task type: me.champeau.gradle.JapicmpTask that you can use to compare two jars. This task exposes the following properties as part of its configuration:

oldArchive

The jar file which will be used as the reference for comparison. Type: File.

newArchive

The jar file we want the report to work on. Type: File.

onlyModified

Outputs only modified classes/methods. If not set to true, all classes and methods are printed. Type: boolean. Default value: false

packagesToInclude

List of package names to include, * can be used as wildcard. Type: List<String>

packagesToExclude

List of package names to exclude, * can be used as wildcard. Type: List<String>

accessModifier

Sets the access modifier level (public, package, protected, private). Type: String. Default value: public

failOnModification

When set to true, the build fails in case a modification has been detected. Type: boolean. Default value: false

xmlOutputFile

Path to the generated XML report. Type: File. Default value: null

txtOutputFile

Path to the generated TXT report. Type: File. Default value: null

includeSynthetic

Synthetic classes and class members (like e.g. bridge methods) are not tracked per default. This new option enables the tracking of such kind of classes and class members

Usage

Add the following to your build file:

task japicmp(type: me.champeau.gradle.JapicmpTask) {
    oldArchive = file('path/to/reference.jar')
    newArchive = jar.archivePath
    onlyModified = true
    failOnModification = true
    txtOutputFile = file("$buildDir/reports/japi.txt")
}

Alternative task

An alternative task will let you work on dependencies instead of plain jars. Imagine that you want to compare the current jar with a previous version, available in a repository. Then you can do:

task japicmp(type: me.champeau.gradle.ArtifactJapicmpTask) {
    baseline = 'com.acme.group:artifactid:version'
    to = jar.archivePath
    onlyModified = true
    failOnModification = true
    txtOutputFile = file("$buildDir/reports/japi.txt")
}

Note the use of ArtifactJapicmpTask instead of JapicmpTask.

Custom build failure conditions

The plugin also supports a DSL providing hooks for classes and methods which have been added/removed/…​ You can use those hooks to trigger custom build failures, like illustrated here:

task japicmp(type: me.champeau.gradle.ArtifactJapicmpTask) {
    baseline = 'com.acme.group:artifactid:version'
    to = jar.archivePath
    onlyModified = true
    failOnModification = false // by default, no failure
    txtOutputFile = file("$buildDir/reports/japi.txt")
    outputProcessor {
        removedMethod { clazz, method ->
            if (clazz.fullyQualifiedName == 'com.Foo') {
                failOnModification = true // This class must absolutely not be touched!
            }
        }
    }
}

The outputProcessor block supports the following hooks:

Table 1. Output processor hooks
Hook name Arguments Description

unchangedClass

JApiClass

Called on an unchanged class, unless onlyModified is true

newClass

JApiClass

A class has been added

modifiedClass

JApiClass

A class has been modified

removedClass

JApiClass

A class has been removed

unchangedMethod

(JApiMethod) or (JApiClass,JApiMethod)

Called on an unchanged method, unless onlyModified is true

unchangedConstructor

(JApiConstructor) or (JApiClass,JApiConstructor)

Called on an unchanged constructor, unless onlyModified is true

newMethod

(JApiMethod) or (JApiClass,JApiMethod)

A method has been added

modifiedMethod

(JApiMethod) or (JApiClass,JApiMethod)

A method has been modified

modifiedConstructor

(JApiConstructor) or (JApiClass,JApiConstructor)

A constructor has been modified

removedMethod

(JApiMethod) or (JApiClass,JApiMethod)

A method has been removed

removedConstructor

(JApiConstructor) or (JApiClass,JApiConstructor)

A method has been removed

before

List<JApiClass>

Called before iteration on classes is triggered

after

List<JApiClass>

Called after iteration on classes is triggered

The xxxMethod hooks support two variants. One takes a single argument corresponding to the method only. The second version is a convenient way to track to which class the method belongs to, by adding it as a first argument.

Custom output

The outputProcessor hooks can be used to produce custom reports, as illustrated here:

task japicmp(type: me.champeau.gradle.ArtifactJapicmpTask) {
    // ...

    outputProcessor {
        def sb = new StringBuilder()

        before {
            sb << "Comparing $baseline with $to\n"
        }
        after { list ->
            sb << "Reported ${list.size()} changed classes\n"
            file("${buildDir}/reports/custom.txt").write(sb.toString())
        }
        newMethod { c, m ->
           sb.append "Class $c.fullyQualifiedName has new method: $m.name\n"
        }
    }
}

About

A Gradle plugin for JApicmp

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Groovy 100.0%