// Copyright 2019 The Nomulus Authors. 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 // // 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. apply plugin: 'java' apply plugin: 'nebula.lint' apply plugin: 'net.ltgt.apt' apply plugin: 'net.ltgt.errorprone' apply plugin: 'checkstyle' apply plugin: 'jacoco' // Checkstyle should run as part of the testing task tasks.test.dependsOn tasks.checkstyleMain tasks.test.dependsOn tasks.checkstyleTest // Generate per-subproject reports in build/reports/jacoco directory. // TODO(weiminyu): publish periodical reports to well known location. // TODO(weiminyu): investigate incremental coverage change calculation and alert. tasks.test.finalizedBy jacocoTestReport // Exclude test-only dependencies from release artifacts. // TLDR: Project dependency should be on runtimeClasspath. A custom // configuration 'deploy_jar' is used as a proxy to expose runtimeClasspath // to other projects. It is also convenient to exclude test-only jars from // runtimeClasspath. // // Here is the context: // - Some dependencies have test-only jars on their 'compile' classpaths. // - As a result, they appear in our 'compile', 'runtimeClasspath' and // 'default' configurations, among others, and end up in our release war // files. // - Since these jars are needed for our own tests, we can only exclude them // from runtimeClasspath. Excluding them from 'compile' or 'runtime' would // also exclude them from testCompileClasspath and testRuntimeClasspath, // resulting in test failures. // - If configuration is not specified, project dependency uses the 'default' // configuration, which always has the same content as 'runtime'. // - When release is involved, 'runtimeClasspath' is actually the right // configuration to use. The 'runtime' configuration does not include // 'runtimeOnly' dependencies, while 'runtimeClasspath' does. // - 'runtimeClasspath' cannot be referenced directly by another project. // We use a custom configuration 'deploy_jar' as a proxy. // TODO(weiminyu): Fix all project dependencies to use deploy_jar configurations { deploy_jar.extendsFrom runtimeClasspath all.findAll { it.name in ['runtimeClasspath', 'compileClasspath'] }.each { // JUnit is from org.apache.beam:beam-runners-google-cloud-dataflow-java, // and json-simple. it.exclude group: 'junit' // Mockito is from org.apache.beam:beam-runners-google-cloud-dataflow-java // See https://issues.apache.org/jira/browse/BEAM-8862 it.exclude group: 'org.mockito', module: 'mockito-core' } } dependencies { // compatibility with Java 8 errorproneJavac("com.google.errorprone:javac:9+181-r4173-1") errorprone("com.google.errorprone:error_prone_core:2.3.3") } tasks.withType(JavaCompile).configureEach { // The -Werror flag causes Intellij to fail on deprecated api use. // Allow IDE user to turn off this flag by specifying a Gradle VM // option from inside the IDE. if (System.getProperty('no_werror') != 'true') { options.compilerArgs << "-Werror" } options.errorprone.disableWarningsInGeneratedCode = true options.errorprone.errorproneArgumentProviders.add([ asArguments: { return ['-XepExcludedPaths:.*/build/generated/.*'] }] as CommandLineArgumentProvider) // Disable features currently incompatible with Java 12 if ((JavaVersion.current().majorVersion as Integer) > 11) { // This check is broken in Java 12. // See https://github.com/google/error-prone/issues/1257 options.errorprone.errorproneArgs=['-Xep:Finally:OFF'] } } sourceCompatibility = '1.8' targetCompatibility = '1.8' compileJava { options.encoding = "UTF-8" } compileTestJava { options.encoding = "UTF-8" } gradleLint.rules = [ // Checks if Gradle wrapper is up-to-date 'archaic-wrapper', // Checks for indirect dependencies with dynamic version spec. Best // practice calls for declaring them with specific versions. 'undeclared-dependency', 'unused-dependency' // TODO(weiminyu): enable more dependency checks ] // To check or fix file formats, run the following commands from this directory: // - Check: ./gradlew spotlessCheck // - Format in place: ./gradlew spotlessApply spotless { format 'misc', { clearSteps() target '**/*.gradle' trimTrailingWhitespace() indentWithSpaces(2) endWithNewline() } } jacocoTestReport { // Use coverage data from all tests tasks, not just the one named 'test'. getExecutionData().setFrom(fileTree(buildDir).include("/jacoco/*.exec")) } // Initialize for coverage minimum determination for each sub project. task initCoverageMinimums { // Use current coverage ratio of each subproject as placeholder value. // Long-term plan is to calculate incremental coverage on the fly. rootProject.ext.coverageMinimums = [ 'core' : 0.6, 'proxy' : 0.52, 'util' : 0.57 ].asImmutable() rootProject.ext.getMinCoverage = { key -> if (rootProject.coverageMinimums.containsKey(key)) { return rootProject.coverageMinimums.get(key) } return 0.0 } } // Alerts for coverage violation. Note that, // - This task is FYI only and needs to be invoked explicitly. // - This task does not address incremental coverage. jacocoTestCoverageVerification { dependsOn initCoverageMinimums violationRules { rule { // Each limit consists of the following properties: // - An 'element' type: BUNDLE (default), PACKAGE, CLASS, SOURCEFILE, or METHOD. // - A 'counter' type: INSTRUCTION (default), LINE, BRANCH, COMPLEXITY, METHOD, or CLASS // - A 'value' type: TOTALCOUNT, COVEREDCOUNT, MISSEDCOUNT, COVEREDRATIO (default), // or MISSEDRATIO // - The 'minimum' threshold, given as a fraction or a percentage (including '%') limit { minimum = rootProject.getMinCoverage(project.getName()) } } } }