ru.vyarus:gradle-java-lib-plugin

Gradle Java-lib plugin


Keywords
gradle, gradle-plugin, java, maven-publish
License
MIT

Documentation

Gradle Java-lib plugin

License CI Appveyor build status codecov

About

Plugin do all boilerplate of maven publication configuration (using maven-publish) for java (or groovy) library or gradle plugin. Simplifies POM configuration and dependencies management (BOM). Also, changes some defaults common for java projects (like UTF-8 usage).

Makes gradle more "maven" (in sense of simplicity, some behaviours and for multi-module projects).

Features:

  • Maven-like jar configuration
    • put pom.xml and pom.properties inside jar
    • fill manifest properties
  • Configure javadoc and sources artifacts (required for maven central publish) (with native gradle integrations)
  • Prepare maven publication (maven-publish plugin configuration)
    • maven publication configured with all jars (jar, sources javadoc)
  • Applies pom plugin which:
  • Add install task as shortcut for publishToMavenLocal (simpler to use)
  • Apply UTF-8 encoding for:
    • compile tasks: JavaCompile and GroovyCompile
    • javadoc (encoding, charSet, docEncoding)
    • test tasks: set file.encoding=UTF-8 system property (only for test tasks)
  • Prepares BOM publication for java-platform plugin
  • Test and coverage reports aggregation for multi-module projects
  • Simplifies gradle platforms usage in multi-module projects (avoid "platform" leaking in published poms)

If you need multiple publications from the same project, then you will have to perform additional configuration or, maybe (depends on case), use only pom plugin.

Confusion point: plugin named almost the same as gradle's own java-library plugin, but plugins do different things (gradle plugin only provides api and implementation configurations) and plugins could be used together.

Summary
  • Configuration closures: maven (from pom plugin), javaLib
  • Tasks: sourcesJar, javadocJar, install, openDependencyReport
  • Publication: maven, bom
  • Enable plugins: maven-publish, ru.vyarus.pom

Setup

Maven Central Gradle Plugin Portal

buildscript {
    repositories {
      gradlePluginPortal()
    }
    dependencies {
        classpath 'ru.vyarus:gradle-java-lib-plugin:3.0.0'
    }
}
apply plugin: 'ru.vyarus.java-lib'

OR

plugins {
    id 'ru.vyarus.java-lib' version '3.0.0'
}

Compatibility

Plugin compiled for java 8, compatible with java 17

Gradle Version
7 3.0.0
5.1 2.4.0
4.6 1.1.2
older 1.0.5

NOTE: plugin-publish 1.x would work properly only with gradle 7.6 or above

Snapshots

Snapshots may be used through JitPack
  • Go to JitPack project page

  • Select Commits section and click Get it on commit you want to use or use master-SNAPSHOT to use the most recent snapshot

  • Add to settings.gradle (top most!) with required commit hash as version:

    pluginManagement {
        resolutionStrategy {
            eachPlugin {
                if (requested.id.namespace == 'ru.vyarus.java-lib') {
                    useModule('ru.vyarus:gradle-java-lib-plugin:b5a8aee24f')
                }
            }
        }
        repositories {
            maven { url 'https://jitpack.io' }
            gradlePluginPortal()          
        }
    }    
  • Use plugin without declaring version:

    plugins {
        id 'ru.vyarus.java-lib'
    }

Usage

Plugin activate features based on registered plugins. Plugin support several usage scenarios.

In case of multi-module projects, plugin activate features only in applied module, ignoring submodules or root module (so to apply it in all submodules use allprojects or subprojects section)

Example projects:

Java module

plugins {
  id 'java' // groovy or java-library
  // id 'signing'
  // id 'project-report'
  id 'ru.vyarus.java-lib'
}

group = 'your.group'                    
version = '1.0.0'                       
description = 'My project description'

// configure target pom
maven.pom {
  name = 'Project Name'
  description = 'My awesome project'
  ...
}

repositories { mavenLocal(); mavenCentral() }
dependencies {
  ...
}

