Skip to content

Commit

Permalink
[build] Backport last relevant build changes from 3.3 (reactor#2156)
Browse files Browse the repository at this point in the history
This includes:
 - using local buildSrc plugins rather than adhoc code blocks (detecting
 ci, java conventions, custom version)
 - splitting out javadoc/asciidoc gradle files
 - fixing the directory into which asciidocs are built
 - avoid building pdf reference guide locally (unless release)
 - remove spring-io-plugin / platform
 - bump asciidoctor.convert plugin
 - micrometer version defined in gradle.properties and pinned
 - reactiveStream version defined in gradle.properties
 - junit, awaitility, jol and testNg versions defined in properties
 rather than inline
 - use gradle enterprise plugin for buildScan
 - removed hamcrest-library dependency
 - automatic module names (see reactor#1692)

The shadow plugin has been removed in 3.2.x but will be reintroduced
in 3.3.x
  • Loading branch information
simonbasle authored May 14, 2020
1 parent b3c6230 commit 9a5f9cc
Show file tree
Hide file tree
Showing 14 changed files with 764 additions and 190 deletions.
188 changes: 83 additions & 105 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,92 +13,94 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

buildscript {
//we define kotlin version for benefit of both core and test (see kotlin-gradle-plugin below)
ext.kotlinVersion = '1.3.71'
repositories {
maven { url "https://repo.spring.io/plugins-release" }
}
dependencies {
classpath 'org.springframework.build.gradle:propdeps-plugin:0.0.7'
classpath 'io.spring.gradle:spring-io-plugin:0.0.4.RELEASE'
classpath 'com.github.jengelman.gradle.plugins:shadow:1.2.0'
classpath 'org.springframework.build.gradle:propdeps-plugin:0.0.7' //still uses the old ways
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}"
}
}


plugins {
id 'org.asciidoctor.convert' version '1.5.9.2'
id 'org.asciidoctor.convert' version '1.5.11'
id "me.champeau.gradle.jmh" version "0.4.7" apply false
id "org.jetbrains.dokka" version "0.9.18" apply false
id "me.champeau.gradle.japicmp" version "0.2.6"
id "de.undercouch.download" version "3.4.3"
//note: build scan plugin now must be applied in settings.gradle
id "com.jfrog.artifactory" version "4.9.8" apply false
id 'biz.aQute.bnd.builder' version '5.0.1' apply false
}

apply from: "gradle/doc.gradle"
apply plugin: "io.reactor.gradle.detect-ci"
apply from: "gradle/asciidoc.gradle" //asciidoc (which is generated from root dir)
apply from: "gradle/releaser.gradle"

ext {
//also set up the special version at root, for refguide
if (project.hasProperty('versionBranch') && version.toString().endsWith(".BUILD-SNAPSHOT")) {
versionBranch = versionBranch.replaceAll("\"", "").trim()
if (!versionBranch.isEmpty()) {
realVersion = version.toString().replace("BUILD-SNAPSHOT", versionBranch + ".BUILD-SNAPSHOT")
project.version = realVersion
jdk = JavaVersion.current().majorVersion
jdkJavadoc = "https://docs.oracle.com/javase/$jdk/docs/api/"
if (JavaVersion.current().isJava11Compatible()) {
jdkJavadoc = "https://docs.oracle.com/en/java/javase/$jdk/docs/api/"
}
}

// Metrics
micrometerVersion = 'latest.release' //TODO specify a version of micrometer?
println "JDK Javadoc link for this build is ${rootProject.jdkJavadoc}"

/*
* Note that some versions can be bumped by a script.
* These are found in `gradle.properties`...
*
* Versions not necessarily bumped by a script (testing, etc...) below:
*/
// Misc not often upgraded
jsr305Version = '3.0.2'
jsr166BackportVersion = '1.0.0.RELEASE'

// Logging
slf4jVersion = '1.7.12'
logbackVersion = '1.1.2'

// Testing
jUnitVersion = '4.13'
assertJVersion = '3.11.1'
mockitoVersion = '2.23.0'
jUnitParamsVersion = '1.1.1'
awaitilityVersion = '3.1.2'
javaObjectLayoutVersion = '0.9'
testNgVersion = '6.8.5'
}

jdk = JavaVersion.current().majorVersion
jdkJavadoc = "https://docs.oracle.com/javase/$jdk/docs/api/"
if (JavaVersion.current().isJava11Compatible()) {
jdkJavadoc = "https://docs.oracle.com/en/java/javase/$jdk/docs/api/"
}

javadocLinks = [jdkJavadoc,
"https://www.reactive-streams.org/reactive-streams-1.0.2-javadoc/"] as String[]
//only publish scan if a specific gradle entreprise server is passed
//typically, for local usage, you would temporarily set the env with:
// `GRADLE_ENTERPRISE_URL=https://myge.example.com/ gradle foo`
if (System.getenv('GRADLE_ENTERPRISE_URL')) {
gradleEnterprise {
buildScan {
captureTaskInputFiles = true
obfuscation {
ipAddresses { addresses -> addresses.collect { '0.0.0.0' } }
}
publishAlways()
server = System.getenv('GRADLE_ENTERPRISE_URL')
}
}
}

configure(subprojects) { p ->
apply plugin: 'java'
apply plugin: 'kotlin'
apply plugin: 'jacoco'
apply plugin: 'propdeps'
apply plugin: 'propdeps' //TODO replace with a simpler local plugin?
apply from: "${rootDir}/gradle/setup.gradle"

description = 'Non-Blocking Reactive Foundation for the JVM'
group = 'io.projectreactor'

ext {
//set up special version per sub-project
//(the root level configuration doesn't seem to propagate)
if (project.hasProperty('versionBranch') && version.toString().endsWith(".BUILD-SNAPSHOT")) {
versionBranch = versionBranch.replaceAll("\"", "").trim()
if (!versionBranch.isEmpty()) {
realVersion = p.version.toString().replace("BUILD-SNAPSHOT", versionBranch + ".BUILD-SNAPSHOT")
p.version = realVersion
println "Building special ${project} snapshot ${p.version}"
}
}
}

repositories {
mavenLocal()
if (version.endsWith('BUILD-SNAPSHOT') || project.hasProperty('platformVersion')) {
if (version.endsWith('BUILD-SNAPSHOT')) {
maven { url 'https://repo.spring.io/libs-snapshot' }
}

Expand All @@ -120,55 +122,6 @@ configure(subprojects) { p ->
}
}

[compileJava, compileTestJava]*.options*.encoding = 'UTF-8'
[compileJava, compileTestJava]*.options*.compilerArgs =
["-Xlint:-varargs", // intentionally disabled
"-Xlint:cast",
"-Xlint:classfile",
"-Xlint:dep-ann",
"-Xlint:divzero",
"-Xlint:empty",
"-Xlint:finally",
"-Xlint:overrides",
"-Xlint:path",
"-Xlint:processing",
"-Xlint:static",
"-Xlint:try",
"-Xlint:deprecation",
"-Xlint:unchecked",
"-Xlint:-serial", // intentionally disabled
"-Xlint:-options", // intentionally disabled
"-Xlint:-fallthrough", // intentionally disabled
"-Xlint:-rawtypes" // TODO enable and fix warnings
]

compileJava {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}

compileTestJava {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}

compileKotlin {
kotlinOptions.jvmTarget = "1.8"
kotlinOptions.freeCompilerArgs = ["-Xjsr305=strict"]
}

compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
kotlinOptions.freeCompilerArgs = ["-Xjsr305=strict"]
}

if (JavaVersion.current().isJava8Compatible()) {
compileTestJava.options.compilerArgs += "-parameters"
p.tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
}
}

//includes for base test task (see below for additional common configurations)
test {
include '**/*Tests.*'
Expand All @@ -187,14 +140,33 @@ configure(subprojects) { p ->
maxGranularity 3
}

if (isCiServer) {
def stdout = new LinkedList<TestOutputEvent>()
beforeTest { TestDescriptor td ->
stdout.clear()
}
onOutput { TestDescriptor td, TestOutputEvent toe ->
stdout.add(toe)
}
afterTest { TestDescriptor td, TestResult tr ->
if (tr.resultType == TestResult.ResultType.FAILURE && stdout.size() > 0) {
def stdOutput = stdout.collect {
it.getDestination().name() == "StdErr"
? "STD_ERR: ${it.getMessage()}"
: "STD_OUT: ${it.getMessage()}"
}
.join()
println "This is the console output of the failing test below:\n$stdOutput"
}
}
}

if (JavaVersion.current().isJava9Compatible()) {
println "Java 9+: lowering MaxGCPauseMillis to 20ms in ${project.name} ${name}"
jvmArgs = ["-XX:MaxGCPauseMillis=20"]
}

systemProperty("java.awt.headless", "true")
systemProperty("reactor.trace.cancel", "true")
systemProperty("reactor.trace.nocapacity", "true")
systemProperty("testGroups", p.properties.get("testGroups"))
scanForTestClasses = false
exclude '**/*Abstract*.*'
Expand All @@ -211,25 +183,31 @@ configure(subprojects) { p ->
}
}
}
}

