Avoid unnecessary eager creation of Gradle tasks (#45098) (#45310)

This commit is contained in:
Mark Vieira 2019-08-08 10:50:09 -07:00 committed by GitHub
parent b716b840d3
commit 0ae103c40f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 278 additions and 192 deletions

View File

@ -24,10 +24,13 @@ import org.elasticsearch.gradle.Version
import org.elasticsearch.gradle.BwcVersions import org.elasticsearch.gradle.BwcVersions
import org.elasticsearch.gradle.VersionProperties import org.elasticsearch.gradle.VersionProperties
import org.elasticsearch.gradle.plugin.PluginBuildPlugin import org.elasticsearch.gradle.plugin.PluginBuildPlugin
import org.elasticsearch.gradle.tool.Boilerplate
import org.gradle.util.GradleVersion import org.gradle.util.GradleVersion
import org.gradle.util.DistributionLocator import org.gradle.util.DistributionLocator
import org.gradle.plugins.ide.eclipse.model.SourceFolder import org.gradle.plugins.ide.eclipse.model.SourceFolder
import static org.elasticsearch.gradle.tool.Boilerplate.maybeConfigure
plugins { plugins {
id 'com.gradle.build-scan' version '2.3' id 'com.gradle.build-scan' version '2.3'
id 'base' id 'base'
@ -212,7 +215,7 @@ task branchConsistency {
allprojects { allprojects {
// ignore missing javadocs // ignore missing javadocs
tasks.withType(Javadoc) { Javadoc javadoc -> tasks.withType(Javadoc).configureEach { Javadoc javadoc ->
// the -quiet here is because of a bug in gradle, in that adding a string option // the -quiet here is because of a bug in gradle, in that adding a string option
// by itself is not added to the options. By adding quiet, both this option and // by itself is not added to the options. By adding quiet, both this option and
// the "value" -quiet is added, separated by a space. This is ok since the javadoc // the "value" -quiet is added, separated by a space. This is ok since the javadoc
@ -329,13 +332,9 @@ allprojects {
} }
} }
task cleanIdeaBuildDir(type: Delete) { tasks.named('cleanIdea') {
delete 'build-idea' delete 'build-idea'
} }
cleanIdeaBuildDir.setGroup("ide")
cleanIdeaBuildDir.setDescription("Deletes the IDEA build directory.")
tasks.cleanIdea.dependsOn(cleanIdeaBuildDir)
} }
idea { idea {
@ -390,29 +389,20 @@ allprojects {
String lineSeparator = Os.isFamily(Os.FAMILY_WINDOWS) ? '\\\\r\\\\n' : '\\\\n' String lineSeparator = Os.isFamily(Os.FAMILY_WINDOWS) ? '\\\\r\\\\n' : '\\\\n'
String licenseHeader = licenseHeaderFile.getText('UTF-8').replace(System.lineSeparator(), lineSeparator) String licenseHeader = licenseHeaderFile.getText('UTF-8').replace(System.lineSeparator(), lineSeparator)
task copyEclipseSettings(type: Copy) { tasks.register('copyEclipseSettings', Copy) {
mustRunAfter 'wipeEclipseSettings'
// TODO: "package this up" for external builds // TODO: "package this up" for external builds
from new File(project.rootDir, 'buildSrc/src/main/resources/eclipse.settings') from new File(project.rootDir, 'buildSrc/src/main/resources/eclipse.settings')
into '.settings' into '.settings'
filter{ it.replaceAll('@@LICENSE_HEADER_TEXT@@', licenseHeader)} filter{ it.replaceAll('@@LICENSE_HEADER_TEXT@@', licenseHeader)}
} }
// otherwise .settings is not nuked entirely // otherwise .settings is not nuked entirely
task wipeEclipseSettings(type: Delete) { tasks.register('wipeEclipseSettings', Delete) {
delete '.settings' delete '.settings'
} }
tasks.cleanEclipse.dependsOn(wipeEclipseSettings) tasks.named('cleanEclipse') { dependsOn 'wipeEclipseSettings' }
// otherwise the eclipse merging is *super confusing* // otherwise the eclipse merging is *super confusing*
tasks.eclipse.dependsOn(cleanEclipse, copyEclipseSettings) tasks.named('eclipse') { dependsOn 'cleanEclipse', 'copyEclipseSettings' }
// work arround https://github.com/gradle/gradle/issues/6582
tasks.eclipseProject.mustRunAfter tasks.cleanEclipseProject
tasks.matching { it.name == 'eclipseClasspath' }.all {
it.mustRunAfter { tasks.cleanEclipseClasspath }
}
tasks.matching { it.name == 'eclipseJdt' }.all {
it.mustRunAfter { tasks.cleanEclipseJdt }
}
tasks.copyEclipseSettings.mustRunAfter tasks.wipeEclipseSettings
} }
allprojects { allprojects {
@ -477,13 +467,11 @@ gradle.projectsEvaluated {
* need to publish artifacts for them. * need to publish artifacts for them.
*/ */
if (project.name.equals('qa') || project.path.contains(':qa:')) { if (project.name.equals('qa') || project.path.contains(':qa:')) {
Task assemble = project.tasks.findByName('assemble') maybeConfigure(project.tasks, 'assemble') {
if (assemble) { it.enabled = false
assemble.enabled = false
} }
Task dependenciesInfo = project.tasks.findByName('dependenciesInfo') maybeConfigure(project.tasks, 'dependenciesInfo') {
if (dependenciesInfo) { it.enabled = false
dependenciesInfo.enabled = false
} }
} }
} }
@ -505,7 +493,7 @@ gradle.projectsEvaluated {
} }
allprojects { allprojects {
task resolveAllDependencies { tasks.register('resolveAllDependencies') {
dependsOn tasks.matching { it.name == "pullFixture"} dependsOn tasks.matching { it.name == "pullFixture"}
doLast { doLast {
configurations.findAll { it.isCanBeResolved() }.each { it.resolve() } configurations.findAll { it.isCanBeResolved() }.each { it.resolve() }
@ -535,13 +523,13 @@ allprojects {
} }
} }
task checkPart1 def checkPart1 = tasks.register('checkPart1')
task checkPart2 def checkPart2 = tasks.register('checkPart2')
tasks.matching { it.name == "check" }.all { check -> plugins.withId('lifecycle-base') {
if (check.path.startsWith(":x-pack:")) { if (project.path.startsWith(":x-pack:")) {
checkPart2.dependsOn check checkPart1.configure { dependsOn 'check' }
} else { } else {
checkPart1.dependsOn check checkPart2.configure { dependsOn 'check' }
} }
} }
} }

View File

@ -18,6 +18,7 @@
*/ */
package org.elasticsearch.gradle package org.elasticsearch.gradle
import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import groovy.transform.CompileDynamic import groovy.transform.CompileDynamic
@ -66,6 +67,7 @@ import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
import org.gradle.api.publish.maven.tasks.GenerateMavenPom import org.gradle.api.publish.maven.tasks.GenerateMavenPom
import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.TaskProvider
import org.gradle.api.tasks.bundling.Jar import org.gradle.api.tasks.bundling.Jar
import org.gradle.api.tasks.compile.GroovyCompile import org.gradle.api.tasks.compile.GroovyCompile
import org.gradle.api.tasks.compile.JavaCompile import org.gradle.api.tasks.compile.JavaCompile
@ -82,10 +84,11 @@ import org.gradle.process.ExecSpec
import org.gradle.util.GradleVersion import org.gradle.util.GradleVersion
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import java.time.ZoneOffset import java.nio.file.Files
import java.time.ZonedDateTime
import java.util.regex.Matcher import java.util.regex.Matcher
import static org.elasticsearch.gradle.tool.Boilerplate.maybeConfigure
/** /**
* Encapsulates build configuration for elasticsearch projects. * Encapsulates build configuration for elasticsearch projects.
*/ */
@ -127,7 +130,7 @@ class BuildPlugin implements Plugin<Project> {
// apply global test task failure listener // apply global test task failure listener
project.rootProject.pluginManager.apply(TestFailureReportingPlugin) project.rootProject.pluginManager.apply(TestFailureReportingPlugin)
project.getTasks().create("buildResources", ExportElasticsearchBuildResourcesTask) project.getTasks().register("buildResources", ExportElasticsearchBuildResourcesTask)
setupSeed(project) setupSeed(project)
configureRepositories(project) configureRepositories(project)
@ -154,7 +157,7 @@ class BuildPlugin implements Plugin<Project> {
ExtraPropertiesExtension ext = project.extensions.getByType(ExtraPropertiesExtension) ExtraPropertiesExtension ext = project.extensions.getByType(ExtraPropertiesExtension)
// Common config when running with a FIPS-140 runtime JVM // Common config when running with a FIPS-140 runtime JVM
if (ext.has('inFipsJvm') && ext.get('inFipsJvm')) { if (ext.has('inFipsJvm') && ext.get('inFipsJvm')) {
project.tasks.withType(Test) { Test task -> project.tasks.withType(Test).configureEach { Test task ->
task.systemProperty 'javax.net.ssl.trustStorePassword', 'password' task.systemProperty 'javax.net.ssl.trustStorePassword', 'password'
task.systemProperty 'javax.net.ssl.keyStorePassword', 'password' task.systemProperty 'javax.net.ssl.keyStorePassword', 'password'
} }
@ -530,7 +533,7 @@ class BuildPlugin implements Plugin<Project> {
static void configurePomGeneration(Project project) { static void configurePomGeneration(Project project) {
// Only works with `enableFeaturePreview('STABLE_PUBLISHING')` // Only works with `enableFeaturePreview('STABLE_PUBLISHING')`
// https://github.com/gradle/gradle/issues/5696#issuecomment-396965185 // https://github.com/gradle/gradle/issues/5696#issuecomment-396965185
project.tasks.withType(GenerateMavenPom.class) { GenerateMavenPom generatePOMTask -> project.tasks.withType(GenerateMavenPom.class).configureEach({ GenerateMavenPom generatePOMTask ->
// The GenerateMavenPom task is aggressive about setting the destination, instead of fighting it, // The GenerateMavenPom task is aggressive about setting the destination, instead of fighting it,
// just make a copy. // just make a copy.
ExtraPropertiesExtension ext = generatePOMTask.extensions.getByType(ExtraPropertiesExtension) ExtraPropertiesExtension ext = generatePOMTask.extensions.getByType(ExtraPropertiesExtension)
@ -546,12 +549,15 @@ class BuildPlugin implements Plugin<Project> {
} }
} }
} }
} as Action<GenerateMavenPom>)
// build poms with assemble (if the assemble task exists) // build poms with assemble (if the assemble task exists)
Task assemble = project.tasks.findByName('assemble') maybeConfigure(project.tasks, 'assemble') { assemble ->
if (assemble && assemble.enabled) { if (assemble.enabled) {
assemble.dependsOn(generatePOMTask) assemble.dependsOn(project.tasks.withType(GenerateMavenPom))
} }
} }
project.plugins.withType(MavenPublishPlugin).whenPluginAdded { project.plugins.withType(MavenPublishPlugin).whenPluginAdded {
PublishingExtension publishing = project.extensions.getByType(PublishingExtension) PublishingExtension publishing = project.extensions.getByType(PublishingExtension)
publishing.publications.all { MavenPublication publication -> // we only deal with maven publishing.publications.all { MavenPublication publication -> // we only deal with maven
@ -607,7 +613,7 @@ class BuildPlugin implements Plugin<Project> {
project.afterEvaluate { project.afterEvaluate {
File compilerJavaHome = ext.get('compilerJavaHome') as File File compilerJavaHome = ext.get('compilerJavaHome') as File
project.tasks.withType(JavaCompile) { JavaCompile compileTask -> project.tasks.withType(JavaCompile).configureEach({ JavaCompile compileTask ->
final JavaVersion targetCompatibilityVersion = JavaVersion.toVersion(compileTask.targetCompatibility) final JavaVersion targetCompatibilityVersion = JavaVersion.toVersion(compileTask.targetCompatibility)
// we only fork if the Gradle JDK is not the same as the compiler JDK // we only fork if the Gradle JDK is not the same as the compiler JDK
if (compilerJavaHome.canonicalPath == Jvm.current().javaHome.canonicalPath) { if (compilerJavaHome.canonicalPath == Jvm.current().javaHome.canonicalPath) {
@ -644,9 +650,9 @@ class BuildPlugin implements Plugin<Project> {
// TODO: use native Gradle support for --release when available (cf. https://github.com/gradle/gradle/issues/2510) // TODO: use native Gradle support for --release when available (cf. https://github.com/gradle/gradle/issues/2510)
compileTask.options.compilerArgs << '--release' << targetCompatibilityVersion.majorVersion compileTask.options.compilerArgs << '--release' << targetCompatibilityVersion.majorVersion
} } as Action<JavaCompile>)
// also apply release flag to groovy, which is used in build-tools // also apply release flag to groovy, which is used in build-tools
project.tasks.withType(GroovyCompile) { GroovyCompile compileTask -> project.tasks.withType(GroovyCompile).configureEach({ GroovyCompile compileTask ->
// we only fork if the Gradle JDK is not the same as the compiler JDK // we only fork if the Gradle JDK is not the same as the compiler JDK
if (compilerJavaHome.canonicalPath == Jvm.current().javaHome.canonicalPath) { if (compilerJavaHome.canonicalPath == Jvm.current().javaHome.canonicalPath) {
compileTask.options.fork = false compileTask.options.fork = false
@ -655,19 +661,23 @@ class BuildPlugin implements Plugin<Project> {
compileTask.options.forkOptions.javaHome = compilerJavaHome compileTask.options.forkOptions.javaHome = compilerJavaHome
compileTask.options.compilerArgs << '--release' << JavaVersion.toVersion(compileTask.targetCompatibility).majorVersion compileTask.options.compilerArgs << '--release' << JavaVersion.toVersion(compileTask.targetCompatibility).majorVersion
} }
} } as Action<GroovyCompile>)
} }
} }
static void configureJavadoc(Project project) { static void configureJavadoc(Project project) {
// remove compiled classes from the Javadoc classpath: http://mail.openjdk.java.net/pipermail/javadoc-dev/2018-January/000400.html // remove compiled classes from the Javadoc classpath: http://mail.openjdk.java.net/pipermail/javadoc-dev/2018-January/000400.html
final List<File> classes = new ArrayList<>() final List<File> classes = new ArrayList<>()
project.tasks.withType(JavaCompile) { JavaCompile javaCompile -> project.tasks.withType(JavaCompile).configureEach { JavaCompile javaCompile ->
classes.add(javaCompile.destinationDir) classes.add(javaCompile.destinationDir)
} }
project.tasks.withType(Javadoc) { Javadoc javadoc -> project.tasks.withType(Javadoc).configureEach { Javadoc javadoc ->
File compilerJavaHome = project.extensions.getByType(ExtraPropertiesExtension).get('compilerJavaHome') as File File compilerJavaHome = project.extensions.getByType(ExtraPropertiesExtension).get('compilerJavaHome') as File
// only explicitly set javadoc executable if compiler JDK is different from Gradle
// this ensures better cacheability as setting ths input to an absolute path breaks portability
if (Files.isSameFile(compilerJavaHome.toPath(), Jvm.current().getJavaHome().toPath()) == false) {
javadoc.executable = new File(compilerJavaHome, 'bin/javadoc') javadoc.executable = new File(compilerJavaHome, 'bin/javadoc')
}
javadoc.classpath = javadoc.getClasspath().filter { f -> javadoc.classpath = javadoc.getClasspath().filter { f ->
return classes.contains(f) == false return classes.contains(f) == false
} }
@ -682,21 +692,27 @@ class BuildPlugin implements Plugin<Project> {
/** Adds a javadocJar task to generate a jar containing javadocs. */ /** Adds a javadocJar task to generate a jar containing javadocs. */
static void configureJavadocJar(Project project) { static void configureJavadocJar(Project project) {
Jar javadocJarTask = project.tasks.create('javadocJar', Jar) TaskProvider<Jar> javadocJarTask = project.tasks.register('javadocJar', Jar, { Jar jar ->
javadocJarTask.classifier = 'javadoc' jar.archiveClassifier.set('javadoc')
javadocJarTask.group = 'build' jar.group = 'build'
javadocJarTask.description = 'Assembles a jar containing javadocs.' jar.description = 'Assembles a jar containing javadocs.'
javadocJarTask.from(project.tasks.getByName(JavaPlugin.JAVADOC_TASK_NAME)) jar.from(project.tasks.named(JavaPlugin.JAVADOC_TASK_NAME))
project.tasks.getByName(BasePlugin.ASSEMBLE_TASK_NAME).dependsOn(javadocJarTask) } as Action<Jar>)
maybeConfigure(project.tasks, BasePlugin.ASSEMBLE_TASK_NAME) { Task t ->
t.dependsOn(javadocJarTask)
}
} }
static void configureSourcesJar(Project project) { static void configureSourcesJar(Project project) {
Jar sourcesJarTask = project.tasks.create('sourcesJar', Jar) TaskProvider<Jar> sourcesJarTask = project.tasks.register('sourcesJar', Jar, { Jar jar ->
sourcesJarTask.classifier = 'sources' jar.archiveClassifier.set('sources')
sourcesJarTask.group = 'build' jar.group = 'build'
sourcesJarTask.description = 'Assembles a jar containing source files.' jar.description = 'Assembles a jar containing source files.'
sourcesJarTask.from(project.extensions.getByType(SourceSetContainer).getByName(SourceSet.MAIN_SOURCE_SET_NAME).allSource) jar.from(project.extensions.getByType(SourceSetContainer).getByName(SourceSet.MAIN_SOURCE_SET_NAME).allSource)
project.tasks.getByName(BasePlugin.ASSEMBLE_TASK_NAME).dependsOn(sourcesJarTask) } as Action<Jar>)
maybeConfigure(project.tasks, BasePlugin.ASSEMBLE_TASK_NAME) { Task t ->
t.dependsOn(sourcesJarTask)
}
} }
/** Adds additional manifest info to jars */ /** Adds additional manifest info to jars */
@ -704,7 +720,7 @@ class BuildPlugin implements Plugin<Project> {
ExtraPropertiesExtension ext = project.extensions.getByType(ExtraPropertiesExtension) ExtraPropertiesExtension ext = project.extensions.getByType(ExtraPropertiesExtension)
ext.set('licenseFile', null) ext.set('licenseFile', null)
ext.set('noticeFile', null) ext.set('noticeFile', null)
project.tasks.withType(Jar) { Jar jarTask -> project.tasks.withType(Jar).configureEach { Jar jarTask ->
// we put all our distributable files under distributions // we put all our distributable files under distributions
jarTask.destinationDir = new File(project.buildDir, 'distributions') jarTask.destinationDir = new File(project.buildDir, 'distributions')
// fixup the jar manifest // fixup the jar manifest
@ -720,9 +736,10 @@ class BuildPlugin implements Plugin<Project> {
'Build-Date': ext.get('buildDate'), 'Build-Date': ext.get('buildDate'),
'Build-Java-Version': compilerJavaVersion) 'Build-Java-Version': compilerJavaVersion)
} }
}
// add license/notice files // add license/notice files
project.afterEvaluate { project.afterEvaluate {
project.tasks.withType(Jar).configureEach { Jar jarTask ->
if (ext.has('licenseFile') == false || ext.get('licenseFile') == null || ext.has('noticeFile') == false || ext.get('noticeFile') == null) { if (ext.has('licenseFile') == false || ext.get('licenseFile') == null || ext.has('noticeFile') == false || ext.get('noticeFile') == null) {
throw new GradleException("Must specify license and notice file for project ${project.path}") throw new GradleException("Must specify license and notice file for project ${project.path}")
} }
@ -748,8 +765,8 @@ class BuildPlugin implements Plugin<Project> {
* normal jar with the shadow jar so we no longer want to run * normal jar with the shadow jar so we no longer want to run
* the jar task. * the jar task.
*/ */
project.tasks.getByName(JavaPlugin.JAR_TASK_NAME).enabled = false project.tasks.named(JavaPlugin.JAR_TASK_NAME).configure { it.enabled = false }
project.tasks.getByName('shadowJar').configure { ShadowJar shadowJar -> project.tasks.named('shadowJar').configure { ShadowJar shadowJar ->
/* /*
* Replace the default "shadow" classifier with null * Replace the default "shadow" classifier with null
* which will leave the classifier off of the file name. * which will leave the classifier off of the file name.
@ -766,7 +783,9 @@ class BuildPlugin implements Plugin<Project> {
shadowJar.configurations = [project.configurations.getByName('bundle')] shadowJar.configurations = [project.configurations.getByName('bundle')]
} }
// Make sure we assemble the shadow jar // Make sure we assemble the shadow jar
project.tasks.getByName(BasePlugin.ASSEMBLE_TASK_NAME).dependsOn project.tasks.getByName('shadowJar') project.tasks.named(BasePlugin.ASSEMBLE_TASK_NAME).configure {
it.dependsOn project.tasks.named('shadowJar')
}
project.artifacts.add('apiElements', project.tasks.getByName('shadowJar')) project.artifacts.add('apiElements', project.tasks.getByName('shadowJar'))
} }
} }
@ -775,7 +794,7 @@ class BuildPlugin implements Plugin<Project> {
ExtraPropertiesExtension ext = project.extensions.getByType(ExtraPropertiesExtension) ExtraPropertiesExtension ext = project.extensions.getByType(ExtraPropertiesExtension)
// Default test task should run only unit tests // Default test task should run only unit tests
project.tasks.withType(Test).matching { Test task -> task.name == 'test' }.all { Test task -> maybeConfigure(project.tasks, 'test', Test) { Test task ->
task.include '**/*Tests.class' task.include '**/*Tests.class'
} }
@ -783,7 +802,7 @@ class BuildPlugin implements Plugin<Project> {
if (project.path != ':build-tools') { if (project.path != ':build-tools') {
File heapdumpDir = new File(project.buildDir, 'heapdump') File heapdumpDir = new File(project.buildDir, 'heapdump')
project.tasks.withType(Test) { Test test -> project.tasks.withType(Test).configureEach { Test test ->
File testOutputDir = new File(test.reports.junitXml.getDestination(), "output") File testOutputDir = new File(test.reports.junitXml.getDestination(), "output")
ErrorReportingTestListener listener = new ErrorReportingTestListener(test.testLogging, testOutputDir) ErrorReportingTestListener listener = new ErrorReportingTestListener(test.testLogging, testOutputDir)
@ -894,30 +913,37 @@ class BuildPlugin implements Plugin<Project> {
} }
private static configurePrecommit(Project project) { private static configurePrecommit(Project project) {
Task precommit = PrecommitTasks.create(project, true) TaskProvider precommit = PrecommitTasks.create(project, true)
project.tasks.getByName(LifecycleBasePlugin.CHECK_TASK_NAME).dependsOn(precommit) project.tasks.named(LifecycleBasePlugin.CHECK_TASK_NAME).configure { it.dependsOn(precommit) }
project.tasks.getByName(JavaPlugin.TEST_TASK_NAME).mustRunAfter(precommit) project.tasks.named(JavaPlugin.TEST_TASK_NAME).configure { it.mustRunAfter(precommit) }
// only require dependency licenses for non-elasticsearch deps // only require dependency licenses for non-elasticsearch deps
(project.tasks.getByName('dependencyLicenses') as DependencyLicensesTask).dependencies = project.configurations.getByName(JavaPlugin.RUNTIME_CONFIGURATION_NAME).fileCollection { Dependency dependency -> project.tasks.withType(DependencyLicensesTask).named('dependencyLicenses').configure {
it.dependencies = project.configurations.getByName(JavaPlugin.RUNTIME_CONFIGURATION_NAME).fileCollection { Dependency dependency ->
dependency.group.startsWith('org.elasticsearch') == false dependency.group.startsWith('org.elasticsearch') == false
} - project.configurations.getByName(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME) } - project.configurations.getByName(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME)
}
project.plugins.withType(ShadowPlugin).whenPluginAdded { project.plugins.withType(ShadowPlugin).whenPluginAdded {
(project.tasks.getByName('dependencyLicenses') as DependencyLicensesTask).dependencies += project.configurations.getByName('bundle').fileCollection { Dependency dependency -> project.tasks.withType(DependencyLicensesTask).named('dependencyLicenses').configure {
it.dependencies += project.configurations.getByName('bundle').fileCollection { Dependency dependency ->
dependency.group.startsWith('org.elasticsearch') == false dependency.group.startsWith('org.elasticsearch') == false
} }
} }
} }
}
private static configureDependenciesInfo(Project project) { private static configureDependenciesInfo(Project project) {
DependenciesInfoTask deps = project.tasks.create("dependenciesInfo", DependenciesInfoTask) TaskProvider<DependenciesInfoTask> deps = project.tasks.register("dependenciesInfo", DependenciesInfoTask, { DependenciesInfoTask task ->
deps.runtimeConfiguration = project.configurations.getByName(JavaPlugin.RUNTIME_CONFIGURATION_NAME) task.runtimeConfiguration = project.configurations.getByName(JavaPlugin.RUNTIME_CONFIGURATION_NAME)
project.plugins.withType(ShadowPlugin).whenPluginAdded { task.compileOnlyConfiguration = project.configurations.getByName(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME)
deps.runtimeConfiguration = project.configurations.create('infoDeps') task.getConventionMapping().map('mappings') {
deps.runtimeConfiguration.extendsFrom(project.configurations.getByName(JavaPlugin.RUNTIME_CONFIGURATION_NAME), project.configurations.getByName('bundle')) (project.tasks.getByName('dependencyLicenses') as DependencyLicensesTask).mappings
}
} as Action<DependenciesInfoTask>)
project.plugins.withType(ShadowPlugin).whenPluginAdded {
deps.configure { task ->
task.runtimeConfiguration = project.configurations.create('infoDeps')
task.runtimeConfiguration.extendsFrom(project.configurations.getByName(JavaPlugin.RUNTIME_CONFIGURATION_NAME), project.configurations.getByName('bundle'))
} }
deps.compileOnlyConfiguration = project.configurations.getByName(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME)
project.afterEvaluate {
deps.mappings = (project.tasks.getByName('dependencyLicenses') as DependencyLicensesTask).mappings
} }
} }

View File

@ -25,6 +25,7 @@ import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.Dependency import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.DependencyResolutionListener import org.gradle.api.artifacts.DependencyResolutionListener
import org.gradle.api.artifacts.DependencySet import org.gradle.api.artifacts.DependencySet
import org.gradle.api.internal.ConventionTask
import org.gradle.api.tasks.Input import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.OutputFile
@ -45,7 +46,7 @@ import java.util.regex.Pattern
* </ul> * </ul>
* *
*/ */
public class DependenciesInfoTask extends DefaultTask { public class DependenciesInfoTask extends ConventionTask {
/** Dependencies to gather information from. */ /** Dependencies to gather information from. */
@Input @Input
@ -55,8 +56,7 @@ public class DependenciesInfoTask extends DefaultTask {
@Input @Input
public Configuration compileOnlyConfiguration public Configuration compileOnlyConfiguration
@Input private LinkedHashMap<String, String> mappings
public LinkedHashMap<String, String> mappings
/** Directory to read license files */ /** Directory to read license files */
@InputDirectory @InputDirectory
@ -93,7 +93,7 @@ public class DependenciesInfoTask extends DefaultTask {
} }
final String url = createURL(dependency.group, dependency.name, dependency.version) final String url = createURL(dependency.group, dependency.name, dependency.version)
final String dependencyName = DependencyLicensesTask.getDependencyName(mappings, dependency.name) final String dependencyName = DependencyLicensesTask.getDependencyName(getMappings(), dependency.name)
logger.info("mapped dependency ${dependency.group}:${dependency.name} to ${dependencyName} for license info") logger.info("mapped dependency ${dependency.group}:${dependency.name} to ${dependencyName} for license info")
final String licenseType = getLicenseType(dependency.group, dependencyName) final String licenseType = getLicenseType(dependency.group, dependencyName)
@ -103,6 +103,14 @@ public class DependenciesInfoTask extends DefaultTask {
outputFile.setText(output.toString(), 'UTF-8') outputFile.setText(output.toString(), 'UTF-8')
} }
@Input
LinkedHashMap<String, String> getMappings() {
return mappings
}
void setMappings(LinkedHashMap<String, String> mappings) {
this.mappings = mappings
}
/** /**
* Create an URL on <a href="https://repo1.maven.org/maven2/">Maven Central</a> * Create an URL on <a href="https://repo1.maven.org/maven2/">Maven Central</a>
* based on dependency coordinates. * based on dependency coordinates.

View File

@ -32,6 +32,7 @@ import org.gradle.api.InvalidUserDataException
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
import org.gradle.api.publish.maven.tasks.GenerateMavenPom import org.gradle.api.publish.maven.tasks.GenerateMavenPom
@ -112,7 +113,7 @@ class PluginBuildPlugin implements Plugin<Project> {
addNoticeGeneration(project, extension) addNoticeGeneration(project, extension)
} }
} }
project.testingConventions { project.tasks.named('testingConventions').configure {
naming.clear() naming.clear()
naming { naming {
Tests { Tests {
@ -175,7 +176,7 @@ class PluginBuildPlugin implements Plugin<Project> {
/** Adds an integTest task which runs rest tests */ /** Adds an integTest task which runs rest tests */
private static void createIntegTestTask(Project project) { private static void createIntegTestTask(Project project) {
RestIntegTestTask integTest = project.tasks.create('integTest', RestIntegTestTask.class) RestIntegTestTask integTest = project.tasks.create('integTest', RestIntegTestTask.class)
integTest.mustRunAfter(project.precommit, project.test) integTest.mustRunAfter('precommit', 'test')
if (project.plugins.hasPlugin(TestClustersPlugin.class) == false) { if (project.plugins.hasPlugin(TestClustersPlugin.class) == false) {
// only if not using test clusters // only if not using test clusters
project.integTestCluster.distribution = System.getProperty('tests.distribution', 'integ-test-zip') project.integTestCluster.distribution = System.getProperty('tests.distribution', 'integ-test-zip')
@ -259,7 +260,9 @@ class PluginBuildPlugin implements Plugin<Project> {
include 'bin/**' include 'bin/**'
} }
} }
project.assemble.dependsOn(bundle) project.tasks.named(BasePlugin.ASSEMBLE_TASK_NAME).configure {
dependsOn(bundle)
}
// also make the zip available as a configuration (used when depending on this project) // also make the zip available as a configuration (used when depending on this project)
project.configurations.create('zip') project.configurations.create('zip')

View File

@ -26,11 +26,10 @@ import org.elasticsearch.gradle.VersionProperties
import org.elasticsearch.gradle.tool.ClasspathUtils import org.elasticsearch.gradle.tool.ClasspathUtils
import org.gradle.api.JavaVersion import org.gradle.api.JavaVersion
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Configuration
import org.gradle.api.plugins.JavaBasePlugin import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.plugins.quality.Checkstyle import org.gradle.api.plugins.quality.Checkstyle
import org.gradle.api.tasks.TaskProvider
/** /**
* Validation tasks which should be run before committing. These run before tests. * Validation tasks which should be run before committing. These run before tests.
@ -41,7 +40,7 @@ class PrecommitTasks {
public static final String CHECKSTYLE_VERSION = '8.20' public static final String CHECKSTYLE_VERSION = '8.20'
public static Task create(Project project, boolean includeDependencyLicenses) { public static TaskProvider create(Project project, boolean includeDependencyLicenses) {
project.configurations.create("forbiddenApisCliJar") project.configurations.create("forbiddenApisCliJar")
project.dependencies { project.dependencies {
forbiddenApisCliJar('de.thetaphi:forbiddenapis:2.6') forbiddenApisCliJar('de.thetaphi:forbiddenapis:2.6')
@ -57,12 +56,12 @@ class PrecommitTasks {
} }
} }
List<Task> precommitTasks = [ List<TaskProvider> precommitTasks = [
configureCheckstyle(project), configureCheckstyle(project),
configureForbiddenApisCli(project), configureForbiddenApisCli(project),
project.tasks.create('forbiddenPatterns', ForbiddenPatternsTask.class), project.tasks.register('forbiddenPatterns', ForbiddenPatternsTask),
project.tasks.create('licenseHeaders', LicenseHeadersTask.class), project.tasks.register('licenseHeaders', LicenseHeadersTask),
project.tasks.create('filepermissions', FilePermissionsTask.class), project.tasks.register('filepermissions', FilePermissionsTask),
configureJarHell(project, jarHellConfig), configureJarHell(project, jarHellConfig),
configureThirdPartyAudit(project), configureThirdPartyAudit(project),
configureTestingConventions(project) configureTestingConventions(project)
@ -71,11 +70,12 @@ class PrecommitTasks {
// tasks with just tests don't need dependency licenses, so this flag makes adding // tasks with just tests don't need dependency licenses, so this flag makes adding
// the task optional // the task optional
if (includeDependencyLicenses) { if (includeDependencyLicenses) {
DependencyLicensesTask dependencyLicenses = project.tasks.create('dependencyLicenses', DependencyLicensesTask.class) TaskProvider<DependencyLicensesTask> dependencyLicenses = project.tasks.register('dependencyLicenses', DependencyLicensesTask)
precommitTasks.add(dependencyLicenses) precommitTasks.add(dependencyLicenses)
// we also create the updateShas helper task that is associated with dependencyLicenses // we also create the updateShas helper task that is associated with dependencyLicenses
UpdateShasTask updateShas = project.tasks.create('updateShas', UpdateShasTask.class) project.tasks.register('updateShas', UpdateShasTask) {
updateShas.parentTask = dependencyLicenses it.parentTask = dependencyLicenses
}
} }
if (project.path != ':build-tools') { if (project.path != ':build-tools') {
/* /*
@ -93,22 +93,23 @@ class PrecommitTasks {
// We want to get any compilation error before running the pre-commit checks. // We want to get any compilation error before running the pre-commit checks.
project.sourceSets.all { sourceSet -> project.sourceSets.all { sourceSet ->
precommitTasks.each { task -> precommitTasks.each { provider ->
task.shouldRunAfter(sourceSet.getClassesTaskName()) provider.configure {
shouldRunAfter(sourceSet.getClassesTaskName())
}
} }
} }
return project.tasks.create([ return project.tasks.register('precommit') {
name : 'precommit', group = JavaBasePlugin.VERIFICATION_GROUP
group : JavaBasePlugin.VERIFICATION_GROUP, description = 'Runs all non-test checks.'
description: 'Runs all non-test checks.', dependsOn = precommitTasks
dependsOn : precommitTasks }
])
} }
static Task configureTestingConventions(Project project) { static TaskProvider configureTestingConventions(Project project) {
TestingConventionsTasks task = project.getTasks().create("testingConventions", TestingConventionsTasks.class) return project.getTasks().register("testingConventions", TestingConventionsTasks) {
task.naming { naming {
Tests { Tests {
baseClass "org.apache.lucene.util.LuceneTestCase" baseClass "org.apache.lucene.util.LuceneTestCase"
} }
@ -117,11 +118,11 @@ class PrecommitTasks {
baseClass 'org.elasticsearch.test.rest.ESRestTestCase' baseClass 'org.elasticsearch.test.rest.ESRestTestCase'
} }
} }
return task }
} }
private static Task configureJarHell(Project project, Configuration jarHelConfig) { private static TaskProvider configureJarHell(Project project, Configuration jarHelConfig) {
return project.tasks.create('jarHell', JarHellTask) { task -> return project.tasks.register('jarHell', JarHellTask) { task ->
task.classpath = project.sourceSets.test.runtimeClasspath + jarHelConfig; task.classpath = project.sourceSets.test.runtimeClasspath + jarHelConfig;
if (project.plugins.hasPlugin(ShadowPlugin)) { if (project.plugins.hasPlugin(ShadowPlugin)) {
task.classpath += project.configurations.bundle task.classpath += project.configurations.bundle
@ -130,9 +131,9 @@ class PrecommitTasks {
} }
} }
private static Task configureThirdPartyAudit(Project project) { private static TaskProvider configureThirdPartyAudit(Project project) {
ExportElasticsearchBuildResourcesTask buildResources = project.tasks.getByName('buildResources') ExportElasticsearchBuildResourcesTask buildResources = project.tasks.getByName('buildResources')
return project.tasks.create('thirdPartyAudit', ThirdPartyAuditTask.class) { task -> return project.tasks.register('thirdPartyAudit', ThirdPartyAuditTask) { task ->
task.dependsOn(buildResources) task.dependsOn(buildResources)
task.signatureFile = buildResources.copy("forbidden/third-party-audit.txt") task.signatureFile = buildResources.copy("forbidden/third-party-audit.txt")
task.javaHome = project.runtimeJavaHome task.javaHome = project.runtimeJavaHome
@ -140,10 +141,10 @@ class PrecommitTasks {
} }
} }
private static Task configureForbiddenApisCli(Project project) { private static TaskProvider configureForbiddenApisCli(Project project) {
project.pluginManager.apply(ForbiddenApisPlugin) project.pluginManager.apply(ForbiddenApisPlugin)
ExportElasticsearchBuildResourcesTask buildResources = project.tasks.getByName('buildResources') ExportElasticsearchBuildResourcesTask buildResources = project.tasks.getByName('buildResources')
project.tasks.withType(CheckForbiddenApis) { project.tasks.withType(CheckForbiddenApis).configureEach {
dependsOn(buildResources) dependsOn(buildResources)
doFirst { doFirst {
// we need to defer this configuration since we don't know the runtime java version until execution time // we need to defer this configuration since we don't know the runtime java version until execution time
@ -183,12 +184,14 @@ class PrecommitTasks {
) )
} }
} }
Task forbiddenApis = project.tasks.getByName("forbiddenApis") TaskProvider forbiddenApis = project.tasks.named("forbiddenApis")
forbiddenApis.group = "" forbiddenApis.configure {
group = ""
}
return forbiddenApis return forbiddenApis
} }
private static Task configureCheckstyle(Project project) { private static TaskProvider configureCheckstyle(Project project) {
// Always copy the checkstyle configuration files to 'buildDir/checkstyle' since the resources could be located in a jar // Always copy the checkstyle configuration files to 'buildDir/checkstyle' since the resources could be located in a jar
// file. If the resources are located in a jar, Gradle will fail when it tries to turn the URL into a file // file. If the resources are located in a jar, Gradle will fail when it tries to turn the URL into a file
URL checkstyleConfUrl = PrecommitTasks.getResource("/checkstyle.xml") URL checkstyleConfUrl = PrecommitTasks.getResource("/checkstyle.xml")
@ -196,18 +199,25 @@ class PrecommitTasks {
File checkstyleDir = new File(project.buildDir, "checkstyle") File checkstyleDir = new File(project.buildDir, "checkstyle")
File checkstyleSuppressions = new File(checkstyleDir, "checkstyle_suppressions.xml") File checkstyleSuppressions = new File(checkstyleDir, "checkstyle_suppressions.xml")
File checkstyleConf = new File(checkstyleDir, "checkstyle.xml"); File checkstyleConf = new File(checkstyleDir, "checkstyle.xml");
Task copyCheckstyleConf = project.tasks.create("copyCheckstyleConf") TaskProvider copyCheckstyleConf = project.tasks.register("copyCheckstyleConf")
// configure inputs and outputs so up to date works properly // configure inputs and outputs so up to date works properly
copyCheckstyleConf.outputs.files(checkstyleSuppressions, checkstyleConf) copyCheckstyleConf.configure {
outputs.files(checkstyleSuppressions, checkstyleConf)
}
if ("jar".equals(checkstyleConfUrl.getProtocol())) { if ("jar".equals(checkstyleConfUrl.getProtocol())) {
JarURLConnection jarURLConnection = (JarURLConnection) checkstyleConfUrl.openConnection() JarURLConnection jarURLConnection = (JarURLConnection) checkstyleConfUrl.openConnection()
copyCheckstyleConf.inputs.file(jarURLConnection.getJarFileURL()) copyCheckstyleConf.configure {
inputs.file(jarURLConnection.getJarFileURL())
}
} else if ("file".equals(checkstyleConfUrl.getProtocol())) { } else if ("file".equals(checkstyleConfUrl.getProtocol())) {
copyCheckstyleConf.inputs.files(checkstyleConfUrl.getFile(), checkstyleSuppressionsUrl.getFile()) copyCheckstyleConf.configure {
inputs.files(checkstyleConfUrl.getFile(), checkstyleSuppressionsUrl.getFile())
}
} }
copyCheckstyleConf.doLast { copyCheckstyleConf.configure {
doLast {
checkstyleDir.mkdirs() checkstyleDir.mkdirs()
// withStream will close the output stream and IOGroovyMethods#getBytes reads the InputStream fully and closes it // withStream will close the output stream and IOGroovyMethods#getBytes reads the InputStream fully and closes it
new FileOutputStream(checkstyleConf).withStream { new FileOutputStream(checkstyleConf).withStream {
@ -217,8 +227,11 @@ class PrecommitTasks {
it.write(checkstyleSuppressionsUrl.openStream().getBytes()) it.write(checkstyleSuppressionsUrl.openStream().getBytes())
} }
} }
}
Task checkstyleTask = project.tasks.create('checkstyle') TaskProvider checkstyleTask = project.tasks.register('checkstyle') {
dependsOn project.tasks.withType(Checkstyle)
}
// Apply the checkstyle plugin to create `checkstyleMain` and `checkstyleTest`. It only // Apply the checkstyle plugin to create `checkstyleMain` and `checkstyleTest`. It only
// creates them if there is main or test code to check and it makes `check` depend // creates them if there is main or test code to check and it makes `check` depend
// on them. We also want `precommit` to depend on `checkstyle`. // on them. We also want `precommit` to depend on `checkstyle`.
@ -231,8 +244,7 @@ class PrecommitTasks {
toolVersion = CHECKSTYLE_VERSION toolVersion = CHECKSTYLE_VERSION
} }
project.tasks.withType(Checkstyle) { task -> project.tasks.withType(Checkstyle).configureEach { task ->
checkstyleTask.dependsOn(task)
task.dependsOn(copyCheckstyleConf) task.dependsOn(copyCheckstyleConf)
task.inputs.file(checkstyleSuppressions) task.inputs.file(checkstyleSuppressions)
task.reports { task.reports {
@ -243,13 +255,13 @@ class PrecommitTasks {
return checkstyleTask return checkstyleTask
} }
private static Task configureLoggerUsage(Project project) { private static TaskProvider configureLoggerUsage(Project project) {
Object dependency = ClasspathUtils.isElasticsearchProject() ? project.project(':test:logger-usage') : Object dependency = ClasspathUtils.isElasticsearchProject() ? project.project(':test:logger-usage') :
"org.elasticsearch.test:logger-usage:${VersionProperties.elasticsearch}" "org.elasticsearch.test:logger-usage:${VersionProperties.elasticsearch}"
project.configurations.create('loggerUsagePlugin') project.configurations.create('loggerUsagePlugin')
project.dependencies.add('loggerUsagePlugin', dependency) project.dependencies.add('loggerUsagePlugin', dependency)
return project.tasks.create('loggerUsageCheck', LoggerUsageTask.class) { return project.tasks.register('loggerUsageCheck', LoggerUsageTask) {
classpath = project.configurations.loggerUsagePlugin classpath = project.configurations.loggerUsagePlugin
} }
} }

View File

@ -77,7 +77,7 @@ public class GlobalBuildInfoPlugin implements Plugin<Project> {
project.allprojects(p -> { project.allprojects(p -> {
// Make sure than any task execution generates and prints build info // Make sure than any task execution generates and prints build info
p.getTasks().all(task -> { p.getTasks().configureEach(task -> {
if (task != generateTask && task != printTask) { if (task != generateTask && task != printTask) {
task.dependsOn(printTask); task.dependsOn(printTask);
} }

View File

@ -23,6 +23,7 @@ import org.gradle.api.DefaultTask;
import org.gradle.api.logging.Logger; import org.gradle.api.logging.Logger;
import org.gradle.api.logging.Logging; import org.gradle.api.logging.Logging;
import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.TaskProvider;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@ -40,20 +41,20 @@ public class UpdateShasTask extends DefaultTask {
private final Logger logger = Logging.getLogger(getClass()); private final Logger logger = Logging.getLogger(getClass());
/** The parent dependency licenses task to use configuration from */ /** The parent dependency licenses task to use configuration from */
private DependencyLicensesTask parentTask; private TaskProvider<DependencyLicensesTask> parentTask;
public UpdateShasTask() { public UpdateShasTask() {
setDescription("Updates the sha files for the dependencyLicenses check"); setDescription("Updates the sha files for the dependencyLicenses check");
setOnlyIf(element -> parentTask.getLicensesDir() != null); setOnlyIf(element -> parentTask.get().getLicensesDir() != null);
} }
@TaskAction @TaskAction
public void updateShas() throws NoSuchAlgorithmException, IOException { public void updateShas() throws NoSuchAlgorithmException, IOException {
Set<File> shaFiles = parentTask.getShaFiles(); Set<File> shaFiles = parentTask.get().getShaFiles();
for (File dependency : parentTask.getDependencies()) { for (File dependency : parentTask.get().getDependencies()) {
String jarName = dependency.getName(); String jarName = dependency.getName();
File shaFile = parentTask.getShaFile(jarName); File shaFile = parentTask.get().getShaFile(jarName);
if (shaFile.exists() == false) { if (shaFile.exists() == false) {
createSha(dependency, jarName, shaFile); createSha(dependency, jarName, shaFile);
@ -71,16 +72,16 @@ public class UpdateShasTask extends DefaultTask {
private void createSha(File dependency, String jarName, File shaFile) throws IOException, NoSuchAlgorithmException { private void createSha(File dependency, String jarName, File shaFile) throws IOException, NoSuchAlgorithmException {
logger.lifecycle("Adding sha for " + jarName); logger.lifecycle("Adding sha for " + jarName);
String sha = parentTask.getSha1(dependency); String sha = parentTask.get().getSha1(dependency);
Files.write(shaFile.toPath(), sha.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE); Files.write(shaFile.toPath(), sha.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE);
} }
public DependencyLicensesTask getParentTask() { public DependencyLicensesTask getParentTask() {
return parentTask; return parentTask.get();
} }
public void setParentTask(DependencyLicensesTask parentTask) { public void setParentTask(TaskProvider<DependencyLicensesTask> parentTask) {
this.parentTask = parentTask; this.parentTask = parentTask;
} }
} }

View File

@ -123,7 +123,7 @@ public class TestClustersPlugin implements Plugin<Project> {
private void createUseClusterTaskExtension(Project project, NamedDomainObjectContainer<ElasticsearchCluster> container) { private void createUseClusterTaskExtension(Project project, NamedDomainObjectContainer<ElasticsearchCluster> container) {
// register an extension for all current and future tasks, so that any task can declare that it wants to use a // register an extension for all current and future tasks, so that any task can declare that it wants to use a
// specific cluster. // specific cluster.
project.getTasks().all((Task task) -> project.getTasks().configureEach((Task task) ->
task.getExtensions().findByType(ExtraPropertiesExtension.class) task.getExtensions().findByType(ExtraPropertiesExtension.class)
.set( .set(
"useCluster", "useCluster",

View File

@ -21,8 +21,12 @@ package org.elasticsearch.gradle.tool;
import org.gradle.api.Action; import org.gradle.api.Action;
import org.gradle.api.NamedDomainObjectContainer; import org.gradle.api.NamedDomainObjectContainer;
import org.gradle.api.Project; import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.UnknownTaskException;
import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.SourceSetContainer; import org.gradle.api.tasks.SourceSetContainer;
import org.gradle.api.tasks.TaskContainer;
import org.gradle.api.tasks.TaskProvider;
import java.util.Optional; import java.util.Optional;
@ -37,6 +41,7 @@ public abstract class Boilerplate {
.orElse(collection.create(name)); .orElse(collection.create(name));
} }
public static <T> T maybeCreate(NamedDomainObjectContainer<T> collection, String name, Action<T> action) { public static <T> T maybeCreate(NamedDomainObjectContainer<T> collection, String name, Action<T> action) {
return Optional.ofNullable(collection.findByName(name)) return Optional.ofNullable(collection.findByName(name))
.orElseGet(() -> { .orElseGet(() -> {
@ -47,4 +52,37 @@ public abstract class Boilerplate {
} }
public static void maybeConfigure(TaskContainer tasks, String name, Action<? super Task> config) {
TaskProvider<?> task;
try {
task = tasks.named(name);
} catch (UnknownTaskException e) {
return;
}
task.configure(config);
}
public static <T extends Task> void maybeConfigure(
TaskContainer tasks, String name,
Class<? extends T> type,
Action<? super T> config
) {
tasks.withType(type).configureEach(task -> {
if (task.getName().equals(name)) {
config.execute(task);
}
});
}
public static TaskProvider<?> findByName(TaskContainer tasks, String name) {
TaskProvider<?> task;
try {
task = tasks.named(name);
} catch (UnknownTaskException e) {
return null;
}
return task;
}
} }

View File

@ -1,11 +1,13 @@
package org.elasticsearch.gradle.precommit; package org.elasticsearch.gradle.precommit;
import org.elasticsearch.gradle.test.GradleUnitTestCase; import org.elasticsearch.gradle.test.GradleUnitTestCase;
import org.gradle.api.Action;
import org.gradle.api.GradleException; import org.gradle.api.GradleException;
import org.gradle.api.Project; import org.gradle.api.Project;
import org.gradle.api.artifacts.Dependency; import org.gradle.api.artifacts.Dependency;
import org.gradle.api.file.FileCollection; import org.gradle.api.file.FileCollection;
import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.testfixtures.ProjectBuilder; import org.gradle.testfixtures.ProjectBuilder;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
@ -31,7 +33,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
private UpdateShasTask updateShas; private UpdateShasTask updateShas;
private DependencyLicensesTask task; private TaskProvider<DependencyLicensesTask> task;
private Project project; private Project project;
@ -51,7 +53,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
expectedException.expectMessage(containsString("exists, but there are no dependencies")); expectedException.expectMessage(containsString("exists, but there are no dependencies"));
getLicensesDir(project).mkdir(); getLicensesDir(project).mkdir();
task.checkDependencies(); task.get().checkDependencies();
} }
@Test @Test
@ -60,12 +62,12 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
expectedException.expectMessage(containsString("does not exist, but there are dependencies")); expectedException.expectMessage(containsString("does not exist, but there are dependencies"));
project.getDependencies().add("compile", dependency); project.getDependencies().add("compile", dependency);
task.checkDependencies(); task.get().checkDependencies();
} }
@Test @Test
public void givenProjectWithoutLicensesDirNorDependenciesThenShouldReturnSilently() throws Exception { public void givenProjectWithoutLicensesDirNorDependenciesThenShouldReturnSilently() throws Exception {
task.checkDependencies(); task.get().checkDependencies();
} }
@Test @Test
@ -78,7 +80,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
createFileIn(licensesDir, "groovy-all-NOTICE.txt", ""); createFileIn(licensesDir, "groovy-all-NOTICE.txt", "");
project.getDependencies().add("compile", project.getDependencies().localGroovy()); project.getDependencies().add("compile", project.getDependencies().localGroovy());
task.checkDependencies(); task.get().checkDependencies();
} }
@Test @Test
@ -90,7 +92,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
getLicensesDir(project).mkdir(); getLicensesDir(project).mkdir();
updateShas.updateShas(); updateShas.updateShas();
task.checkDependencies(); task.get().checkDependencies();
} }
@Test @Test
@ -103,7 +105,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
createFileIn(getLicensesDir(project), "groovy-all-LICENSE.txt", ""); createFileIn(getLicensesDir(project), "groovy-all-LICENSE.txt", "");
updateShas.updateShas(); updateShas.updateShas();
task.checkDependencies(); task.get().checkDependencies();
} }
@Test @Test
@ -113,7 +115,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
File licensesDir = getLicensesDir(project); File licensesDir = getLicensesDir(project);
createAllDefaultDependencyFiles(licensesDir, "groovy-all"); createAllDefaultDependencyFiles(licensesDir, "groovy-all");
task.checkDependencies(); task.get().checkDependencies();
} }
@Test @Test
@ -127,7 +129,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
createAllDefaultDependencyFiles(licensesDir, "groovy-all"); createAllDefaultDependencyFiles(licensesDir, "groovy-all");
createFileIn(licensesDir, "non-declared-LICENSE.txt", ""); createFileIn(licensesDir, "non-declared-LICENSE.txt", "");
task.checkDependencies(); task.get().checkDependencies();
} }
@Test @Test
@ -141,7 +143,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
createAllDefaultDependencyFiles(licensesDir, "groovy-all"); createAllDefaultDependencyFiles(licensesDir, "groovy-all");
createFileIn(licensesDir, "non-declared-NOTICE.txt", ""); createFileIn(licensesDir, "non-declared-NOTICE.txt", "");
task.checkDependencies(); task.get().checkDependencies();
} }
@Test @Test
@ -155,7 +157,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
createAllDefaultDependencyFiles(licensesDir, "groovy-all"); createAllDefaultDependencyFiles(licensesDir, "groovy-all");
createFileIn(licensesDir, "non-declared.sha1", ""); createFileIn(licensesDir, "non-declared.sha1", "");
task.checkDependencies(); task.get().checkDependencies();
} }
@Test @Test
@ -175,7 +177,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
Files.write(groovySha, new byte[] { 1 }, StandardOpenOption.CREATE); Files.write(groovySha, new byte[] { 1 }, StandardOpenOption.CREATE);
task.checkDependencies(); task.get().checkDependencies();
} }
@Test @Test
@ -189,8 +191,8 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
mappings.put("from", "groovy-all"); mappings.put("from", "groovy-all");
mappings.put("to", "groovy"); mappings.put("to", "groovy");
task.mapping(mappings); task.get().mapping(mappings);
task.checkDependencies(); task.get().checkDependencies();
} }
@Test @Test
@ -201,8 +203,8 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
createFileIn(licensesDir, "groovy-all-LICENSE.txt", ""); createFileIn(licensesDir, "groovy-all-LICENSE.txt", "");
createFileIn(licensesDir, "groovy-all-NOTICE.txt", ""); createFileIn(licensesDir, "groovy-all-NOTICE.txt", "");
task.ignoreSha("groovy-all"); task.get().ignoreSha("groovy-all");
task.checkDependencies(); task.get().checkDependencies();
} }
@Test @Test
@ -210,7 +212,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
expectedException.expect(GradleException.class); expectedException.expect(GradleException.class);
expectedException.expectMessage(containsString("isn't a valid directory")); expectedException.expectMessage(containsString("isn't a valid directory"));
task.getShaFiles(); task.get().getShaFiles();
} }
private Project createProject() { private Project createProject() {
@ -244,7 +246,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
Files.write(file, content.getBytes(StandardCharsets.UTF_8)); Files.write(file, content.getBytes(StandardCharsets.UTF_8));
} }
private UpdateShasTask createUpdateShasTask(Project project, DependencyLicensesTask dependencyLicensesTask) { private UpdateShasTask createUpdateShasTask(Project project, TaskProvider<DependencyLicensesTask> dependencyLicensesTask) {
UpdateShasTask task = project.getTasks() UpdateShasTask task = project.getTasks()
.register("updateShas", UpdateShasTask.class) .register("updateShas", UpdateShasTask.class)
.get(); .get();
@ -253,12 +255,15 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase {
return task; return task;
} }
private DependencyLicensesTask createDependencyLicensesTask(Project project) { private TaskProvider<DependencyLicensesTask> createDependencyLicensesTask(Project project) {
DependencyLicensesTask task = project.getTasks() TaskProvider<DependencyLicensesTask> task = project.getTasks()
.register("dependencyLicenses", DependencyLicensesTask.class) .register("dependencyLicenses", DependencyLicensesTask.class, new Action<DependencyLicensesTask>() {
.get(); @Override
public void execute(DependencyLicensesTask dependencyLicensesTask) {
dependencyLicensesTask.setDependencies(getDependencies(project));
}
});
task.setDependencies(getDependencies(project));
return task; return task;
} }

View File

@ -2,11 +2,13 @@ package org.elasticsearch.gradle.precommit;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.elasticsearch.gradle.test.GradleUnitTestCase; import org.elasticsearch.gradle.test.GradleUnitTestCase;
import org.gradle.api.Action;
import org.gradle.api.GradleException; import org.gradle.api.GradleException;
import org.gradle.api.Project; import org.gradle.api.Project;
import org.gradle.api.artifacts.Dependency; import org.gradle.api.artifacts.Dependency;
import org.gradle.api.file.FileCollection; import org.gradle.api.file.FileCollection;
import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.tasks.TaskProvider;
import org.gradle.testfixtures.ProjectBuilder; import org.gradle.testfixtures.ProjectBuilder;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule; import org.junit.Rule;
@ -125,12 +127,15 @@ public class UpdateShasTaskTests extends GradleUnitTestCase {
return task; return task;
} }
private DependencyLicensesTask createDependencyLicensesTask(Project project) { private TaskProvider<DependencyLicensesTask> createDependencyLicensesTask(Project project) {
DependencyLicensesTask task = project.getTasks() TaskProvider<DependencyLicensesTask> task = project.getTasks()
.register("dependencyLicenses", DependencyLicensesTask.class) .register("dependencyLicenses", DependencyLicensesTask.class, new Action<DependencyLicensesTask>() {
.get(); @Override
public void execute(DependencyLicensesTask dependencyLicensesTask) {
dependencyLicensesTask.setDependencies(getDependencies(project));
}
});
task.setDependencies(getDependencies(project));
return task; return task;
} }