javaLib {
  // withoutJavadoc()
  // withoutSources()
  withoutGradleMetadata()
  
  // autoModuleName = 'project-module-name'
  
  pom {
    // removeDependencyManagement()
    // forceVersions()
    // disableScopesCorrection()
    // disableBomsReorder()
  }
}

Activates with java, groovy or java-library plugin.
Typical usage: single-module gradle project which must be published to maven central (or any other maven repo)

  • Adds javadoc and sources for publication
  • Registers maven publication for pom, jar, javadoc and sources artifacts
  • Applies UTF-8 encoding for java/groovy compile, javadoc/groovydoc and test executions
  • If signing plugin active, configures publication signing (required for maven central publication)
  • Adds install task for installation into local repository (like maven; simply shortcut for publishToMavenLocal task)
  • Enables xml jacoco reports (if jacoco enabled; required for coverage services)
  • Register ru.vyarus.pom plugin which:
    • adds optional and provided configurations (in maven sense)
    • fixes dependency scopes in the generated pom
    • moves up dependencyManagement section in the generated pom (if platforms used)
    • adds maven.pom extension for pom declaration (maven.withPomXml might be used for low-level modification)
  • Utilities:
    • simple Auto-Module-Name declaration (java 9 modules)
    • option to disable gradle metadata publication (maven central fails on it sometimes)
    • option to remove dependencyManagement section in the generated pom (appears if platforms used): use resolved dependencies versions instead (pom plugin feature)
  • Adds openDependencyReport task added if project-report plugin enabled
    (opens htmlDependencyReport directly in browser)

BOM module

plugins {
  id 'java-platform' 
  // id 'signing'
  // id 'project-report'
  id 'ru.vyarus.java-lib'
}

group = 'your.group'                    
version = '1.0.0'                       
description = 'My project description'

maven.pom {
  ...
}

repositories { mavenLocal(); mavenCentral() }
dependencies {
  api platform('ru.vyarus.guicey:guicey-bom:5.2.0-1')
  constraints {
    api 'org.webjars:webjars-locator:0.40'
  }
  // add subprojects to published BOM
  project.subprojects.each { api it }
}

javaLib {
  bom {
    // change artifact from project name, if required
    artifactId = 'something-bom'
    description = 'Different from project description'
  }
  withoutGradleMetadata()
}

Activates with java-platform plugin.
Typical usage: BOM module (might be root project) in multi-module project

  • Activates platform dependencies (javaPlatform.allowDependencies()) to allow single dependencies declaration
  • Registers bom publication for bom artifact (produced from declared platform)
  • Register ru.vyarus.pom plugin (with the same features as above)
  • If signing plugin active, configures publication signing (required for maven central publication)
  • Adds install task for installation into local repository (like maven; simply shortcut for publishToMavenLocal task)
  • Utilities:
    • option to disable gradle metadata publication (maven central fails on it sometimes)
    • option to change bom artifact id (useful when platform declared in the root module)
  • Adds openDependencyReport task added if project-report plugin enabled
    (opens htmlDependencyReport directly in browser)

Root project reports aggregation

plugins {
  id 'base' 
  id 'jacoco'
  //id 'project-report'
  id 'ru.vyarus.java-lib'
}

javaLib {
  aggregateReports()
}

// sub modules - simple java projects
subprojects {
  apply plugin: 'java'
  
  ...
}

Activates with base plugin.
Used to aggregate test and coverage reports from java submodules.

By default, will only register openDependencyReport task added if project-report plugin enabled.
Reports aggregation must be explicitly triggered:

  • Adds test task which would simply aggregate (run if required) java submodules test reports
  • If jacoco plugin active, add jacocoMerge (not for direct usage) and jacocoTestReport tasks to aggregate jacoco xml and html reports from java submodules
  • If project-report plugin active, will aggregate dependency reports for submodules

In short: it adds absolutely the same tasks as in java modules and generates reports exactly into the same locations so there would be no difference in paths when configuring external services (e.g. coveralls).