// now that kotlin-gradle-plugin 1.1.60 is out with fix for https://youtrack.jetbrains.com/issue/KT-17564
// be wary and fail if the issue of source file duplication in jar comes up again
sourcesJar {
duplicatesStrategy = DuplicatesStrategy.FAIL
}
assemble.dependsOn docsZip

gradle.allprojects() { p ->
apply plugin: "io.reactor.gradle.custom-version"
}

if (project.hasProperty('platformVersion')) {
apply plugin: 'spring-io'

dependencyManagement {
springIoTestRuntime {
imports {
mavenBom "io.spring.platform:platform-bom:$platformVersion"
configure(subprojects) { p ->
//these apply once the above configure is done, but before project-specific build.gradle have applied
apply plugin: "io.reactor.gradle.java-conventions"
apply from: "${rootDir}/gradle/javadoc.gradle"

//these apply AFTER project-specific build.gradle have applied
afterEvaluate {
if (p.plugins.hasPlugin("kotlin")) {
println "Applying Kotlin conventions to ${p.name}"
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
kotlinOptions.freeCompilerArgs = ["-Xjsr305=strict"]
}
compileTestKotlin {
kotlinOptions.jvmTarget = "1.8"
kotlinOptions.freeCompilerArgs = ["-Xjsr305=strict"]
}
}
}
}

assemble.dependsOn docsZip
56 changes: 56 additions & 0 deletions buildSrc/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2011-Present Pivotal Software Inc, All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

plugins {
id 'java-gradle-plugin'
}

repositories {
mavenCentral()
jcenter()
gradlePluginPortal()
}

dependencies {
testImplementation("org.assertj:assertj-core:3.11.1")
testImplementation("org.junit.jupiter:junit-jupiter-api:5.5.2")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.5.2")
}

test {
useJUnitPlatform()
testLogging {
showStackTraces = true
exceptionFormat = "FULL"
}
}

gradlePlugin {
plugins {
customVersionPlugin {
id = "io.reactor.gradle.custom-version"
implementationClass = "io.reactor.gradle.CustomVersionPlugin"
}
detectCIPlugin {
id = "io.reactor.gradle.detect-ci"
implementationClass = "io.reactor.gradle.DetectCiPlugin"
}
javaConventionsPlugin {
id = "io.reactor.gradle.java-conventions"
implementationClass = "io.reactor.gradle.JavaConventions"
}
}
}
67 changes: 67 additions & 0 deletions buildSrc/src/main/java/io/reactor/gradle/CustomVersionPlugin.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright (c) 2011-Present Pivotal Software Inc, All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.reactor.gradle;

import java.util.regex.Pattern;

import org.gradle.api.InvalidUserDataException;
import org.gradle.api.Plugin;
import org.gradle.api.Project;

/**
* Looks for a {@code -PversionBranch=foo} type of property and uses that as an additional
* suffix between the patch number and the snapshot qualifier ({@code .BUILD-SNAPSHOT}), in
* order to generate branch-specific snapshots that can be used to eg. validate a PR.
* <p>
* The custom suffix must only contain alphanumeric characters.
*
* @author Simon Baslé
*/
public class CustomVersionPlugin implements Plugin<Project> {

private static final String CUSTOM_VERSION_PROPERTY = "versionBranch";
private static final String SNAPSHOT_SUFFIX = ".BUILD-SNAPSHOT";

private static final Pattern ONLY_ALPHANUMERIC_PATTERN = Pattern.compile("[A-Za-z0-9]+");

@Override
public void apply(Project project) {
String version = project.getVersion().toString();
Object versionBranchProperty = project.getProperties().get(CUSTOM_VERSION_PROPERTY);
if (versionBranchProperty == null) {
return;
}

String versionBranch = versionBranchProperty.toString();
//consider an empty string as "no custom version"
if (versionBranch.isEmpty()) {
return;
}
if (!ONLY_ALPHANUMERIC_PATTERN.matcher(versionBranch).matches()) {
throw new InvalidUserDataException("Custom version for project passed through -PversionBranch must be alphanumeric chars only: " + versionBranch);
}

if (!version.endsWith(SNAPSHOT_SUFFIX)) {
return;
}

String realVersion = version.replace(SNAPSHOT_SUFFIX, "." + versionBranch + SNAPSHOT_SUFFIX);
project.setVersion(realVersion);
System.out.println("Building custom snapshot for " + project + ": '" + project.getVersion());
}

}
Loading

0 comments on commit 9a5f9cc

Please sign in to comment.