All Projects → melix → Japicmp Gradle Plugin

melix / Japicmp Gradle Plugin

Licence: apache-2.0
A Gradle plugin for JApicmp

Programming Languages

java
68154 projects - #9 most used programming language

Projects that are alternatives of or similar to Japicmp Gradle Plugin

Gradle Util Plugins
Fix for windows gradle long classpath issue. Fixes JavaExec tasks that error out with message "CreateProcess error=206, The filename or extension is too long"
Stars: ✭ 87 (-13.86%)
Mutual labels:  gradle, plugin
Android Development Aircraft Carrier
打造安卓开发航空母舰,Android Studio 使用集锦
Stars: ✭ 138 (+36.63%)
Mutual labels:  gradle, plugin
Gradle Maven Plugin
Gradle 5.x Maven Publish Plugin to deploy artifacts
Stars: ✭ 124 (+22.77%)
Mutual labels:  gradle, plugin
Argusapm
Powerful, comprehensive (Android) application performance management platform. 360线上移动性能检测平台
Stars: ✭ 2,452 (+2327.72%)
Mutual labels:  gradle, plugin
Jmh Gradle Plugin
Integrates the JMH benchmarking framework with Gradle
Stars: ✭ 441 (+336.63%)
Mutual labels:  gradle, plugin
Craftbook
🔧 Machines, ICs, PLCs, and more!
Stars: ✭ 226 (+123.76%)
Mutual labels:  gradle, plugin
Google Java Format Gradle Plugin
Stars: ✭ 147 (+45.54%)
Mutual labels:  gradle, plugin
Hidden Secrets Gradle Plugin
🔒 Deeply hide secrets on Android
Stars: ✭ 79 (-21.78%)
Mutual labels:  gradle, plugin
Android Gradle Localization Plugin
Gradle plugin for generating localized string resources
Stars: ✭ 100 (-0.99%)
Mutual labels:  gradle, plugin
Parrot
A package to rotate text and party with parrots at the same time
Stars: ✭ 99 (-1.98%)
Mutual labels:  plugin
Kibana Object Format
A Kibana plugin for displaying objects and arrays of objects.
Stars: ✭ 100 (-0.99%)
Mutual labels:  plugin
Wrapper Validation Action
Gradle Wrapper Validation Action
Stars: ✭ 99 (-1.98%)
Mutual labels:  gradle
Latestversionplugin
LatestVersion Plugin for Xamarin and Windows apps
Stars: ✭ 99 (-1.98%)
Mutual labels:  plugin
Pytest Repeat
pytest plugin for repeating test execution
Stars: ✭ 99 (-1.98%)
Mutual labels:  plugin
33 Live2d Wp
🍟 The live2d poster girl plugin of 33 for WordPress.
Stars: ✭ 99 (-1.98%)
Mutual labels:  plugin
Flutter iap
Flutter iap plugin
Stars: ✭ 101 (+0%)
Mutual labels:  plugin
Vertx Gradle Plugin
An opinionated Gradle plugin for Vert.x projects
Stars: ✭ 98 (-2.97%)
Mutual labels:  gradle
Dark Mode
Dark Mode for the WordPress dashboard.
Stars: ✭ 98 (-2.97%)
Mutual labels:  plugin
Doctordark
📂 MacForge Plugin to bring dark mode to macOS
Stars: ✭ 100 (-0.99%)
Mutual labels:  plugin
Restfultoolkit
A Toolkit for RESTful services development.
Stars: ✭ 101 (+0%)
Mutual labels:  plugin

= JApicmp Gradle Plugin :japicmp-url: https://github.com/siom79/japicmp :issues: https://github.com/melix/japicmp-gradle-plugin/issues :gradle-url: http://gradle.org/ :plugin-version: 0.2.8

image:http://img.shields.io/travis/melix/japicmp-gradle-plugin/master.svg["Build Status (travis)", link="https://travis-ci.org/melix/japicmp-gradle-plugin"] image:http://img.shields.io/badge/license-ASF2-blue.svg["Apache License 2", link="http://www.apache.org/licenses/LICENSE-2.0.txt"]

The japicmp-gradle-plugin provides binary compatibility reporting through {japicmp-url}[JApicmp] using {gradle-url}[Gradle].

== Installation

NOTE: Version 0.2+ of this plugin is NOT compatible with 0.1

This plugin requires Gradle 4+. Use the following snippet inside a Gradle build file:

[source,groovy] [subs="attributes"] .build.gradle

buildscript { repositories { jcenter() }

dependencies {
    classpath 'me.champeau.gradle:japicmp-gradle-plugin:{plugin-version}'
}

} apply plugin: 'me.champeau.gradle.japicmp'

or

[source,groovy] [subs="attributes"]

plugins { id 'me.champeau.gradle.japicmp' version '{plugin-version}' }

== Configuration

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

[horizontal] oldClasspath:: The classpath of the baseline library to compare. Type: FileCollection newClasspath:: The classpath of the current version of the library, which you want to check binary compatibility Type: FileCollection oldArchives:: The jar files which will be used as the baseline for comparison. Type: FileCollection. newArchives:: The jar files we want to analyze. Type: Type: FileCollection. onlyModified:: Outputs only modified classes/methods. If not set to true, all classes and methods are printed. Type: boolean. Default value: false onlyBinaryIncompatibleModified:: Outputs only classes/methods with modifications that result in binary incompatibility. Type: boolean. Default value: false packageIncludes:: List of package names to include, * can be used as wildcard. Type: List packageExcludes:: List of package names to exclude, * can be used as wildcard. Type: List classIncludes:: List of classes to include. Type: List classExcludes:: List of classes to exclude. Type: List methodIncludes:: List of methods to include. Type: List methodExcludes:: List of methods to exclude. Type: List fieldIncludes:: List of fields to include. Type: List fieldExcludes:: List of fields to exclude. Type: List annotationIncludes:: List of annotations to include. The string must begin with '@'. Type: List annotationExcludes:: List of annotations to exclude. The string must begin with '@'. Type: List accessModifier:: Sets the access modifier level (public, package, protected, private). Type: String. Default value: public failOnSourceIncompatibility:: Fails if the changes result in source level incompatibility. Setting this to true also implicitly enables failOnModification. imType: boolean. Default value: false 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 htmlOutputFile:: Path to the generated HTML 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 ignoreMissingClasses:: Ignores all superclasses or interfaces that missing on the classpath. Default value: false

If you don't set oldArchives and newArchives, the plugin will infer them from the oldClasspath and newClasspath properties:

  • if you set the classpath to a configuration, the archives to compare will be the first level dependencies of that configuration
  • if you set the classpath to a simple file collection, all archives will be compared

== Usage

Add the following to your build file:

[source,groovy]

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

== Custom filtering

The plugin supports adding filters for bytecode members before they are considered for API comparison:

[source,groovy]

task japicmp(type: me.champeau.gradle.japicmp.JapicmpTask) { ... addIncludeFilter(MyCustomFilter) addExcludeFilter(MyOtherFilter) }

where MyIncludeFilter and MyExcludeFilter are classes implementing types inheriting from japicmp.filter.Filter.

For example, adding the following filter as an exclude filter will hide fields that are annotated with @Custom or have a name that contains Custom from the API comparison:

[source,groovy]

class MyOtherFilter implements FieldFilter { @Override boolean matches(CtField field) { return field.hasAnnotation("Custom") || field.name.contains("Custom") } }

== Custom reports and failure conditions

The plugin supports a DSL to generate custom reports based on the API comparison result. This has several advantages:

  • you can generate a report that focuses only on your public API, leaving the internal APIs out
  • you can implement custom rules to determine if the build should fail or not
  • the report can be presented to users and provide guidance for migration from one version to the other

=== Configuration

The report can be configured using the richReport block:

[source,groovy]

task japicmp(type: me.champeau.gradle.japicmp.JapicmpTask) { ... richReport { ... } }

Options for the rich report are:

[horizontal] renderer:: The renderer used to generate the report. By default, it uses the GroovyReportRenderer includedClasses:: A list of strings representing inclusion patterns (interpreted as regular expressions). Only classes matching this pattern will be included. excludedClasses:: A list of strings representing exclusion patterns. If a class fully qualified name matches any of those patterns, it will not be included. destinationDir:: the directory where to store the report reportName:: file name of the generated report (defaults to rich-report.html) title:: a title for the report description:: a description for the report addDefaultRules:: a boolean, indicating whether the default rules should be added or not.

If no rules are explicitly defined, the default rules are applied. If any rule is added, the default rules won't be applied unless addDefaultRules is set to true.

=== Custom rules

Rules are used to add violations to the report. The "violation" term must be taken in a simple sense, as it represents data to be shown in the report, whether it's a critical violation or just information.