NOTE: aggregation will work with java-platform plugin too if it used in the root module (see complete multi-module example).

Options

javaLib {

  /**
   * Do not publish javadoc (groovydoc) with `maven` publication. 
   */
  withoutJavadoc()

  /**
   * Do not publish sources with `maven` publication. 
   */
  withoutSources()

  /**
   * Do not publish gradle metadata artifact. 
   * Affects all publications (not just registered by plugin).
   */
  withoutGradleMetadata()

  /**
   * Disable all publications. Might be used to disable configured BOM publication or any sub-module publication.
   */
  withoutPublication()

  /**
   * Shortcut for Auto-Module-Name meta-inf header declaration
   */
  autoModuleName = 'project-module-name'

  /**
   * Used ONLY with java-platform plugin if published artifact must differ from
   * project name (for example, when declared in the root project).
   */
  bom {
    // when not declared, project.name used
    artifactId = 'name'
    // when not declared, project.description used
    description = 'desc'
  }

  /**
   * Used in the root project (project with child projects) to aggregate
   * test, coverage (jacoco) and dependency (project-report) reports. 
   * Requires at least `base` plugin. Will work java-platform plugin
   * (will not work with java plugin because such module can't aggregate).
   */
  aggregateReports()
}

POM

You need to specify general project info:

group = 'your.group'                    // maven group
version = '1.0.0'                       // project version
description = 'My project description'  // optional (affects jar manifest) 

Note: maven artifactId will be the same as project name, and the default for project name is current directory name. If you need to change name, add in settings.gradle:

rootProject.name = 'the-name-you-want'

For maven-central publication you need to fill all required pom sections:

maven.pom {
    // name and desciption set automatically from project, but you can override them here
    //name 'Project Name'
    //description 'My awesome project'
    licenses {
        license {
            name = "The MIT License"
            url = "http://www.opensource.org/licenses/MIT"
            distribution = 'repo'
        }
    }
    scm {
        url = 'https://github.com/me/my-repo'
        connection = 'scm:git@github.com:me/my-repo.git'
        developerConnection = 'scm:git@github.com:me/my-repo.git'
    }
    developers {
        developer {
            id = "dev1"
            name = "Dev1 Name"
            email = "dev1@email.com"
        }
    }
}

Read more about pom configuration in the pom plugin's docs.

If your project hosted on github you may use github-info plugin, which fills most github-related pom sections for you automatically.

Use the following configurations to get correct scopes in the resulted pom:

Maven scope Gradle configuration
compile implementation, api
runtime runtimeOnly
provided provided (not compileOnly!)
optional optional, feature variants

See pom plugin doc for more details about dependencies scopes in the generated pom

Using BOMs

When you use BOMs (for dependencies versions management) with spring plugin or gradle platform you'll have dependencyManagement section generated in the target pom. Often it is not desired:to use only resolved versions and avoid dependencyManagent use:

maven.pom.removeDependencyManagement()

Read more in the pom plugin's docs

BOM declaration

The simplest way to declare BOM is using java-platform

plugins {
  id 'java-platform'
  id 'ru.vyarus.java-lib'
}

repositories { mavenLocal(); mavenCentral() }
dependencies {
  api platform('ru.vyarus.guicey:guicey-bom:5.2.0-1')
  constraints {
    api 'org.webjars:webjars-locator:0.40'
  }
  // add subprojects to published BOM
  project.subprojects.each { api it }
}

Java-lib plugin would automatically activate dependencies declaration (constraints block).

I propose to mix dependencies and modules into single BOM declaration, but you can always split dependencies management and modules BOM by declaring two platforms in two different modules.

If you use java-platform in the root project, then you might want to change name of published artifact (by default it would be root project name in this case). To change it use:

javaLib {
  bom {
    artifactId = 'some-bom'
    description = 'overridden description'
  }
}

Publication

maven-publish plugin used for publication.

By default, plugin configures maven publication with javadoc or (and) groovydoc and sources jars for java (groovy or java-library) plugins and bom publication for java-platform plugin.

