diff --git a/build.gradle b/build.gradle index ba4f241080f..39010704ce0 100644 --- a/build.gradle +++ b/build.gradle @@ -24,10 +24,13 @@ import org.elasticsearch.gradle.Version import org.elasticsearch.gradle.BwcVersions import org.elasticsearch.gradle.VersionProperties import org.elasticsearch.gradle.plugin.PluginBuildPlugin +import org.elasticsearch.gradle.tool.Boilerplate import org.gradle.util.GradleVersion import org.gradle.util.DistributionLocator import org.gradle.plugins.ide.eclipse.model.SourceFolder +import static org.elasticsearch.gradle.tool.Boilerplate.maybeConfigure + plugins { id 'com.gradle.build-scan' version '2.3' id 'base' @@ -212,7 +215,7 @@ task branchConsistency { allprojects { // 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 // 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 @@ -329,13 +332,9 @@ allprojects { } } - task cleanIdeaBuildDir(type: Delete) { - delete 'build-idea' + tasks.named('cleanIdea') { + delete 'build-idea' } - cleanIdeaBuildDir.setGroup("ide") - cleanIdeaBuildDir.setDescription("Deletes the IDEA build directory.") - - tasks.cleanIdea.dependsOn(cleanIdeaBuildDir) } idea { @@ -390,29 +389,20 @@ allprojects { String lineSeparator = Os.isFamily(Os.FAMILY_WINDOWS) ? '\\\\r\\\\n' : '\\\\n' 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 from new File(project.rootDir, 'buildSrc/src/main/resources/eclipse.settings') into '.settings' filter{ it.replaceAll('@@LICENSE_HEADER_TEXT@@', licenseHeader)} } // otherwise .settings is not nuked entirely - task wipeEclipseSettings(type: Delete) { + tasks.register('wipeEclipseSettings', Delete) { delete '.settings' } - tasks.cleanEclipse.dependsOn(wipeEclipseSettings) + tasks.named('cleanEclipse') { dependsOn 'wipeEclipseSettings' } // otherwise the eclipse merging is *super confusing* - tasks.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 + tasks.named('eclipse') { dependsOn 'cleanEclipse', 'copyEclipseSettings' } } allprojects { @@ -477,13 +467,11 @@ gradle.projectsEvaluated { * need to publish artifacts for them. */ if (project.name.equals('qa') || project.path.contains(':qa:')) { - Task assemble = project.tasks.findByName('assemble') - if (assemble) { - assemble.enabled = false + maybeConfigure(project.tasks, 'assemble') { + it.enabled = false } - Task dependenciesInfo = project.tasks.findByName('dependenciesInfo') - if (dependenciesInfo) { - dependenciesInfo.enabled = false + maybeConfigure(project.tasks, 'dependenciesInfo') { + it.enabled = false } } } @@ -505,7 +493,7 @@ gradle.projectsEvaluated { } allprojects { - task resolveAllDependencies { + tasks.register('resolveAllDependencies') { dependsOn tasks.matching { it.name == "pullFixture"} doLast { configurations.findAll { it.isCanBeResolved() }.each { it.resolve() } @@ -535,13 +523,13 @@ allprojects { } } - task checkPart1 - task checkPart2 - tasks.matching { it.name == "check" }.all { check -> - if (check.path.startsWith(":x-pack:")) { - checkPart2.dependsOn check - } else { - checkPart1.dependsOn check - } - } + def checkPart1 = tasks.register('checkPart1') + def checkPart2 = tasks.register('checkPart2') + plugins.withId('lifecycle-base') { + if (project.path.startsWith(":x-pack:")) { + checkPart1.configure { dependsOn 'check' } + } else { + checkPart2.configure { dependsOn 'check' } + } + } } diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy index 1ad4a3f7d93..b303ba5f388 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy @@ -18,6 +18,7 @@ */ package org.elasticsearch.gradle + import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar 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.tasks.SourceSet import org.gradle.api.tasks.SourceSetContainer +import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.bundling.Jar import org.gradle.api.tasks.compile.GroovyCompile import org.gradle.api.tasks.compile.JavaCompile @@ -82,10 +84,11 @@ import org.gradle.process.ExecSpec import org.gradle.util.GradleVersion import java.nio.charset.StandardCharsets -import java.time.ZoneOffset -import java.time.ZonedDateTime +import java.nio.file.Files import java.util.regex.Matcher +import static org.elasticsearch.gradle.tool.Boilerplate.maybeConfigure + /** * Encapsulates build configuration for elasticsearch projects. */ @@ -127,7 +130,7 @@ class BuildPlugin implements Plugin { // apply global test task failure listener project.rootProject.pluginManager.apply(TestFailureReportingPlugin) - project.getTasks().create("buildResources", ExportElasticsearchBuildResourcesTask) + project.getTasks().register("buildResources", ExportElasticsearchBuildResourcesTask) setupSeed(project) configureRepositories(project) @@ -154,7 +157,7 @@ class BuildPlugin implements Plugin { ExtraPropertiesExtension ext = project.extensions.getByType(ExtraPropertiesExtension) // Common config when running with a FIPS-140 runtime JVM 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.keyStorePassword', 'password' } @@ -530,7 +533,7 @@ class BuildPlugin implements Plugin { static void configurePomGeneration(Project project) { // Only works with `enableFeaturePreview('STABLE_PUBLISHING')` // 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, // just make a copy. ExtraPropertiesExtension ext = generatePOMTask.extensions.getByType(ExtraPropertiesExtension) @@ -546,12 +549,15 @@ class BuildPlugin implements Plugin { } } } - // build poms with assemble (if the assemble task exists) - Task assemble = project.tasks.findByName('assemble') - if (assemble && assemble.enabled) { - assemble.dependsOn(generatePOMTask) + } as Action) + + // build poms with assemble (if the assemble task exists) + maybeConfigure(project.tasks, 'assemble') { assemble -> + if (assemble.enabled) { + assemble.dependsOn(project.tasks.withType(GenerateMavenPom)) } } + project.plugins.withType(MavenPublishPlugin).whenPluginAdded { PublishingExtension publishing = project.extensions.getByType(PublishingExtension) publishing.publications.all { MavenPublication publication -> // we only deal with maven @@ -607,7 +613,7 @@ class BuildPlugin implements Plugin { project.afterEvaluate { 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) // we only fork if the Gradle JDK is not the same as the compiler JDK if (compilerJavaHome.canonicalPath == Jvm.current().javaHome.canonicalPath) { @@ -644,9 +650,9 @@ class BuildPlugin implements Plugin { // TODO: use native Gradle support for --release when available (cf. https://github.com/gradle/gradle/issues/2510) compileTask.options.compilerArgs << '--release' << targetCompatibilityVersion.majorVersion - } + } as Action) // 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 if (compilerJavaHome.canonicalPath == Jvm.current().javaHome.canonicalPath) { compileTask.options.fork = false @@ -655,19 +661,23 @@ class BuildPlugin implements Plugin { compileTask.options.forkOptions.javaHome = compilerJavaHome compileTask.options.compilerArgs << '--release' << JavaVersion.toVersion(compileTask.targetCompatibility).majorVersion } - } + } as Action) } } static void configureJavadoc(Project project) { // remove compiled classes from the Javadoc classpath: http://mail.openjdk.java.net/pipermail/javadoc-dev/2018-January/000400.html final List classes = new ArrayList<>() - project.tasks.withType(JavaCompile) { JavaCompile javaCompile -> + project.tasks.withType(JavaCompile).configureEach { JavaCompile javaCompile -> 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 - javadoc.executable = new File(compilerJavaHome, 'bin/javadoc') + // 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.classpath = javadoc.getClasspath().filter { f -> return classes.contains(f) == false } @@ -682,21 +692,27 @@ class BuildPlugin implements Plugin { /** Adds a javadocJar task to generate a jar containing javadocs. */ static void configureJavadocJar(Project project) { - Jar javadocJarTask = project.tasks.create('javadocJar', Jar) - javadocJarTask.classifier = 'javadoc' - javadocJarTask.group = 'build' - javadocJarTask.description = 'Assembles a jar containing javadocs.' - javadocJarTask.from(project.tasks.getByName(JavaPlugin.JAVADOC_TASK_NAME)) - project.tasks.getByName(BasePlugin.ASSEMBLE_TASK_NAME).dependsOn(javadocJarTask) + TaskProvider javadocJarTask = project.tasks.register('javadocJar', Jar, { Jar jar -> + jar.archiveClassifier.set('javadoc') + jar.group = 'build' + jar.description = 'Assembles a jar containing javadocs.' + jar.from(project.tasks.named(JavaPlugin.JAVADOC_TASK_NAME)) + } as Action) + maybeConfigure(project.tasks, BasePlugin.ASSEMBLE_TASK_NAME) { Task t -> + t.dependsOn(javadocJarTask) + } } static void configureSourcesJar(Project project) { - Jar sourcesJarTask = project.tasks.create('sourcesJar', Jar) - sourcesJarTask.classifier = 'sources' - sourcesJarTask.group = 'build' - sourcesJarTask.description = 'Assembles a jar containing source files.' - sourcesJarTask.from(project.extensions.getByType(SourceSetContainer).getByName(SourceSet.MAIN_SOURCE_SET_NAME).allSource) - project.tasks.getByName(BasePlugin.ASSEMBLE_TASK_NAME).dependsOn(sourcesJarTask) + TaskProvider sourcesJarTask = project.tasks.register('sourcesJar', Jar, { Jar jar -> + jar.archiveClassifier.set('sources') + jar.group = 'build' + jar.description = 'Assembles a jar containing source files.' + jar.from(project.extensions.getByType(SourceSetContainer).getByName(SourceSet.MAIN_SOURCE_SET_NAME).allSource) + } as Action) + maybeConfigure(project.tasks, BasePlugin.ASSEMBLE_TASK_NAME) { Task t -> + t.dependsOn(sourcesJarTask) + } } /** Adds additional manifest info to jars */ @@ -704,7 +720,7 @@ class BuildPlugin implements Plugin { ExtraPropertiesExtension ext = project.extensions.getByType(ExtraPropertiesExtension) ext.set('licenseFile', 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 jarTask.destinationDir = new File(project.buildDir, 'distributions') // fixup the jar manifest @@ -720,9 +736,10 @@ class BuildPlugin implements Plugin { 'Build-Date': ext.get('buildDate'), 'Build-Java-Version': compilerJavaVersion) } - - // add license/notice files - project.afterEvaluate { + } + // add license/notice files + 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) { throw new GradleException("Must specify license and notice file for project ${project.path}") } @@ -748,8 +765,8 @@ class BuildPlugin implements Plugin { * normal jar with the shadow jar so we no longer want to run * the jar task. */ - project.tasks.getByName(JavaPlugin.JAR_TASK_NAME).enabled = false - project.tasks.getByName('shadowJar').configure { ShadowJar shadowJar -> + project.tasks.named(JavaPlugin.JAR_TASK_NAME).configure { it.enabled = false } + project.tasks.named('shadowJar').configure { ShadowJar shadowJar -> /* * Replace the default "shadow" classifier with null * which will leave the classifier off of the file name. @@ -766,7 +783,9 @@ class BuildPlugin implements Plugin { shadowJar.configurations = [project.configurations.getByName('bundle')] } // 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')) } } @@ -775,7 +794,7 @@ class BuildPlugin implements Plugin { ExtraPropertiesExtension ext = project.extensions.getByType(ExtraPropertiesExtension) // 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' } @@ -783,7 +802,7 @@ class BuildPlugin implements Plugin { if (project.path != ':build-tools') { 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") ErrorReportingTestListener listener = new ErrorReportingTestListener(test.testLogging, testOutputDir) @@ -894,30 +913,37 @@ class BuildPlugin implements Plugin { } private static configurePrecommit(Project project) { - Task precommit = PrecommitTasks.create(project, true) - project.tasks.getByName(LifecycleBasePlugin.CHECK_TASK_NAME).dependsOn(precommit) - project.tasks.getByName(JavaPlugin.TEST_TASK_NAME).mustRunAfter(precommit) + TaskProvider precommit = PrecommitTasks.create(project, true) + project.tasks.named(LifecycleBasePlugin.CHECK_TASK_NAME).configure { it.dependsOn(precommit) } + project.tasks.named(JavaPlugin.TEST_TASK_NAME).configure { it.mustRunAfter(precommit) } // 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 -> - dependency.group.startsWith('org.elasticsearch') == false - } - project.configurations.getByName(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME) - 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(JavaPlugin.RUNTIME_CONFIGURATION_NAME).fileCollection { Dependency dependency -> dependency.group.startsWith('org.elasticsearch') == false + } - project.configurations.getByName(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME) + } + project.plugins.withType(ShadowPlugin).whenPluginAdded { + project.tasks.withType(DependencyLicensesTask).named('dependencyLicenses').configure { + it.dependencies += project.configurations.getByName('bundle').fileCollection { Dependency dependency -> + dependency.group.startsWith('org.elasticsearch') == false + } } } } private static configureDependenciesInfo(Project project) { - DependenciesInfoTask deps = project.tasks.create("dependenciesInfo", DependenciesInfoTask) - deps.runtimeConfiguration = project.configurations.getByName(JavaPlugin.RUNTIME_CONFIGURATION_NAME) + TaskProvider deps = project.tasks.register("dependenciesInfo", DependenciesInfoTask, { DependenciesInfoTask task -> + task.runtimeConfiguration = project.configurations.getByName(JavaPlugin.RUNTIME_CONFIGURATION_NAME) + task.compileOnlyConfiguration = project.configurations.getByName(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME) + task.getConventionMapping().map('mappings') { + (project.tasks.getByName('dependencyLicenses') as DependencyLicensesTask).mappings + } + } as Action) project.plugins.withType(ShadowPlugin).whenPluginAdded { - deps.runtimeConfiguration = project.configurations.create('infoDeps') - deps.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 + deps.configure { task -> + task.runtimeConfiguration = project.configurations.create('infoDeps') + task.runtimeConfiguration.extendsFrom(project.configurations.getByName(JavaPlugin.RUNTIME_CONFIGURATION_NAME), project.configurations.getByName('bundle')) + } } } diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/DependenciesInfoTask.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/DependenciesInfoTask.groovy index 13e457c0317..aa01b1d7dfd 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/DependenciesInfoTask.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/DependenciesInfoTask.groovy @@ -25,6 +25,7 @@ import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.Dependency import org.gradle.api.artifacts.DependencyResolutionListener import org.gradle.api.artifacts.DependencySet +import org.gradle.api.internal.ConventionTask import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.OutputFile @@ -45,7 +46,7 @@ import java.util.regex.Pattern * * */ -public class DependenciesInfoTask extends DefaultTask { +public class DependenciesInfoTask extends ConventionTask { /** Dependencies to gather information from. */ @Input @@ -55,8 +56,7 @@ public class DependenciesInfoTask extends DefaultTask { @Input public Configuration compileOnlyConfiguration - @Input - public LinkedHashMap mappings + private LinkedHashMap mappings /** Directory to read license files */ @InputDirectory @@ -93,7 +93,7 @@ public class DependenciesInfoTask extends DefaultTask { } 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") final String licenseType = getLicenseType(dependency.group, dependencyName) @@ -103,7 +103,15 @@ public class DependenciesInfoTask extends DefaultTask { outputFile.setText(output.toString(), 'UTF-8') } - /** + @Input + LinkedHashMap getMappings() { + return mappings + } + + void setMappings(LinkedHashMap mappings) { + this.mappings = mappings + } +/** * Create an URL on Maven Central * based on dependency coordinates. */ diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/plugin/PluginBuildPlugin.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/plugin/PluginBuildPlugin.groovy index 692181710f4..b832f53b342 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/plugin/PluginBuildPlugin.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/plugin/PluginBuildPlugin.groovy @@ -32,6 +32,7 @@ import org.gradle.api.InvalidUserDataException import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.Task +import org.gradle.api.plugins.BasePlugin import org.gradle.api.publish.maven.MavenPublication import org.gradle.api.publish.maven.plugins.MavenPublishPlugin import org.gradle.api.publish.maven.tasks.GenerateMavenPom @@ -112,7 +113,7 @@ class PluginBuildPlugin implements Plugin { addNoticeGeneration(project, extension) } } - project.testingConventions { + project.tasks.named('testingConventions').configure { naming.clear() naming { Tests { @@ -175,7 +176,7 @@ class PluginBuildPlugin implements Plugin { /** Adds an integTest task which runs rest tests */ private static void createIntegTestTask(Project project) { 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) { // only if not using test clusters project.integTestCluster.distribution = System.getProperty('tests.distribution', 'integ-test-zip') @@ -259,7 +260,9 @@ class PluginBuildPlugin implements Plugin { 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) project.configurations.create('zip') diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/precommit/PrecommitTasks.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/precommit/PrecommitTasks.groovy index 7f3aa3edb0d..8127c485e19 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/precommit/PrecommitTasks.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/precommit/PrecommitTasks.groovy @@ -26,11 +26,10 @@ import org.elasticsearch.gradle.VersionProperties import org.elasticsearch.gradle.tool.ClasspathUtils import org.gradle.api.JavaVersion import org.gradle.api.Project -import org.gradle.api.Task import org.gradle.api.artifacts.Configuration import org.gradle.api.plugins.JavaBasePlugin -import org.gradle.api.plugins.JavaPluginConvention 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. @@ -41,7 +40,7 @@ class PrecommitTasks { 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.dependencies { forbiddenApisCliJar('de.thetaphi:forbiddenapis:2.6') @@ -57,12 +56,12 @@ class PrecommitTasks { } } - List precommitTasks = [ + List precommitTasks = [ configureCheckstyle(project), configureForbiddenApisCli(project), - project.tasks.create('forbiddenPatterns', ForbiddenPatternsTask.class), - project.tasks.create('licenseHeaders', LicenseHeadersTask.class), - project.tasks.create('filepermissions', FilePermissionsTask.class), + project.tasks.register('forbiddenPatterns', ForbiddenPatternsTask), + project.tasks.register('licenseHeaders', LicenseHeadersTask), + project.tasks.register('filepermissions', FilePermissionsTask), configureJarHell(project, jarHellConfig), configureThirdPartyAudit(project), configureTestingConventions(project) @@ -71,11 +70,12 @@ class PrecommitTasks { // tasks with just tests don't need dependency licenses, so this flag makes adding // the task optional if (includeDependencyLicenses) { - DependencyLicensesTask dependencyLicenses = project.tasks.create('dependencyLicenses', DependencyLicensesTask.class) + TaskProvider dependencyLicenses = project.tasks.register('dependencyLicenses', DependencyLicensesTask) precommitTasks.add(dependencyLicenses) // we also create the updateShas helper task that is associated with dependencyLicenses - UpdateShasTask updateShas = project.tasks.create('updateShas', UpdateShasTask.class) - updateShas.parentTask = dependencyLicenses + project.tasks.register('updateShas', UpdateShasTask) { + it.parentTask = dependencyLicenses + } } if (project.path != ':build-tools') { /* @@ -93,35 +93,36 @@ class PrecommitTasks { // We want to get any compilation error before running the pre-commit checks. project.sourceSets.all { sourceSet -> - precommitTasks.each { task -> - task.shouldRunAfter(sourceSet.getClassesTaskName()) + precommitTasks.each { provider -> + provider.configure { + shouldRunAfter(sourceSet.getClassesTaskName()) + } } } - return project.tasks.create([ - name : 'precommit', - group : JavaBasePlugin.VERIFICATION_GROUP, - description: 'Runs all non-test checks.', - dependsOn : precommitTasks - ]) + return project.tasks.register('precommit') { + group = JavaBasePlugin.VERIFICATION_GROUP + description = 'Runs all non-test checks.' + dependsOn = precommitTasks + } } - static Task configureTestingConventions(Project project) { - TestingConventionsTasks task = project.getTasks().create("testingConventions", TestingConventionsTasks.class) - task.naming { - Tests { - baseClass "org.apache.lucene.util.LuceneTestCase" - } - IT { - baseClass "org.elasticsearch.test.ESIntegTestCase" - baseClass 'org.elasticsearch.test.rest.ESRestTestCase' + static TaskProvider configureTestingConventions(Project project) { + return project.getTasks().register("testingConventions", TestingConventionsTasks) { + naming { + Tests { + baseClass "org.apache.lucene.util.LuceneTestCase" + } + IT { + baseClass "org.elasticsearch.test.ESIntegTestCase" + baseClass 'org.elasticsearch.test.rest.ESRestTestCase' + } } } - return task } - private static Task configureJarHell(Project project, Configuration jarHelConfig) { - return project.tasks.create('jarHell', JarHellTask) { task -> + private static TaskProvider configureJarHell(Project project, Configuration jarHelConfig) { + return project.tasks.register('jarHell', JarHellTask) { task -> task.classpath = project.sourceSets.test.runtimeClasspath + jarHelConfig; if (project.plugins.hasPlugin(ShadowPlugin)) { 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') - return project.tasks.create('thirdPartyAudit', ThirdPartyAuditTask.class) { task -> + return project.tasks.register('thirdPartyAudit', ThirdPartyAuditTask) { task -> task.dependsOn(buildResources) task.signatureFile = buildResources.copy("forbidden/third-party-audit.txt") 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) ExportElasticsearchBuildResourcesTask buildResources = project.tasks.getByName('buildResources') - project.tasks.withType(CheckForbiddenApis) { + project.tasks.withType(CheckForbiddenApis).configureEach { dependsOn(buildResources) doFirst { // 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") - forbiddenApis.group = "" + TaskProvider forbiddenApis = project.tasks.named("forbiddenApis") + forbiddenApis.configure { + group = "" + } 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 // 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") @@ -196,29 +199,39 @@ class PrecommitTasks { File checkstyleDir = new File(project.buildDir, "checkstyle") File checkstyleSuppressions = new File(checkstyleDir, "checkstyle_suppressions.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 - copyCheckstyleConf.outputs.files(checkstyleSuppressions, checkstyleConf) + copyCheckstyleConf.configure { + outputs.files(checkstyleSuppressions, checkstyleConf) + } if ("jar".equals(checkstyleConfUrl.getProtocol())) { JarURLConnection jarURLConnection = (JarURLConnection) checkstyleConfUrl.openConnection() - copyCheckstyleConf.inputs.file(jarURLConnection.getJarFileURL()) + copyCheckstyleConf.configure { + inputs.file(jarURLConnection.getJarFileURL()) + } } else if ("file".equals(checkstyleConfUrl.getProtocol())) { - copyCheckstyleConf.inputs.files(checkstyleConfUrl.getFile(), checkstyleSuppressionsUrl.getFile()) - } - - copyCheckstyleConf.doLast { - checkstyleDir.mkdirs() - // withStream will close the output stream and IOGroovyMethods#getBytes reads the InputStream fully and closes it - new FileOutputStream(checkstyleConf).withStream { - it.write(checkstyleConfUrl.openStream().getBytes()) - } - new FileOutputStream(checkstyleSuppressions).withStream { - it.write(checkstyleSuppressionsUrl.openStream().getBytes()) + copyCheckstyleConf.configure { + inputs.files(checkstyleConfUrl.getFile(), checkstyleSuppressionsUrl.getFile()) } } - Task checkstyleTask = project.tasks.create('checkstyle') + copyCheckstyleConf.configure { + doLast { + checkstyleDir.mkdirs() + // withStream will close the output stream and IOGroovyMethods#getBytes reads the InputStream fully and closes it + new FileOutputStream(checkstyleConf).withStream { + it.write(checkstyleConfUrl.openStream().getBytes()) + } + new FileOutputStream(checkstyleSuppressions).withStream { + it.write(checkstyleSuppressionsUrl.openStream().getBytes()) + } + } + } + + TaskProvider checkstyleTask = project.tasks.register('checkstyle') { + dependsOn project.tasks.withType(Checkstyle) + } // 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 // on them. We also want `precommit` to depend on `checkstyle`. @@ -231,8 +244,7 @@ class PrecommitTasks { toolVersion = CHECKSTYLE_VERSION } - project.tasks.withType(Checkstyle) { task -> - checkstyleTask.dependsOn(task) + project.tasks.withType(Checkstyle).configureEach { task -> task.dependsOn(copyCheckstyleConf) task.inputs.file(checkstyleSuppressions) task.reports { @@ -243,13 +255,13 @@ class PrecommitTasks { return checkstyleTask } - private static Task configureLoggerUsage(Project project) { + private static TaskProvider configureLoggerUsage(Project project) { Object dependency = ClasspathUtils.isElasticsearchProject() ? project.project(':test:logger-usage') : "org.elasticsearch.test:logger-usage:${VersionProperties.elasticsearch}" project.configurations.create('loggerUsagePlugin') project.dependencies.add('loggerUsagePlugin', dependency) - return project.tasks.create('loggerUsageCheck', LoggerUsageTask.class) { + return project.tasks.register('loggerUsageCheck', LoggerUsageTask) { classpath = project.configurations.loggerUsagePlugin } } diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/info/GlobalBuildInfoPlugin.java b/buildSrc/src/main/java/org/elasticsearch/gradle/info/GlobalBuildInfoPlugin.java index 1b6880277fe..bc5b9fb135e 100644 --- a/buildSrc/src/main/java/org/elasticsearch/gradle/info/GlobalBuildInfoPlugin.java +++ b/buildSrc/src/main/java/org/elasticsearch/gradle/info/GlobalBuildInfoPlugin.java @@ -77,7 +77,7 @@ public class GlobalBuildInfoPlugin implements Plugin { project.allprojects(p -> { // Make sure than any task execution generates and prints build info - p.getTasks().all(task -> { + p.getTasks().configureEach(task -> { if (task != generateTask && task != printTask) { task.dependsOn(printTask); } diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/precommit/UpdateShasTask.java b/buildSrc/src/main/java/org/elasticsearch/gradle/precommit/UpdateShasTask.java index db3148da696..c4dd1feb745 100644 --- a/buildSrc/src/main/java/org/elasticsearch/gradle/precommit/UpdateShasTask.java +++ b/buildSrc/src/main/java/org/elasticsearch/gradle/precommit/UpdateShasTask.java @@ -23,6 +23,7 @@ import org.gradle.api.DefaultTask; import org.gradle.api.logging.Logger; import org.gradle.api.logging.Logging; import org.gradle.api.tasks.TaskAction; +import org.gradle.api.tasks.TaskProvider; import java.io.File; import java.io.IOException; @@ -40,20 +41,20 @@ public class UpdateShasTask extends DefaultTask { private final Logger logger = Logging.getLogger(getClass()); /** The parent dependency licenses task to use configuration from */ - private DependencyLicensesTask parentTask; + private TaskProvider parentTask; public UpdateShasTask() { setDescription("Updates the sha files for the dependencyLicenses check"); - setOnlyIf(element -> parentTask.getLicensesDir() != null); + setOnlyIf(element -> parentTask.get().getLicensesDir() != null); } @TaskAction public void updateShas() throws NoSuchAlgorithmException, IOException { - Set shaFiles = parentTask.getShaFiles(); + Set shaFiles = parentTask.get().getShaFiles(); - for (File dependency : parentTask.getDependencies()) { + for (File dependency : parentTask.get().getDependencies()) { String jarName = dependency.getName(); - File shaFile = parentTask.getShaFile(jarName); + File shaFile = parentTask.get().getShaFile(jarName); if (shaFile.exists() == false) { 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 { 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); } public DependencyLicensesTask getParentTask() { - return parentTask; + return parentTask.get(); } - public void setParentTask(DependencyLicensesTask parentTask) { + public void setParentTask(TaskProvider parentTask) { this.parentTask = parentTask; } } diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/testclusters/TestClustersPlugin.java b/buildSrc/src/main/java/org/elasticsearch/gradle/testclusters/TestClustersPlugin.java index cb17f7a4026..1eef78c2962 100644 --- a/buildSrc/src/main/java/org/elasticsearch/gradle/testclusters/TestClustersPlugin.java +++ b/buildSrc/src/main/java/org/elasticsearch/gradle/testclusters/TestClustersPlugin.java @@ -123,7 +123,7 @@ public class TestClustersPlugin implements Plugin { private void createUseClusterTaskExtension(Project project, NamedDomainObjectContainer container) { // register an extension for all current and future tasks, so that any task can declare that it wants to use a // specific cluster. - project.getTasks().all((Task task) -> + project.getTasks().configureEach((Task task) -> task.getExtensions().findByType(ExtraPropertiesExtension.class) .set( "useCluster", diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/tool/Boilerplate.java b/buildSrc/src/main/java/org/elasticsearch/gradle/tool/Boilerplate.java index 29b0b5def20..70926c8982d 100644 --- a/buildSrc/src/main/java/org/elasticsearch/gradle/tool/Boilerplate.java +++ b/buildSrc/src/main/java/org/elasticsearch/gradle/tool/Boilerplate.java @@ -21,8 +21,12 @@ package org.elasticsearch.gradle.tool; import org.gradle.api.Action; import org.gradle.api.NamedDomainObjectContainer; 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.tasks.SourceSetContainer; +import org.gradle.api.tasks.TaskContainer; +import org.gradle.api.tasks.TaskProvider; import java.util.Optional; @@ -37,6 +41,7 @@ public abstract class Boilerplate { .orElse(collection.create(name)); } + public static T maybeCreate(NamedDomainObjectContainer collection, String name, Action action) { return Optional.ofNullable(collection.findByName(name)) .orElseGet(() -> { @@ -47,4 +52,37 @@ public abstract class Boilerplate { } + public static void maybeConfigure(TaskContainer tasks, String name, Action config) { + TaskProvider task; + try { + task = tasks.named(name); + } catch (UnknownTaskException e) { + return; + } + + task.configure(config); + } + + public static void maybeConfigure( + TaskContainer tasks, String name, + Class type, + Action 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; + } } diff --git a/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/DependencyLicensesTaskTests.java b/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/DependencyLicensesTaskTests.java index 397c5938fba..5492a7cfa96 100644 --- a/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/DependencyLicensesTaskTests.java +++ b/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/DependencyLicensesTaskTests.java @@ -1,11 +1,13 @@ package org.elasticsearch.gradle.precommit; import org.elasticsearch.gradle.test.GradleUnitTestCase; +import org.gradle.api.Action; import org.gradle.api.GradleException; import org.gradle.api.Project; import org.gradle.api.artifacts.Dependency; import org.gradle.api.file.FileCollection; import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.tasks.TaskProvider; import org.gradle.testfixtures.ProjectBuilder; import org.junit.Before; import org.junit.Rule; @@ -31,7 +33,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { private UpdateShasTask updateShas; - private DependencyLicensesTask task; + private TaskProvider task; private Project project; @@ -51,7 +53,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { expectedException.expectMessage(containsString("exists, but there are no dependencies")); getLicensesDir(project).mkdir(); - task.checkDependencies(); + task.get().checkDependencies(); } @Test @@ -60,12 +62,12 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { expectedException.expectMessage(containsString("does not exist, but there are dependencies")); project.getDependencies().add("compile", dependency); - task.checkDependencies(); + task.get().checkDependencies(); } @Test public void givenProjectWithoutLicensesDirNorDependenciesThenShouldReturnSilently() throws Exception { - task.checkDependencies(); + task.get().checkDependencies(); } @Test @@ -78,7 +80,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { createFileIn(licensesDir, "groovy-all-NOTICE.txt", ""); project.getDependencies().add("compile", project.getDependencies().localGroovy()); - task.checkDependencies(); + task.get().checkDependencies(); } @Test @@ -90,7 +92,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { getLicensesDir(project).mkdir(); updateShas.updateShas(); - task.checkDependencies(); + task.get().checkDependencies(); } @Test @@ -103,7 +105,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { createFileIn(getLicensesDir(project), "groovy-all-LICENSE.txt", ""); updateShas.updateShas(); - task.checkDependencies(); + task.get().checkDependencies(); } @Test @@ -113,7 +115,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { File licensesDir = getLicensesDir(project); createAllDefaultDependencyFiles(licensesDir, "groovy-all"); - task.checkDependencies(); + task.get().checkDependencies(); } @Test @@ -127,7 +129,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { createAllDefaultDependencyFiles(licensesDir, "groovy-all"); createFileIn(licensesDir, "non-declared-LICENSE.txt", ""); - task.checkDependencies(); + task.get().checkDependencies(); } @Test @@ -141,7 +143,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { createAllDefaultDependencyFiles(licensesDir, "groovy-all"); createFileIn(licensesDir, "non-declared-NOTICE.txt", ""); - task.checkDependencies(); + task.get().checkDependencies(); } @Test @@ -155,7 +157,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { createAllDefaultDependencyFiles(licensesDir, "groovy-all"); createFileIn(licensesDir, "non-declared.sha1", ""); - task.checkDependencies(); + task.get().checkDependencies(); } @Test @@ -175,7 +177,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { Files.write(groovySha, new byte[] { 1 }, StandardOpenOption.CREATE); - task.checkDependencies(); + task.get().checkDependencies(); } @Test @@ -189,8 +191,8 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { mappings.put("from", "groovy-all"); mappings.put("to", "groovy"); - task.mapping(mappings); - task.checkDependencies(); + task.get().mapping(mappings); + task.get().checkDependencies(); } @Test @@ -201,8 +203,8 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { createFileIn(licensesDir, "groovy-all-LICENSE.txt", ""); createFileIn(licensesDir, "groovy-all-NOTICE.txt", ""); - task.ignoreSha("groovy-all"); - task.checkDependencies(); + task.get().ignoreSha("groovy-all"); + task.get().checkDependencies(); } @Test @@ -210,7 +212,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { expectedException.expect(GradleException.class); expectedException.expectMessage(containsString("isn't a valid directory")); - task.getShaFiles(); + task.get().getShaFiles(); } private Project createProject() { @@ -244,7 +246,7 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { Files.write(file, content.getBytes(StandardCharsets.UTF_8)); } - private UpdateShasTask createUpdateShasTask(Project project, DependencyLicensesTask dependencyLicensesTask) { + private UpdateShasTask createUpdateShasTask(Project project, TaskProvider dependencyLicensesTask) { UpdateShasTask task = project.getTasks() .register("updateShas", UpdateShasTask.class) .get(); @@ -253,12 +255,15 @@ public class DependencyLicensesTaskTests extends GradleUnitTestCase { return task; } - private DependencyLicensesTask createDependencyLicensesTask(Project project) { - DependencyLicensesTask task = project.getTasks() - .register("dependencyLicenses", DependencyLicensesTask.class) - .get(); + private TaskProvider createDependencyLicensesTask(Project project) { + TaskProvider task = project.getTasks() + .register("dependencyLicenses", DependencyLicensesTask.class, new Action() { + @Override + public void execute(DependencyLicensesTask dependencyLicensesTask) { + dependencyLicensesTask.setDependencies(getDependencies(project)); + } + }); - task.setDependencies(getDependencies(project)); return task; } diff --git a/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/UpdateShasTaskTests.java b/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/UpdateShasTaskTests.java index 62ac9600a83..1cf523e2e62 100644 --- a/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/UpdateShasTaskTests.java +++ b/buildSrc/src/test/java/org/elasticsearch/gradle/precommit/UpdateShasTaskTests.java @@ -2,11 +2,13 @@ package org.elasticsearch.gradle.precommit; import org.apache.commons.io.FileUtils; import org.elasticsearch.gradle.test.GradleUnitTestCase; +import org.gradle.api.Action; import org.gradle.api.GradleException; import org.gradle.api.Project; import org.gradle.api.artifacts.Dependency; import org.gradle.api.file.FileCollection; import org.gradle.api.plugins.JavaPlugin; +import org.gradle.api.tasks.TaskProvider; import org.gradle.testfixtures.ProjectBuilder; import org.junit.Before; import org.junit.Rule; @@ -125,12 +127,15 @@ public class UpdateShasTaskTests extends GradleUnitTestCase { return task; } - private DependencyLicensesTask createDependencyLicensesTask(Project project) { - DependencyLicensesTask task = project.getTasks() - .register("dependencyLicenses", DependencyLicensesTask.class) - .get(); + private TaskProvider createDependencyLicensesTask(Project project) { + TaskProvider task = project.getTasks() + .register("dependencyLicenses", DependencyLicensesTask.class, new Action() { + @Override + public void execute(DependencyLicensesTask dependencyLicensesTask) { + dependencyLicensesTask.setDependencies(getDependencies(project)); + } + }); - task.setDependencies(getDependencies(project)); return task; }