blob: b1e2385fb68d2ba1311e00d0e5faac9bc4b40c88 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE
* file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
* to You 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
*
* http://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.
*/
import org.ajoberstar.grgit.Grgit
import java.time.Instant
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.time.format.FormatStyle
import java.util.regex.Pattern
import net.ltgt.gradle.errorprone.CheckSeverity
buildscript {
repositories { jcenter() // jcenter
}
dependencies { classpath "org.ajoberstar.grgit:grgit-core:3.1.1" }
}
plugins {
id 'com.diffplug.gradle.spotless' version '3.16.0'
id 'net.ltgt.errorprone' version '0.6'
id 'io.spring.dependency-management' version '1.0.6.RELEASE'
id 'com.github.hierynomus.license' version '0.15.0'
id 'org.gradle.crypto.checksum' version '1.1.0'
id 'org.jetbrains.kotlin.jvm' version '1.3.20'
id 'org.jetbrains.dokka' version '0.9.17'
id 'maven-publish'
id 'com.jfrog.bintray' version '1.8.3'
}
description = 'A set of libraries and other tools to aid development of blockchain and other decentralized software in Java and other JVM languages'
//////
// Sanity checks
if (!file("${rootDir}/eth-reference-tests/src/test/resources/eth2.0-tests/README.md").exists()) {
throw new GradleException("eth-reference-tests/src/test/resources/eth2.0-tests/README.md missing: please clone submodules (git submodule update --init --recursive)")
}
//////
// Version numbering
def versionNumber = '0.10.0'
def buildVersion = versionNumber + buildTag()
static String buildTag() {
if (System.getenv('BUILD_RELEASE') == 'true') {
return ''
}
if (System.getenv('BUILD_TIMESTAMP') != null) {
return DateTimeFormatter.ofPattern("-yyyyMMddHHmmss").withLocale(Locale.US).withZone( ZoneId.systemDefault() ).format(Instant.now())
}
return '-SNAPSHOT'
}
//////
// Default tasks and build aliases
defaultTasks 'checkLicenses', 'spotlessCheck', 'jar', 'test', ':javadoc'
def buildAliases = ['dev': [
'spotlessApply',
'checkLicenses',
':jar',
'test',
':javadoc'
]]
def expandedTaskList = []
gradle.startParameter.taskNames.each {
expandedTaskList << (buildAliases[it] ? buildAliases[it] : it)
}
gradle.startParameter.taskNames = expandedTaskList.flatten()
apply from: "${rootDir}/wrapper.gradle"
apply from: "${rootDir}/gradle/stage.gradle"
//////
// RAT checks
if (file('.git').exists()) {
apply from: "${rootDir}/gradle/rat.gradle"
rat {
// Exclude everything under the directory that git should be ignoring via .gitignore or that isn't checked in. These
// restrict us only to files that are checked in or are staged.
def repo = Grgit.open(currentDir: project.getRootDir())
excludes = {
def list = new ArrayList<String>(repo.clean(ignore: false, directories: true, dryRun: true))
// And some of the files that we have checked in should also be excluded from this check
list.addAll([
'.*\\.asc',
'\\w+/out/.*',
'eth-reference-tests/**',
'build',
'.*/build/**',
'.editorconfig',
'.idea/**',
'gradlew.bat',
'gradlew',
'toml/src/test/resources/**',
'.gitattributes',
'.*\\.kotlin_module',
'example-v0.4.0.toml',
'hard_example.toml',
'toml-v0.5.0-spec-example.toml',
])
return list
}
}
}
//////
// Gradle script formatting
spotless {
groovyGradle {
target '**/*.gradle'
greclipse().configFile(rootProject.file('gradle/greclipse-gradle-tuweni-style.properties'))
endWithNewline()
}
}
subprojects {
//////
// Source formatting
apply plugin: 'com.diffplug.gradle.spotless'
spotless {
java {
target project.fileTree(project.projectDir) {
include '**/*.java'
exclude '**/generated-src/**/*.*'
exclude '**/SECP256K1.java'
}
removeUnusedImports()
licenseHeaderFile rootProject.file('gradle/spotless.license.txt')
eclipse().configFile(rootProject.file('gradle/eclipse-java-tuweni-style.xml'))
importOrder 'org.apache', 'java', ''
endWithNewline()
}
kotlin {
licenseHeaderFile rootProject.file('gradle/spotless.license.txt')
ktlint().userData(['indent_size': '2', 'continuation_indent_size' : '2', 'max_line_length': '120'])
endWithNewline()
}
}
//////
// Parallel build execution
tasks.withType(Test) {
// If GRADLE_MAX_TEST_FORKS is not set, use half the available processors
maxParallelForks = (System.getenv('GRADLE_MAX_TEST_FORKS') ?:
(Runtime.runtime.availableProcessors().intdiv(2) ?: 1)).toInteger()
}
tasks.withType(JavaCompile) {
options.fork = true
options.incremental = true
options.encoding = 'UTF-8'
}
task allDependencies(type: DependencyReportTask) {}
}
//////
// Project defaults
allprojects {
apply plugin: 'java-library'
apply plugin: 'kotlin'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'jacoco'
apply plugin: 'com.jfrog.bintray'
apply plugin: 'net.ltgt.errorprone'
apply plugin: 'maven-publish'
apply plugin: 'org.jetbrains.dokka'
apply plugin: 'signing'
apply from: "${rootDir}/dependency-versions.gradle"
apply from: "${rootDir}/gradle/check-licenses.gradle"
version = buildVersion
repositories { jcenter() }
//////
// Compiler arguments
sourceCompatibility = '1.8'
targetCompatibility = '1.8'
jacoco { toolVersion = '0.8.2' }
dependencies {
errorprone 'com.google.errorprone:error_prone_core'
if (JavaVersion.current().isJava8()) {
errorproneJavac("com.google.errorprone:javac")
}
}
tasks.withType(AbstractArchiveTask) {
preserveFileTimestamps = false
reproducibleFileOrder = true
}
tasks.withType(JavaCompile) {
// Until https://github.com/gradle/gradle/issues/2510 is resolved and
// something like a `releaseCompability` property is added, we have to add
// the --release flag explicitly
if (JavaVersion.current() > JavaVersion.VERSION_1_8) {
options.compilerArgs.addAll(['--release', '8'])
}
options.compilerArgs += [
'-Xlint:unchecked',
'-Xlint:cast',
'-Xlint:rawtypes',
'-Xlint:overloads',
'-Xlint:divzero',
'-Xlint:finally',
'-Xlint:static',
'-Werror'
]
options.errorprone {
excludedPaths '.*/generated-src/.*'
check('FutureReturnValueIgnored', CheckSeverity.OFF)
check('UnnecessaryParentheses', CheckSeverity.OFF)
disableWarningsInGeneratedCode = true
}
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
jvmTarget = "1.8"
allWarningsAsErrors = true
freeCompilerArgs = [
'-Xjsr305=strict',
'-Xjvm-default=enable',
'-Xuse-experimental=kotlin.Experimental'
]
}
}
//////
// Use JUnit5 for testing
test { useJUnitPlatform() { includeEngines 'spek', 'junit-jupiter' } }
//////
// Documentation
dokka {
outputFormat = 'html'
outputDirectory = "$buildDir/docs/dokka"
jdkVersion = 8
includeNonPublic = false
def relativePath = rootDir.toPath().relativize(projectDir.toPath()).toString()
linkMapping {
dir = projectDir.toString()
url = "https://github.com/apache/incubator-tuweni/blob/master/$relativePath"
suffix = "#L"
}
}
//////
// Artifact locations
jar {
destinationDir = file("${rootProject.buildDir}/libs")
}
task sourcesJar(type: Jar, dependsOn: classes) {
destinationDir = file("${rootProject.buildDir}/src")
classifier = 'sources'
from sourceSets.main.allSource
}
task javadocJar(type: Jar, dependsOn: javadoc) {
destinationDir = file("${rootProject.buildDir}/docs")
classifier = 'javadoc'
from javadoc.destinationDir
}
task dokkaJar(type: Jar, dependsOn: dokka) {
destinationDir = file("${rootProject.buildDir}/docs")
classifier = 'dokka'
from dokka.outputDirectory
}
//////
// Packaging and deployment
tasks.withType(Jar) {
if (rootProject == project) {
baseName = project.name
} else {
baseName = rootProject.name + '-' + project.name
}
manifest {
attributes('Implementation-Title': baseName,
'Implementation-Version': project.version)
}
from(rootProject.projectDir) {
include 'DISCLAIMER'
include 'LICENSE'
include 'NOTICE'
into 'META-INF'
}
}
if (project.name != 'eth-reference-tests' && project.name != 'dist') {
artifacts {
archives sourcesJar
archives jar
archives dokkaJar
}
signing {
useGpgCmd()
sign configurations.archives
}
publishing {
repositories {
maven {
def isRelease = buildVersion.endsWith('SNAPSHOT')
def releasesRepoUrl = "https://repository.apache.org/service/local/staging/deploy/maven2"
def snapshotsRepoUrl = "https://repository.apache.org/content/repositories/snapshots"
url = isRelease ? snapshotsRepoUrl : releasesRepoUrl
def settingsXml = new File(System.getProperty('user.home'), '.m2/settings.xml')
def credentialsFound = false;
if (settingsXml.exists()) {
project.logger.info('Reading .m2/settings.xml')
def serverId = (project.properties['distMgmtServerId'] ?: isRelease
? 'apache.releases.https' : 'apache.snapshots.https')
def m2SettingCreds = new XmlSlurper().parse(settingsXml).servers.server.find { server -> serverId.equals(server.id.text()) }
if (m2SettingCreds) {
project.logger.info('Found matching credentials from .m2/settings.xml')
credentials {
username m2SettingCreds.username.text()
password m2SettingCreds.password.text()
}
credentialsFound = true
}
}
if (!credentialsFound) {
project.logger.info('Reading credentials from environment')
project.logger.info('Username ' + asfNexusUsername)
credentials {
username asfNexusUsername
password asfNexusPassword
}
}
}
}
publications {
MavenDeployment(MavenPublication) { publication ->
if (project != rootProject) {
from components.java
artifact sourcesJar { classifier 'sources' }
}
artifact dokkaJar { classifier 'javadoc' }
groupId 'org.apache.tuweni'
artifactId project.jar.baseName
version project.version
pom {
name = project.jar.baseName
afterEvaluate { description = project.description }
url = 'https://github.com/apache/incubator-tuweni'
licenses {
license {
name = "The Apache License, Version 2.0"
url = "http://www.apache.org/licenses/LICENSE-2.0.txt"
}
}
scm {
connection = 'scm:https://github.com/apache/incubator-tuweni.git'
developerConnection = 'scm:git@github.com:apache/incubator-tuweni.git'
url = 'https://github.com/apache/incubator-tuweni'
}
developers {
developer {
name = 'Antoine Toulme'
email = 'antoine@lunar-ocean.com'
organization = 'Apache'
organizationUrl = 'https://tuweni.apache.org'
}
developer {
name = 'Jonny Rhea'
organization = 'Apache'
organizationUrl = 'https://tuweni.apache.org'
}
developer {
name = 'Steven J Schroeder'
email = 'sjs@apache.org'
organization = 'Apache'
organizationUrl = 'https://tuweni.apache.org'
}
}
issueManagement {
system = "jira"
url = "https://issues.apache.org/jira/projects/TUWENI"
}
}
pom.withXml {
// use inline versions rather than pom dependency management
asNode().remove(asNode().dependencyManagement[0])
if (asNode().dependencies[0]) {
asNode().remove(asNode().dependencies[0])
}
def dependenciesNode = asNode().appendNode('dependencies')
def addDependencyNode = { dep, optional ->
def dependencyNode = dependenciesNode.appendNode('dependency')
if (dep instanceof ProjectDependency) {
dependencyNode.appendNode('groupId', 'org.apache.tuweni')
dependencyNode.appendNode('artifactId', rootProject.name + '-' + dep.name)
dependencyNode.appendNode('version', dep.version)
} else {
dependencyNode.appendNode('groupId', dep.group)
dependencyNode.appendNode('artifactId', dep.name)
if (dep.version != null) {
dependencyNode.appendNode('version', dep.version)
} else {
def version = dependencyManagement.managedVersions["$dep.group:$dep.name"]
dependencyNode.appendNode('version', version)
}
}
if (optional) {
dependencyNode.appendNode('optional', 'true')
}
def ers = dep.excludeRules
if (!ers.empty) {
def exclusionsNode = dependencyNode.appendNode('exclusions')
ers.each { er ->
def exclusionNode = exclusionsNode.appendNode('exclusion')
exclusionNode.appendNode('groupId', er.group)
exclusionNode.appendNode('artifactId', er.module)
}
}
}
configurations.compile.allDependencies.each { dep ->
addDependencyNode(dep, false)
}
configurations.compileOnly.allDependencies.each { dep ->
addDependencyNode(dep, true)
}
if (System.getenv('ENABLE_SIGNING') == 'true') {
def pomFile = file("${project.buildDir}/generated-pom.xml")
writeTo(pomFile)
def pomAscFile = signing.sign(pomFile).signatureFiles[0]
artifact(pomAscFile) {
classifier = null
extension = 'pom.asc'
}
}
}
if (System.getenv('ENABLE_SIGNING') == 'true') {
// create the signed artifacts
tasks.signArchives.signatureFiles.each {
artifact(it) {
def matcher = it.file =~ /-(sources|javadoc)\.jar\.asc$/
if (matcher.find()) {
classifier = matcher.group(1)
} else {
classifier = null
}
extension = 'jar.asc'
}
}
}
}
}
}
tasks.withType(Sign) {
onlyIf {
System.getenv('ENABLE_SIGNING') == 'true'
}
}
model {
tasks.generatePomFileForMavenDeploymentPublication {
destination = file("$buildDir/generated-pom.xml")
}
tasks.publishMavenDeploymentPublicationToMavenLocal { dependsOn project.tasks.signArchives }
}
bintray {
publications = ['MavenDeployment']
user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : 'invalid'
key = project.hasProperty('bintrayKey') ? project.property('bintrayKey') : 'invalid'
pkg {
repo = project.hasProperty('bintrayRepo') ? project.property('bintrayRepo') : 'invalid'
name = project.hasProperty('bintrayName') ? project.property('bintrayName') : 'invalid'
userOrg = project.hasProperty('bintrayOrg') ? project.property('bintrayOrg') : 'invalid'
licenses = ['Apache-2.0']
vcsUrl = 'https://github.com/apache/incubator-tuweni.git'
}
}
}
}
//////
// Configure root project as a virtual package that depends on all components
dependencies {
subprojects.each { p ->
switch (p.name) {
case 'eth-reference-tests':
// ignore
break
case 'crypto':
compile(p) {
exclude group: 'com.github.jnr', module: 'jnr-ffi'
}
break
default:
compile p
break
}
}
}
jar {
subprojects.each { subproject ->
if (subproject.name != 'eth-reference-tests') {
from subproject.configurations.archives.collect { it.path.endsWith('.jar') }.files.collect { zipTree(it) }
}
}
}
javadoc {
subprojects.each {
source += it.javadoc.source
classpath += it.javadoc.classpath
}
}
dokka {
moduleName = rootProject.name
subprojects.each {
dependsOn it.classes
it.sourceSets.main.output.each { d ->
if (d.exists()) {
classpath += d
}
}
}
sourceDirs = files(subprojects.collect {
return [
new File(it.projectDir, '/src/main/kotlin'),
new File(it.projectDir, '/src/main/java')
]
})
linkMapping {
dir = rootDir.toString()
url = "https://github.com/apache/incubator-tuweni/blob/master"
suffix = "#L"
}
includes = ['PACKAGES.md']
externalDocumentationLink {
url = new URL("https://docs.oracle.com/javase/8/docs/api/")
}
externalDocumentationLink {
url = new URL('https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/')
}
}
dokkaJar {
baseName = rootProject.name
manifest {
attributes('Implementation-Title': baseName,
'Implementation-Version': project.version)
}
}