A violation consists of a triplet (member, severity, explanation), that will be seen in the report. For example, if a binary incompatibility is found, you can create a violation using:

Violation.notBinaryCompatible(member)

which will automatically assign it to the error severity, leading in a build failure. However, it is possible to create any kind of violation, and even accept binary incompatible changes.

Rules can be applied to 3 different levels:

  • all members (a generic rule applied unconditionnaly)
  • on specific change types (NEW, REMOVED, UNCHANGED, MODIFIED), see JApiChangeStatus
  • on specific compatibility change descriptors (see JApiCompatibilityChange)

Rules are executed in the following order:

. status change first . specific compatibility change . generic rules

For example, imagine that we want to check that all new methods are annotated with @Incubating (this is a rule in the Gradle project). Then, you need to create a rule class which will implement that check:

[source,groovy]

class IncubatingMissingRule implements ViolationRule { @Override Violation maybeViolation(final JApiCompatibility member) { if (member instanceof JApiMethod) { if (!member.annotations.find { it.fullyQualifiedName == 'org.gradle.api.Incubating' }) { if (!member.jApiClass.annotations.find { it.fullyQualifiedName == 'org.gradle.api.Incubating' }) { Violation.error(member, "New method is not annotated with @Incubating") } } } } }

and then you need to configure the report to use that rule:

[source,groovy]

richReport { addRule(JApiChangeStatus.NEW, IncubatingMissingRule) }

Rules can take arguments, but those are limited to Map<String, String>. For example, the following rule will mark a binary breaking change as an error, unless it is reviewed and accepted. The list of acceptations is passed as an argument to the rule:

[source,groovy]

class AcceptedRegressionRule implements ViolationRule { private final Map<String, String> acceptedViolations

public AcceptedRegressionRule(Map<String, String> params) {
    acceptedViolations = params
}

@Override
Violation maybeViolation(final JApiCompatibility member) {
    if (!member.binaryCompatible) {
        def acceptation = acceptedViolations[Violation.describe(member)]
        if (acceptation) {
            Violation.accept(member, acceptation)
        } else {
            Violation.notBinaryCompatible(member)
        }
    }
}

}

and here's how the rule is applied:

[source,groovy]

richReport { addRule(AcceptedRegressionRule, acceptedViolations) }

=== Setup and post-process rules

Since release 0.2.2, the plugin also supports setup and post-process rules. Setup rules allow setting up some global context that can be accessed by rules extending AbstractContextAwareViolationRule. This can be useful when you need to share data between rules, and perform a final check in a post-process rule.

Setup rules need to implement SetupRule:

[source,groovy]

class MySetupRule implements SetupRule {

@Override
void execute(final ViolationCheckContext violationCheckContext) {
    // this is going to be executed before any other rule is executed
    violationCheckContext.userData.executed = false
}

}

and declared using addSetupRule:

[source,groovy]

richReport { addSetupRule(MySetupRule) }

Then the context can be accessed in rules implementing AbstractContextAwareViolationRule:

[source,groovy]

class ContextAwareRule extends AbstractContextAwareViolationRule {

@Override
Violation maybeViolation(final JApiCompatibility member) {
    // this rule is accessing the global context and can mutate user data
    context.userData.executed = true

    return null
}

}

And then a post-process rule has access to the user data, and can also mutate the actual list of violations per class, before the report is generated:

[source,groovy]

class MyTearDownRule implements PostProcessViolationsRule {

@Override
void execute(final ViolationCheckContextWithViolations violationCheckContextWithViolations) {
    // this rule is executed once all checks have been performed, just before the generation
    // of the report
    // it gives the opportunity to add additional violations, or filter them, or fail
    // with a custom error
    assert violationCheckContextWithViolations.userData.executed == true
    assert !violationCheckContextWithViolations.violations.isEmpty()
}

}

It needs to be wired in using the addPostProcessRule hook:

[source,groovy]

richReport { addPostProcessRule(MySetupRule) }

== Avoiding multiple violations for the same class

Since 0.2.5, it is now possible to track which members have already resulted in a violation. Since rules are executed in order, and that you can have a rule applied for a status change and a generic rule applied on the same member, it was possible for a member to trigger multiple violations. To avoid this, you can make your rule extend AbstractRecordingSeenMembers. This rule requires the RecordSeenMembersSetup to be applied, and it will only add a violation, if no other violation for the same member was added before.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].