Use install task to deploy everything into local maven repository.

$ gradlew install

If you don't want to publish everything (jar, sources, javadoc) then you can:

javaLib {
  withtouSources()
  withoutJavadoc()
}

OR override list of publishing artifacts:

publishing.publications.maven.artifacts = [jar, javadocJar]

NOTE that for maven central publication sources and javadocs are required

To ADD artifacts for publication, configure them directly for publication:

publishing {
    publications.maven {
        artifact buildDelivery { archiveClassifier.set('zip') }
    }
}

Here the result of buildDelivery task (of type Zip) added to maven publication with zip classifier.

Gradle metadata

Since gradle 6, gradle would always publish its metadata:

Gradle Module Metadata is a unique format aimed at improving dependency resolution by making it multi-platform and variant-aware.

Essentially, it's an additional .module file containing json representation of dependencies. This is really necessary only when advanced gradle features used (constraints (not in platform), variants).

But this would mean that gradle and maven projects would use different dependencies after publication: maven use pom, gradle would load .module file with additional dependencies info.

It would be more honest to publish only pom (especially for public projects) and disable metadata publishing:

javaLib {
  withoutMavenMetadata()
}

Also note, that maven central could complain about metadata file (if published).

Publish to repository

You must configure repository for actual publication repository must be configured:

publishing {
    repositories {
        maven {
            // change to point to your repo, e.g. http://my.org/repo
            url "$buildDir/repo"
        }
    }
}

Then publish task may be used to perform publish.

Publish to maven-central

For maven-central publication use nexus publish plugin which automates full maven central release cycle.

plugins {
  ...
  id 'io.github.gradle-nexus.publish-plugin' version '1.1.0'
}

nexusPublishing {
  repositories {
    sonatype {
      username = findProperty('sonatypeUser')
      password = findProperty('sonatypePassword')
    }
  }
}

For release, you would need to call two tasks: publishToSonatype, closeAndReleaseSonatypeStagingRepository

You'll need to configure sonatypeUser and sonatypePassword properties in global gradle file: ~/.gradle/gradle.properties

IMPORTANT artifacts must be signed!

Gradle plugin

Gradle plugin project will have java-gradle-plugin, which declares its own maven publication pluginMaven (with main jar as artifact). Also, plugin creates one more publication per declared plugin to publish plugin marker artifact (required by gradle plugins dsl).

Java-lib plugin will still create separate publication maven and you should use it for publishing with bintray (same way as for usual library)

Publishing to gradle plugin repository

For publishing in gradle plugin repository you will use com.gradle.plugin-publish plugin.

IMPORTANT: plugin-publish 1.x is supported for gradle 7.6 and above, for lower gradle use 0.x

Use maven publication for publishing into maven central or other repo (optional). Plugin-publish will use it's plugin-maven publication for plugins portal publication. Both publications would contain the same artifacts.

Example for publishing in maven central and plugin portal (gradle 7.6 or above):

plugins {
  id 'com.gradle.plugin-publish' version '1.2.1'
  id 'java-gradle-plugin'
  id 'ru.vyarus.java-lib' version '3.0.0'
}

repositories { mavenLocal(); mavenCentral(); gradlePluginPortal() }

group = 'com.foo'
description = 'Short description'

gradlePlugin {
  plugins {
    myPlugin {
      id = 'com.foo.plugin'
      displayName = project.description
      description = 'Long description'
      tags.set(['something'])
      implementationClass = 'com.foo.MyPlugin'
    }
  }
}

Here publishMavenPublicationToMavenRepository would publish to repository and publishPlugins publish into plugins portal.

Assuming custom maven (name!) repository is configured:

publishing {
  repositories { maven { url "http://some.repo/"} }
}
Publishing only to custom repo

This is in-house plugin case, when plugin is published only into corporate repository.

The simplest solution is to disable pluginMaven publication tasks (but marker artifact publications should remain!) and publish only remaining maven publication:

tasks.withType(AbstractPublishToMaven) { Task task ->
    if (task.name.startsWith("publishPluginMaven")) {
        task.enabled(false)
    }
}

