line/gradle-scripts

Name: gradle-scripts

Owner: LINE

Description: Sensible multi-project defaults for Gradle

Created: 2018-02-02 09:08:34.0

Updated: 2018-05-09 06:18:00.0

Pushed: 2018-05-09 06:17:58.0

Homepage: null

Size: 15185

Language: CSS

GitHub Committers

UserMost Recent Commit# Commits

Other Committers

UserEmailMost Recent Commit# Commits

README

Sensible multi-project defaults for Gradle

The scripts here provides a simple way to configure a Java project with sensible defaults. By applying them, you can:

Table of Contents
Setup
  1. Run gradle wrapper to set up a new project.

    dir myproject
     myproject
    adle wrapper
    
    le/
    lew
    lew.bat
    
  2. Copy everything in this directory into <project_root>/gradle/scripts. If copied correctly, you should see the following ls command output:

     gradle/scripts
    
    d-flags.gradle
    ings-flags.gradle
    
  3. Add settings.gradle to apply settings-flags.gradle:

    Project.name = 'myproject'
    
    y from: "${rootDir}/gradle/scripts/settings-flags.gradle"
    
    udeWithFlags ':foo', 'java', 'publish'
    udeWithFlags ':bar', 'java'
    

    Unlike an ordinary settings.gradle, it uses a special directive called includeWithFlags which allows applying one or more flags to a project. Both project foo and bar have the java flag, which denotes a Java project. Project foo also has the publish flag, which means its artifact will be published to a Maven repository.

  4. Add build.gradle:

    dscript {
    epositories {
       mavenCentral()
    
    ependencies {
       classpath 'com.google.gradle:osdetector-gradle-plugin:1.4.0'
       classpath 'io.spring.gradle:dependency-management-plugin:1.0.5.RELEASE'
    
    
    
    y from: "${rootDir}/gradle/scripts/build-flags.gradle"
    

    Note that you have to apply build-flags.gradle only to the top-level build.gradle.

  5. Add gradle.properties that contains the necessary information to publish your artifacts to a Maven repository:

    p=com.doe.john.myexample
    ion=0.0.1-SNAPSHOT
    ectName=My Example
    ectUrl=https://www.example.com/
    ectDescription=My example project
    orName=John Doe
    orEmail=john@doe.com
    orUrl=https://john.doe.com/
    ptionYear=2018
    nseName=The Apache License, Version 2.0
    nseUrl=https://www.apache.org/license/LICENSE-2.0.txt
    rl=https://github.com/john.doe/example
    onnection=scm:git:https://github.com/john.doe/example.git
    eveloperConnection=scm:git:ssh://git@github.com/john.doe/example.git
    ishUrlForRelease=https://oss.sonatype.org/service/local/staging/deploy/maven2/
    ishUrlForSnapshot=https://oss.sonatype.org/content/repositories/snapshots/
    ishUsernameProperty=ossrhUsername
    ishPasswordProperty=ossrhPassword
    SourceCompatibility=1.8
    TargetCompatibility=1.8
    
  6. That's all. You now have two Java subprojects with sensible defaults. In the following sections, you'll learn how to make your project more useful.

Dependency management

Put your dependency versions into <project_root>/dependencies.yml so you don't need to put the version numbers in build.gradle:

mple form:
google.code.findbugs:
r305: { version: '3.0.2' }

ightly more verbose, but useful when an artifact has more than one property:
google.guava:
ava:
version: '23.6-jre'
exclusions:
- com.google.code.findbugs:jsr305
- com.google.errorprone:error_prone_annotations
- com.google.j2objc:j2objc-annotations
- org.codehaus.mojo:animal-sniffer-annotations

re than one artifact under the same group:
fasterxml.jackson.core:
ckson-annotations:
version: &JACKSON_VERSION '2.9.2' # Using a YAML anchor
javadocs:
- https://fasterxml.github.io/jackson-annotations/javadoc/2.9/
ckson-core:
version: *JACKSON_VERSION
javadocs:
- https://fasterxml.github.io/jackson-core/javadoc/2.9/
ckson-databind:
version: *JACKSON_VERSION
javadocs:
- https://fasterxml.github.io/jackson-databind/javadoc/2.9/

dependencies.yml will be parsed at project evaluation time and be fed into gradle-dependency-management plugin.

In build.gradle, you can specify these dependencies without version numbers:

dscript {
repositories {
    mavenCentral()
}
dependencies {
    classpath "com.google.gradle:osdetector-gradle-plugin:1.4.0"
}


rojects {
repositories {
    mavenCentral()
}


y from: "${rootDir}/gradle/scripts/build-flags.gradle"

onfigure all Java projects.
igure(projectsWithFlags('java')) {
// Common dependencies
dependencies {
    compileOnly 'com.google.code.findbugs:jsr305'
    compile 'com.google.guava:guava'
}


n case you need to get the version number of an artifact:
tln "Guava version: ${managedVersions['com.google.guava:guava']}"
Importing Maven BOM (Bill of Materials)

At dependencies.yml, you can add a special section called boms to specify the list of Maven BOMs to import:

:
.spring.platform:platform-bom:2.0.8.RELEASE
Checking if dependencies are up-to-date

gradle-versions-plugin is applied so you can conveniently check if your dependencies are out of date:

gradlew dependencyUpdates -Drevision=release

following dependencies have later integration versions:
om.google.guava:guava [17.0 -> 24.0-jre]
Built-in properties and functions

All projects will get the following extension properties:

Using flags

In build.gradle, you can retrieve the flags you specified with includeWithFlags in settings.gradle:

etting the flags of a project:
rojects {
println "Project '${project.path}' has flags: ${project.flags}"


inding the projects which have certain flags:
javaProjects = projectsWithFlags('java')
publishedJavaProjects = projectsWithFlags('java', 'publish')

onfiguring all Java projects:
igure(projectsWithFlags('java')) {
// Checking whether a project has certain set of flags.
if (project.hasFlags('publish')) {
    assert project.hasFlags('java', 'publish')
    println "A Java project '${project.path}' will be published to a Maven repository."
}

If you added the snippet above to build.gradle, ./gradlew will show the following output:

gradlew
nfigure project :
ect ':' has flags: []
ect ':bar' has flags: [java]
ect ':foo' has flags: [java, publish]
va project ':foo' will be published to a Maven repository.

Note that a flag can be any arbitrary string; you can define your own flags.

Built-in flags

Some flags, such as java, are used for configuring your projects automatically:

We will learn what these flags exactly do in the following sections.

Building Java projects with java flag

When a project has a java flag:

Publishing to Maven repository with publish flag
Generating Maven BOM with bom flag

If you configure a project with bom flag, the project will be configured to generate Maven BOM based on the dependencies specified in dependencies.yml.

bom flag implies publish flag, which means the BOM will be uploaded to a Maven repository by ./gradlew publish.

Building shaded JARs with shade flag

Let's say you have a project that depends on a very old version of Guava and you want to distribute the artifact that shades Guava to avoid the dependency version conflict with other projects that uses the latest version of Guava.

You can generate a shaded JAR very easily by adding shade flag:

ettings.gradle
Project.name = 'myproject'

y from: "${rootDir}/gradle/scripts/settings-flags.gradle"

udeWithFlags ':foo', 'java', 'shade'

You need to add relocations property to dependencies.yml to tell which dependency needs shading:

google.guava:
ava:
version: '17.0' # What an ancient dependency!
relocations:
- from: com.google.common
  to: com.doe.john.myproject.shaded.guava
- from: com.google.thirdparty.publicsuffix
  to: com.doe.john.myproject.shaded.publicsuffix
Trimming a shaded JAR with trim flag

If you shade many dependencies, your JAR will grow huge, even if you only use a fraction of the classes in shaded dependencies. Use trim instead of shade, then ProGuard plugin will strip the unused classes from the shaded JAR:

ettings.gradle
..
udeWithFlags ':foo', 'java', 'trim' // 'trim' implies 'shade'.

You also need to configure the trimShadedJar task to tell ProGuard which classes and members should not be stripped:

uild.gradle
igure(projectsWithFlags('trim')) {
tasks.trimShadedJar.configure {
    // Trim the classes under the shaded packages only.
    keep "class !com.doe.john.myproject.shaded.**,com.doe.john.myproject.** { *; }"
    // Whitelist the classes from Caffeine since it uses unsafe field access.
    keep "class com.doe.john.myproject.shaded.caffeine.** { *; }"
}

See ProGuard plugin manual for more information.

Shading a multi-module project with relocate flag
  1. Choose the core or common project which will contain the shaded classes. Add trim or shade flag to it and relocate flag to the others:

    ettings.gradle
    .
    udeWithFlags ':common', 'java', 'trim'
    udeWithFlags ':client', 'java', 'relocate'
    udeWithFlags ':server', 'java', 'relocate'
    
  2. Add the shaded dependencies to all subprojects:

    project_root>/build.gradle
    ..
    igure(projectsWithFlags('java')) {
    ependencies {
       compile 'com.google.guava'
    
    
    
Tagging conveniently with release task

The task called release is added at the top level project. It will update the version property in gradle.properties to a release version, create a tag and update the version property again to a next version.

gradlew release -PreleaseVersion=0.0.1 -PnextVersion=0.0.2-SNAPSHOT

ed: myproject-0.0.1

By default, the version number must match ^[0-9]+\.[0-9]+\.[0-9]+$. You can override this by setting versionPattern property in gradle.properties:

adle.properties
.
gular expression. Note escaped backslashes.
ionPattern=^[0-9]+\\.[0-9]+\\.[0-9]+\\.(Beta[0-9]+|RC[0-9]+|Release)$

You can add <project_root>/.post-release-msg file to print some additional instructions after tagging:

pload the artifacts to the staging repository:

it checkout ${tag}
/gradlew --no-daemon clean publish

lose and release the staging repository at:

ttps://oss.sonatype.org/

pdate the release note.
eploy the web site.

Note the ${tag}, which is replaced with the tag name. See Groovy SimpleTemplateEngine for the syntax.


This work is supported by the National Institutes of Health's National Center for Advancing Translational Sciences, Grant Number U24TR002306. This work is solely the responsibility of the creators and does not necessarily represent the official views of the National Institutes of Health.