| /* |
| * 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. |
| */ |
| import org.apache.aurora.build.CoverageReportCheck |
| import org.gradle.api.JavaVersion |
| |
| plugins { |
| id 'com.eriwen.gradle.js' version '1.12.1' |
| id 'com.github.ben-manes.versions' version '0.11.3' |
| id 'com.github.hierynomus.license' version '0.11.0' |
| id 'me.champeau.gradle.jmh' version '0.2.0' |
| } |
| |
| apply plugin: 'application' |
| apply plugin: 'checkstyle' |
| apply plugin: 'findbugs' |
| apply plugin: 'jacoco' |
| apply plugin: 'pmd' |
| |
| def minJavaVersion = JavaVersion.VERSION_1_8; |
| |
| allprojects { |
| apply plugin: 'java' |
| apply plugin: 'idea' |
| apply plugin: 'maven-publish' |
| apply plugin: 'project-report' |
| |
| buildDir = 'dist' |
| |
| repositories { |
| mavenCentral() |
| } |
| |
| compileJava { |
| sourceCompatibility = minJavaVersion |
| targetCompatibility = minJavaVersion |
| } |
| |
| group 'org.apache.aurora' |
| version = file("${rootDir}/.auroraversion").text.trim().toUpperCase() |
| if (version.contains('/')) { |
| throw new GradleException(''' |
| ******************************************************************************* |
| The application version string read by gradle is invalid. This is known to |
| happen when building on Windows, or within vagrant with a Windows host. |
| You can work around this issue by cloning git _within_ vagrant and building |
| from there. |
| |
| For more details, please see https://issues.apache.org/jira/browse/AURORA-1169 |
| ******************************************************************************* |
| ''') |
| } |
| |
| task sourceJar(type: Jar) { |
| from sourceSets.main.allJava |
| } |
| |
| if (project.hasProperty('internalMavenUrl')) { |
| publishing { |
| repositories { |
| maven { |
| credentials { |
| username = internalMavenUser |
| password = internalMavenPass |
| } |
| url internalMavenUrl |
| } |
| } |
| } |
| } |
| |
| ext.commonsLangRev = '2.6' |
| ext.curatorRev = '2.11.1' |
| ext.gsonRev = '2.3.1' |
| ext.guavaRev = '20.0' |
| ext.guiceRev = '3.0' |
| ext.httpclientRev = '4.5.2' |
| ext.httpcoreRev = '4.4.4' |
| ext.jacksonRev = '2.5.1' |
| ext.jerseyRev = '1.19' |
| ext.jsrRev = '3.0.1' |
| ext.junitRev = '4.12' |
| ext.logbackRev = '1.2.3' |
| ext.mybatisRev = '3.4.1' |
| ext.protobufRev = '2.6.1' |
| ext.servletRev = '3.1.0' |
| ext.slf4jRev = '1.7.25' |
| ext.stringTemplateRev = '3.2.1' |
| ext.thriftRev = '0.9.1' |
| ext.zookeeperRev = '3.4.8' |
| |
| configurations { |
| compile { |
| exclude module: 'junit-dep' |
| // We use logback, so we do not want to pull in log4j artifacts. |
| exclude module: 'log4j' |
| exclude module: 'slf4j-log4j12' |
| |
| // ResolutionStrategy needs to be set in the allprojects block otherwise dependent projects |
| // will not inherit it. Note that dependencies still need to be specified in a dependencies |
| // block - this only affects strategy. |
| // See http://forums.gradle.org/gradle/topics/shouldnt-resolutionstrategy-affect-depending-projects-transitive-dependencies |
| resolutionStrategy { |
| failOnVersionConflict() |
| force "org.apache.httpcomponents:httpclient:${httpclientRev}" |
| force "org.apache.httpcomponents:httpcore:${httpcoreRev}" |
| force "com.fasterxml.jackson.core:jackson-annotations:${jacksonRev}" |
| force "com.fasterxml.jackson.core:jackson-core:${jacksonRev}" |
| force "com.google.code.gson:gson:${gsonRev}" |
| force "com.google.guava:guava:${guavaRev}" |
| force "com.google.protobuf:protobuf-java:${protobufRev}" |
| force "junit:junit:${junitRev}" |
| force "org.apache.thrift:libthrift:${thriftRev}" |
| force "org.apache.zookeeper:zookeeper:${zookeeperRev}" |
| force "org.hamcrest:hamcrest-core:1.3" |
| force "org.slf4j:slf4j-api:${slf4jRev}" |
| force "org.mybatis:mybatis:${mybatisRev}" |
| } |
| } |
| } |
| } |
| |
| /* This gradle project contains the annotation procesor from |
| * com.twitter.common.args and related dependencies. It needs to be outside of |
| * the commons project because gradle needs to compile the annotation processor |
| * first. |
| */ |
| project(':commons-args') { |
| dependencies { |
| compile "com.google.guava:guava:${guavaRev}" |
| compile "com.google.code.findbugs:jsr305:${jsrRev}" |
| compile "commons-lang:commons-lang:${commonsLangRev}" |
| } |
| |
| apply plugin: 'license' |
| license { |
| header rootProject.file('config/checkstyle/apache.header') |
| strictCheck true |
| } |
| } |
| |
| project(':commons') { |
| apply plugin: org.apache.aurora.build.ThriftPlugin |
| thrift { |
| version = thriftRev |
| } |
| |
| apply plugin: 'license' |
| license { |
| header rootProject.file('config/checkstyle/apache.header') |
| strictCheck true |
| } |
| |
| dependencies { |
| compile project(':commons-args') |
| |
| compile "com.google.code.findbugs:jsr305:${jsrRev}" |
| compile "com.google.code.gson:gson:${gsonRev}" |
| compile "com.google.guava:guava:${guavaRev}" |
| compile "com.google.inject.extensions:guice-multibindings:${guiceRev}" |
| compile "com.google.inject:guice:${guiceRev}" |
| compile "com.sun.jersey:jersey-core:${jerseyRev}" |
| compile "commons-lang:commons-lang:${commonsLangRev}" |
| compile "javax.servlet:javax.servlet-api:${servletRev}" |
| compile "joda-time:joda-time:2.9.1" |
| compile "org.antlr:stringtemplate:${stringTemplateRev}" |
| compile "org.apache.zookeeper:zookeeper:${zookeeperRev}" |
| compile "org.easymock:easymock:3.4" |
| |
| // There are a few testing support libs in the src/main/java trees that use junit - currently: |
| // src/main/java/org/apache/aurora/common/zookeeper/testing |
| // src/main/java/org/apache/aurora/common/testing |
| compile "junit:junit:${junitRev}" |
| |
| testCompile "junit:junit:${junitRev}" |
| testCompile "org.powermock:powermock-module-junit4:1.6.4" |
| testCompile "org.powermock:powermock-api-easymock:1.6.4" |
| } |
| } |
| |
| project(':api') { |
| apply plugin: org.apache.aurora.build.ThriftPlugin |
| apply plugin: org.apache.aurora.build.ThriftEntitiesPlugin |
| |
| task checkPython << { |
| def python27Executable = ['python2.7', 'python'].find { python -> |
| try { |
| def check = "import sys; sys.exit(0 if sys.version_info >= (2,7) and sys.version_info < (3,) else 1)" |
| return [python, "-c", check].execute().waitFor() == 0 |
| } catch (IOException e) { |
| return false |
| } |
| } |
| |
| if (python27Executable == null) { |
| throw new GradleException('Build requires Python 2.7.') |
| } else { |
| thriftEntities.python = python27Executable |
| } |
| } |
| generateThriftEntitiesJava.dependsOn checkPython |
| |
| tasks.withType(Jar) { |
| baseName "aurora-api" |
| } |
| |
| publishing { |
| publications { |
| mavenJava(MavenPublication) { |
| from components.java |
| |
| artifactId "aurora-api" |
| |
| artifact sourceJar { |
| classifier "sources" |
| } |
| } |
| } |
| } |
| |
| thrift { |
| version = thriftRev |
| resourcePrefix = 'org/apache/aurora/scheduler/gen/client' |
| } |
| |
| thriftEntities { |
| gsonRev = project.gsonRev |
| guavaRev = project.guavaRev |
| inputFiles = fileTree("src/main/thrift/org/apache/aurora/gen").matching { |
| include "**/*.thrift" |
| } |
| } |
| |
| idea { |
| module { |
| [thrift.genJavaDir, thriftEntities.genJavaDir].each { |
| sourceDirs += it |
| generatedSourceDirs += it |
| } |
| |
| // These directories must exist, else the plugin omits them from the |
| // generated project. Since this is executed during the configuration |
| // lifecycle phase, dependency tasks have not yet run and created |
| // the directories themselves. |
| // By default, the idea module [1] excludes are set to |
| // [project.buildDir, project.file('.gradle')] |
| // This has the side-effect of also excluding our generated sources [2]. Due to the way |
| // directory exclusion works in idea, you can't exclude a directory and include a child of that |
| // directory. Clearing the excludes seems to have no ill side-effects, making it preferable to |
| // other possible approaches. |
| // |
| // [1] http://www.gradle.org/docs/current/dsl/org.gradle.plugins.ide.idea.model.IdeaModule.html |
| // [2] http://issues.gradle.org/browse/GRADLE-1174 |
| excludeDirs = [file(".gradle")] |
| [ |
| "classes", |
| "dependency-cache", |
| "docs", |
| "jacoco", |
| "reports", |
| "test-results", |
| "tmp" |
| ].each { |
| excludeDirs << file("$buildDir/$it") |
| } |
| } |
| } |
| } |
| |
| def generatedDir = "$buildDir/generated-src" |
| def httpAssetsPath = 'scheduler/assets' |
| |
| compileJava { |
| options.compilerArgs << '-Werror' |
| options.compilerArgs << '-Xlint:all' |
| // Don't fail for annotations not claimed by annotation processors. |
| options.compilerArgs << '-Xlint:-processing' |
| // Don't fail for serialVersionUID warnings. |
| options.compilerArgs << '-Xlint:-serial' |
| // Capture method parameter names in classfiles. |
| options.compilerArgs << '-parameters' |
| } |
| |
| task enforceVersion { |
| def foundVersion = JavaVersion.current(); |
| if (foundVersion < minJavaVersion) { |
| throw new GradleException("Build requires at least Java ${minJavaVersion}; but ${foundVersion}" |
| + " was found. Consider setting JAVA_HOME to select a specific JDK on your system."); |
| } |
| } |
| |
| compileJava.dependsOn(enforceVersion); |
| |
| task wrapper(type: Wrapper) { |
| gradleVersion = project(':buildSrc').GRADLE_VERSION |
| } |
| |
| // TODO(ksweeney): Consider pushing this down to API - the scheduler implementation itself should |
| // only be consumed as an application. |
| publishing { |
| publications { |
| mavenJava(MavenPublication) { |
| from components.java |
| |
| artifactId 'aurora-scheduler' |
| |
| artifact sourceJar { |
| classifier "sources" |
| } |
| } |
| } |
| } |
| |
| task generateBuildProperties (type:Exec) { |
| def outputDir = file("${buildDir}/build-properties") |
| def outputFile = file("${outputDir}/build.properties") |
| outputs.upToDateWhen { false } |
| outputs.dir outputDir |
| doFirst { |
| outputDir.exists() || outputDir.mkdirs() |
| } |
| |
| commandLine "${projectDir}/build-support/generate-build-properties", "${outputFile}" |
| } |
| |
| sourceSets { |
| main { |
| output.dir generateBuildProperties |
| resources { |
| srcDir '3rdparty/javascript' |
| } |
| } |
| } |
| |
| dependencies { |
| def shiroRev = '1.2.5' |
| def jettyDep = '9.3.11.v20160721' |
| |
| compile project(':api') |
| compile project(':commons') |
| compile project(':commons-args') |
| |
| compile 'aopalliance:aopalliance:1.0' |
| compile "ch.qos.logback:logback-classic:${logbackRev}" |
| compile "com.google.code.findbugs:jsr305:${jsrRev}" |
| compile "com.google.inject:guice:${guiceRev}" |
| compile "com.google.inject.extensions:guice-assistedinject:${guiceRev}" |
| compile "com.google.protobuf:protobuf-java:${protobufRev}" |
| compile 'com.h2database:h2:1.4.193' |
| compile 'com.hubspot.jackson:jackson-datatype-protobuf:0.9.3' |
| compile "com.fasterxml.jackson.core:jackson-core:${jacksonRev}" |
| compile "com.sun.jersey:jersey-core:${jerseyRev}" |
| compile "com.sun.jersey:jersey-json:${jerseyRev}" |
| compile "com.sun.jersey:jersey-server:${jerseyRev}" |
| compile "com.sun.jersey:jersey-servlet:${jerseyRev}" |
| compile "com.sun.jersey.contribs:jersey-guice:${jerseyRev}" |
| compile 'javax.inject:javax.inject:1' |
| compile "javax.servlet:javax.servlet-api:${servletRev}" |
| compile "org.antlr:stringtemplate:${stringTemplateRev}" |
| compile "org.apache.curator:curator-client:${curatorRev}" |
| compile "org.apache.curator:curator-framework:${curatorRev}" |
| compile "org.apache.curator:curator-recipes:${curatorRev}" |
| compile 'org.apache.mesos:mesos:1.2.0' |
| compile "org.apache.httpcomponents:httpclient:${httpclientRev}" |
| compile "org.apache.httpcomponents:httpcore:${httpcoreRev}" |
| compile "org.apache.shiro:shiro-guice:${shiroRev}" |
| compile "org.apache.shiro:shiro-web:${shiroRev}" |
| compile "org.apache.zookeeper:zookeeper:${zookeeperRev}" |
| compile "org.eclipse.jetty:jetty-rewrite:${jettyDep}" |
| compile "org.eclipse.jetty:jetty-server:${jettyDep}" |
| compile "org.eclipse.jetty:jetty-servlet:${jettyDep}" |
| compile "org.eclipse.jetty:jetty-servlets:${jettyDep}" |
| compile "org.mybatis:mybatis:${mybatisRev}" |
| compile 'org.mybatis:mybatis-guice:3.7' |
| compile 'org.mybatis:mybatis-migrations:3.2.0' |
| compile 'org.quartz-scheduler:quartz:2.2.2' |
| compile "uno.perk:forward:1.0.0" |
| |
| testCompile "com.sun.jersey:jersey-client:${jerseyRev}" |
| testCompile "junit:junit:${junitRev}" |
| testCompile "org.powermock:powermock-module-junit4:1.6.4" |
| testCompile "org.powermock:powermock-api-easymock:1.6.4" |
| } |
| |
| // For normal developer builds, avoid running the often-time-consuming code quality checks. |
| // Jenkins will always run these, and developers are encouraged to run these before posting diffs |
| // and pushing to master. |
| def runCodeQuality = project.hasProperty('q') |
| def codeQualityTasks = [ |
| Checkstyle, |
| FindBugs, |
| nl.javadude.gradle.plugins.license.License, |
| Pmd |
| ] |
| codeQualityTasks.each { |
| tasks.withType(it) { |
| enabled = runCodeQuality |
| } |
| } |
| |
| checkstyle { |
| sourceSets = [sourceSets.main , sourceSets.test, sourceSets.jmh] |
| toolVersion = '7.3' |
| } |
| |
| findbugs { |
| toolVersion = '3.0.1' |
| effort = "max" |
| } |
| |
| tasks.withType(FindBugs) { |
| reports { |
| xml.enabled = false |
| html.enabled = true |
| } |
| maxHeapSize = '2g' |
| excludeFilter = rootProject.file('config/findbugs/excludeFilter.xml') |
| } |
| |
| pmd { |
| toolVersion = '5.5.3' |
| consoleOutput = true |
| } |
| |
| // As recommended here to work around PMD bugs exposed by otherwise |
| // handing it an `auxClasspath` to resolve types with: |
| // https://discuss.gradle.org/t/upgrading-gradle-from-2-7-to-2-8-results-in-pmd-false-positives/13460 |
| tasks.withType(Pmd) { |
| classpath = null |
| } |
| |
| pmdMain { |
| ruleSetFiles = files('config/pmd/common.xml', 'config/pmd/main.xml') |
| } |
| |
| pmdTest { |
| ruleSetFiles = files('config/pmd/common.xml', 'config/pmd/test.xml') |
| } |
| |
| /** |
| * There is a jshint target recommended in the README for gradle-js-plugin |
| * but it does not work. This workaround from here: |
| * https://github.com/eriwen/gradle-js-plugin/issues/73 |
| */ |
| task jsHint(type:com.eriwen.gradle.js.tasks.JsHintTask) { |
| source = fileTree("src/main/resources/$httpAssetsPath/js/") |
| dest file("${buildDir}/jshint.out") |
| // Set this to false once JS code complies with JSHint. |
| ignoreExitCode false |
| outputToStdOut true |
| jshint.options = [ |
| // See: http://www.jshint.com/docs/options/ for explanation. |
| browser: true, |
| camelcase: true, |
| curly: true, |
| eqeqeq: true, |
| indent: 2, |
| maxlen: 100, |
| quotmark: true, |
| trailing: true, |
| undef: true, |
| unused: 'vars', |
| white: true |
| ] |
| jshint.predef = [ |
| '_': true, |
| 'angular': true, |
| 'moment': true, |
| 'Thrift': true |
| ] |
| } |
| tasks.checkstyleMain.dependsOn(jsHint) |
| |
| tasks.withType(Test) { |
| maxParallelForks = Runtime.runtime.availableProcessors() |
| } |
| |
| // Turn on annotation processors for commons (uses commons-args) and aurora |
| // (uses commons-args, forward, ...). The crux here is _not_ turning annotation processing on |
| // for commons-args (this leads to an attempt at self-processing before its processor is |
| // compiled); so the strategy taken is to white-list modules. |
| // |
| // NB: Unfortunately, most of the ipr/iml modeling we need is not exposed by the idea plugin DSL so |
| // we drop to xml manipulation here only out of necessity. |
| def apt_projects = ['commons', 'aurora'] |
| |
| idea { |
| project { |
| vcs = 'Git' |
| jdkName = '1.8' |
| languageLevel = '1.8' |
| |
| ipr { |
| withXml { |
| def projectNode = it.asNode() |
| |
| // Configure an annotation processor profile. |
| def compilerConfiguration = projectNode.find { |
| it.name() == 'component' && it.@name == 'CompilerConfiguration' |
| } |
| def apt = compilerConfiguration.find { it.name() == 'annotationProcessing' } |
| // Turn on annotation processing only for the whitelisted modules. |
| apt.replaceNode { |
| annotationProcessing { |
| profile(default: 'true', name: 'Default', enabled: 'false') |
| profile(default: 'false', name: 'apt', enabled: 'true') { |
| sourceOutputDir(name: 'generated') |
| sourceTestOutputDir(name: 'generated') |
| processorPath(useClasspath: 'true') |
| apt_projects.each { |
| module(name: it) |
| } |
| } |
| } |
| } |
| def projectRoot = projectNode.find { |
| it.name() == 'component' && it.@name == 'ProjectRootManager' |
| } |
| projectRoot.remove(projectRoot.output) |
| |
| // Add parameter names to generated class file debug info. |
| projectNode |
| .appendNode('component', [name: 'JavacSettings']) |
| .appendNode('option', [name: 'ADDITIONAL_OPTIONS_STRING', value: '-parameters']) |
| } |
| } |
| } |
| } |
| |
| // Map output dirs explicitly per-module with the end goal of mapping the annotation processor |
| // generated code output dirs as source (and test) dirs. The key difficulty being worked around |
| // here is the fact that excludes higher in a directory tree override includes deeper in the tree. |
| allprojects { |
| def isApt = it.name in apt_projects |
| def generatedSourceDir = file("${it.projectDir}/out/production/generated") |
| def generatedTestDir = file("${it.projectDir}/out/test/generated") |
| |
| idea { |
| module { |
| if (isApt) { |
| generatedSourceDir.exists() || generatedSourceDir.mkdirs() |
| sourceDirs += generatedSourceDir |
| generatedSourceDirs += generatedSourceDir |
| |
| generatedTestDir.exists() || generatedTestDir.mkdirs() |
| testSourceDirs += generatedTestDir |
| generatedSourceDirs += generatedTestDir |
| } |
| |
| iml { |
| withXml { |
| def moduleNode = it.asNode() |
| def moduleConfiguration = moduleNode.find { |
| it.name() == 'component' && it.@name == 'NewModuleRootManager' |
| } |
| moduleConfiguration.attributes().remove('inherit-compiler-output') |
| moduleConfiguration.appendNode('output', [url: 'file://$MODULE_DIR$/out/production']) |
| moduleConfiguration.appendNode('output-test', [url: 'file://$MODULE_DIR$/out/test']) |
| |
| if (isApt) { |
| def excludeOutput = moduleConfiguration.find { it.name() == 'exclude-output' } |
| if (excludeOutput) { |
| moduleConfiguration.remove(excludeOutput) |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| // Configuration parameters for the application plugin. |
| applicationName = 'aurora-scheduler' |
| mainClassName = 'org.apache.aurora.scheduler.app.SchedulerMain' |
| |
| // TODO(ksweeney): Configure this to scan resources as well. |
| tasks.withType(nl.javadude.gradle.plugins.license.License).each { |
| it.source = files("$projectDir/src/main/java", "$projectDir/src/test/java") |
| } |
| |
| license { |
| header rootProject.file('config/checkstyle/apache.header') |
| strictCheck true |
| skipExistingHeaders true |
| } |
| |
| def reportPath = "$buildDir/reports/jacoco/test" |
| jacocoTestReport { |
| group = "Reporting" |
| description = "Generate Jacoco coverage reports after running tests." |
| |
| sourceDirectories = sourceSets.main.java |
| classDirectories = files("$buildDir/classes/main") |
| reports { |
| xml.enabled true |
| } |
| doLast { |
| println "Coverage report generated: file://$reportPath/html/index.html" |
| } |
| } |
| test.finalizedBy jacocoTestReport |
| |
| task analyzeReport(type: CoverageReportCheck) { |
| coverageReportFile = "$reportPath/jacocoTestReport.xml" |
| minInstructionCoverage = 0.89 |
| minBranchCoverage = 0.835 |
| legacyClassesWithoutCoverage = file('config/legacy_untested_classes.txt').readLines() |
| } |
| jacocoTestReport.finalizedBy analyzeReport |
| |
| def jmhHumanOutputPath = "$buildDir/reports/jmh/human.txt" |
| jmh { |
| // Run specific benchmarks by passing -Pbenchmarks='<regexp' on the command line. For example |
| // ./gradlew jmh -Pbenchmarks='ThriftApiBenchmarks.*' |
| if (project.hasProperty('benchmarks')) { |
| include = project.getProperty('benchmarks') |
| } |
| jmhVersion = '1.15' |
| jvmArgsPrepend = '-Xmx3g' |
| humanOutputFile = project.file("$jmhHumanOutputPath") |
| resultsFile = project.file("$buildDir/reports/jmh/results.txt") |
| } |
| tasks.getByName('jmh').doLast() { |
| println "Benchmark report generated: file://$jmhHumanOutputPath" |
| } |
| |
| run { |
| main = 'org.apache.aurora.scheduler.app.local.LocalSchedulerMain' |
| classpath += sourceSets.test.output |
| } |
| |
| startScripts { |
| def environmentClasspathPrefix = System.env.CLASSPATH_PREFIX |
| |
| if (!environmentClasspathPrefix?.trim()) { |
| return |
| } |
| |
| doLast { |
| unixScript.text = unixScript.text.replace('CLASSPATH=', "CLASSPATH=${environmentClasspathPrefix}:") |
| } |
| } |