This will disable: publishPluginMavenPublicationToMavenLocal and publishPluginMavenPublicationToMavenRepository

And you can simply use publish task to trigger all required publications without duplicates.

The same way, install will install all required artifacts locally (including markers) and so it is possible to use plugins from local maven repository too (with plugin syntax):

add to settings.gradle:

pluginManagement {
    repositories {
        mavenLocal()
        gradlePluginPortal()
    }
}

Encodings

UTF-8 applied to:

  • (all CompileJava tasks).options.encoding
  • (all CompileGrovy tasks).options.encoding
  • (all Javadoc).options.[encoding, charSet, docEncoding]
  • (all Test).systemProperty 'file.encoding'

Note that groovydoc task does not have encoding configuration, but it should use UTF-8 by defautl.

For tests, encoding is important (especially on windows) because test forked process will not inherit root gradle encoding configuration.

Tasks

NOTE: for gradle 7.6 and above native javadoc and sources registration used

  • sourcesJar
  • javadocJar
  • openDependencyReport if project-report plugin active - opens html dependency report in browser

install task added to simplify publication to local maven repository: this is simply shortcut for gradle's publishToMavenLocal task (simply shorter to type and more common name after maven).

Main Jar

Plugin applies default manifest properties:

'Implementation-Title': project.description ?: project.name,
'Implementation-Version': project.version,
'Built-By': System.getProperty('user.name'),
'Built-Date': new Date(),
'Built-JDK': System.getProperty('java.version'),
'Built-Gradle': gradle.gradleVersion,
'Target-JDK': project.targetCompatibility

You can override it:

jar {
    manifest {
        attributes 'Implementation-Title': 'My Custom value',
            'Built-By': 'Me'
    }
}

For all not specified properties default values will be used.

Plugin will include additional files inside jar (like maven do) into META-INF/maven/group/artifact/

  • pom.xml
  • pom.properties

pom.properties contains:

  • version
  • groupId
  • artifactId

Signing

Plugin will configure signing automatically for configured publications: maven and bom (note that in case of gradle plugin, gradle use its own publication for portal publication and it would not be signed (no need)).

You only need to apply signing plugin:

plugins {
  id 'java'
  id 'signing'
  id 'ru.vyarus.java-lib'
}

No additional configuration required, except properties in the global gradle config ~/.gradle/gradle.properties:

signing.keyId = 78065050
signing.password =
signing.secretKeyRingFile = /path/to/certs.gpg

IMPORTANT: password property (empty) required even if no password used!

Note that project build will not complain while building snapshot versions (version ending with -SNAPSHOT) - signing task would be simply ignored. But, on release gradle would fail if signing not configured properly.

Signing certificate

Certificate generation described in many articles around the web, for example, sonatype gpg guide.

I will just show required commands for generation and obtaining keyring file:

Certificate generation:

gpg --gen-key

(if you want, you can leave passphrase blank - just hit enter several times)

Alternatively, gpg --full-gen-key may be used to set exact algorithm and expiration (by default generated key would expire in few years)

List keys:

gpg --list-keys
gpg --list-secret-keys

You can always edit key if required (for example change expiration):

gpg --edit-key (key id)
gpg> key 1
gpg> expire
(follow prompts)
gpg> save

Create keyring file:

gpg --export-secret-keys (key id) > cert.gpg

Put cert.gpg somewhere and set full path to it in signing.secretKeyRingFile

You also need short key id:

gpg --list-secret-keys --keyid-format SHORT

Example output:
  sec   rsa3072/78065050 2021-06-06 [SC]

Here 78065050 is your keyid which should be set as signing.keyId

If you set passphrase, set it in signing.password, otherwise leave it blank

IMPORTANT: for maven central, you'll need to register your public key with

gpg --keyserver keyserver.ubuntu.com --send-keys (short key id)

That's all.

Dependency report

When project-report plugin active, openDependencyReport task created.

This is pure utility task: it calls htmlDependencyReport and opens it directly in the browser (directly on page with dependencies, instead of index).

This simply faster: manual htmlDependencyReport requires several clicks to open required report.

Maven-like multi-module project

Here is an example of how plugin could be used in multi-module project to apply maven configuration style: root project manage all dependency versions.

plugins {
    id 'jacoco'
    id 'java-platform'
    id 'ru.vyarus.java-lib'
}

description = 'Maven-like project'

// dependency versions management
dependencies {
    api platform("ru.vyarus:dropwizard-guicey:$guicey")
    constraints {
        api 'com.h2database:h2:1.4.200'

        // add subprojects to BOM
        project.subprojects.each { api it }
    }
}

javaLib {
    aggregateReports()
    // publish root BOM as custom artifact
    bom {
        artifactId = 'sample-bom'
        description = 'Sample project BOM'
    }
  
    // OR disable BOM publication
    // withoutPublication()
}

// maven publication related configuration applied to all projects
allprojects {
    //apply plugin: 'project-report'
    //apply plugin: 'signing'

    repositories { mavenCentral(); mavenLocal() }

    group = 'com.test'
  
    // such delay is required because java-lib (and java) plugin would be applied only
    // in the subprojects section and so this would configure root project configuration
    // without delay
    plugins.withId('java') {
        maven.pom {
            licenses {
                license {
                    name = "The MIT License"
                    url = "http://www.opensource.org/licenses/MIT"
                    distribution = 'repo'
                }
            }
            scm {
                url = 'https://github.com/me/my-repo.git'
                connection = 'scm:git@github.com:me/my-repo.git'
                developerConnection = 'scm:git@github.com:me/my-repo.git'
            }
            //...
        }
    }  

    javaLib.withoutGradleMetadata()
}

// all sub-modules are normal java modules, using root BOM (like maven)
subprojects {
    apply plugin: 'groovy'
    apply plugin: 'jacoco'
    apply plugin: 'ru.vyarus.java-lib'

    sourceCompatibility = 1.8

    // common dependencies for all modules
    dependencies {
        implementation platform(project(':'))

        compileOnly 'com.github.spotbugs:spotbugs-annotations:4.2.3'
        implementation 'ru.vyarus:dropwizard-guicey'

        testImplementation 'org.spockframework:spock-core'
        testImplementation 'io.dropwizard:dropwizard-testing'
    }

    javaLib {
        // java 9 auto module name
        autoModuleName = "com.sample.module"
    }
  
    maven {
        // use only direct dependencies in the generated pom, removing BOM
        removeDependencyManagement()
    }
}

Here required dependency versions declared in the root project using gradle platform. Platform published as BOM with custom artifact name (dual BOM: both project modules and dependencies).

Sub-projects are java modules which use platform declared in the root project for dependency management. maven.removeDependencyManagement() prevents "leaking" platform into module poms (generated poms would contain just required dependencies with resolved versions)

groovy plugin used just as an example (used for spock tests, main sources might be java-only): it could be java or java-library plugin.

The complete multi-module project example could be generated with java-library generator.

APPENDIX: boilerplate plugin removes

Section briefly shows what plugin configures so if plugin defaults didn't fit your needs, you can easily reproduce parts of it in your custom build.

Java module boilerplate

plugins { id 'java' }

apply plugin: 'ru.vyarus.pom'

jar {    
    manifest {
        attributes 'Implementation-Title': project.description ?: project.name,
                'Implementation-Version': project.version,
                'Built-By': System.getProperty('user.name'),
                'Built-Date': new Date(),
                'Built-JDK': System.getProperty('java.version'),
                'Built-Gradle': gradle.gradleVersion,
                'Target-JDK': project.targetCompatibility
    }
}

java {
    withJavadocJar()
    withSourcesJar()
}        

task generatePomPropertiesFile {
    inputs.properties ([
            'version': "${ -> project.version }",
            'groupId': "${ -> project.group }",
            'artifactId': "${ -> project.name }"
    ])
    outputs.file "$project.buildDir/generatePomPropertiesFile/pom.properties"
    doLast {
        File file = outputs.files.singleFile
        file.parentFile.mkdirs()
        file << inputs.properties.collect{ key, value -> "$key: $value" }.join('\n')
    }
}

model {
    tasks.jar {
        into("META-INF/maven/$project.group/$project.name") {
            from generatePomFileForMavenPublication
            rename ".*.xml", "pom.xml"
            from generatePomPropertiesFile
        }
    }
}

tasks.withType(JavaCompile).configureEach {
    it.options.encoding = StandardCharsets.UTF_8
}

tasks.withType(GroovyCompile).configureEach {
    it.options.encoding = StandardCharsets.UTF_8
}

tasks.withType(Test).configureEach {
   it.systemProperty JvmOptions.FILE_ENCODING_KEY, StandardCharsets.UTF_8
}

tasks.withType(Javadoc).configureEach {
  it.with {
    options.encoding = StandardCharsets.UTF_8
    // StandardJavadocDocletOptions
    options.charSet = StandardCharsets.UTF_8
    options.docEncoding = StandardCharsets.UTF_8
  }
}

jar.manifest {
  attributes 'Automatic-Module-Name': 'module-name'
}  

publishing.publications {
    maven(MavenPublication) {
        from components.java
    }
}

task.jacocoTestReport.xml.required.set(true)

tasks.register('install') {
    dependsOn: publishToMavenLocal 
    group: 'publishing'
    doLast {
        logger.warn "INSTALLED $project.group:$project.name:$project.version"
    }
}

Java platform boilerplate

plugins { id 'java-platform' }

apply plugin: 'ru.vyarus.pom'

javaPlatform.allowDependencies()

maven.pom {
  name = 'custom-name'                // if differs from project name
  description = 'custom description'
}

publishing.publications {
  bom(MavenPublication) {
    from components.javaPlatform
    artifactId = 'custom-name'      // if differs from project name
  }
}

jacocoTestReport.reports.xml.required.set(true)

tasks.register('install') {
  dependsOn: publishToMavenLocal
  group: 'publishing'
  doLast {
    logger.warn "INSTALLED $project.group:custom-name:$project.version"
  }
}

Reports aggregation boilerplate

task test (type: TestReport, description: 'Generates aggregated test report') {
    group = 'verification'
    destinationDir = project.file("${project.buildDir}/reports/tests/test")
    reportOn project.subprojects.findAll { it.plugins.hasPlugin(JavaPlugin) }.test
}

def projectsWithCoverage = project.subprojects.findAll { it.plugins.hasPlugin(JacocoPlugin) }

task jacocoTestReport (type: JacocoReport, description: 'Generates aggregated jacoco coverage report') {
    dependsOn 'test'
    group = 'verification'
    executionData project.files(projectsWithCoverage
            .collect { it.file("${it.buildDir}/jacoco/test.exec") })
            .filter { it.exists() }
    sourceDirectories.from = project.files(projectsWithCoverage.sourceSets.main.allSource.srcDirs)
    classDirectories.from = project.files(projectsWithCoverage.sourceSets.main.output)
    reports.xml.destination = project.file("$project.buildDir/reports/jacoco/test/jacocoTestReport.xml")
    reports.xml.required.set(true)
    reports.html.destination = project.file("$project.buildDir/reports/jacoco/test/html/")
}

htmlDependencyReport.projects = project.allprojects

Utility boilerplate

Signing:

signing {
  sign publishing.publications.maven    // or bom
  required = { !project.version.toString().endsWith('SNAPSHOT') }
}

Gradle metadata disabling

tasks.withType(GenerateModuleMetadata).configureEach {
    enabled = false
}

Open report:

task openDependencyReport(description: 'Opens gradle htmlDependencyReport in browser', group: 'help') {
  dependsOn 'htmlDependencyReport'
  doLast {
      java.awt.Desktop.desktop.open(file("build/reports/project/dependencies/root.${project.name}.html))
  }
}

Might also like


gradle plugin generator