Просмотр исходного кода

Avoid unnecessary eager creation of Gradle tasks (#45098)

Mark Vieira 6 лет назад
Родитель
Сommit
4d4552c69d

+ 25 - 37
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'
@@ -209,7 +212,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
@@ -326,13 +329,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 {
@@ -387,29 +386,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 {
@@ -474,13 +464,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
       }
     }
   }
@@ -502,7 +490,7 @@ gradle.projectsEvaluated {
 }
 
 allprojects {
-  task resolveAllDependencies {
+  tasks.register('resolveAllDependencies') {
       dependsOn tasks.matching { it.name == "pullFixture"}
       doLast {
         configurations.findAll { it.isCanBeResolved() }.each { it.resolve() }
@@ -532,13 +520,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' }
+      }
+  }
 }

+ 77 - 51
buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy

@@ -67,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 +83,14 @@ import org.gradle.process.ExecSpec
 import org.gradle.util.GradleVersion
 
 import java.nio.charset.StandardCharsets
+import java.nio.file.Files
 import java.time.ZoneOffset
 import java.time.ZonedDateTime
 import java.util.regex.Matcher
 
+import static org.elasticsearch.gradle.tool.Boilerplate.maybeConfigure
+import static org.elasticsearch.gradle.tool.Boilerplate.findByName
+
 /**
  * Encapsulates build configuration for elasticsearch projects.
  */
@@ -127,7 +132,7 @@ class BuildPlugin implements Plugin<Project> {
         // 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 +159,7 @@ class BuildPlugin implements Plugin<Project> {
                 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'
                     }
@@ -532,12 +537,14 @@ class BuildPlugin implements Plugin<Project> {
         // https://github.com/gradle/gradle/issues/5696#issuecomment-396965185
         // dummy task to depend on the real pom generation
         project.plugins.withType(MavenPublishPlugin).whenPluginAdded {
-            Task generatePomTask = project.tasks.create("generatePom")
-            Task assemble = project.tasks.findByName('assemble')
+            TaskProvider generatePomTask = project.tasks.register("generatePom") { Task task ->
+                task.dependsOn 'generatePomFileForNebulaPublication'
+            }
+            TaskProvider assemble = findByName(project.tasks, 'assemble')
             if (assemble) {
-                assemble.dependsOn(generatePomTask)
+                assemble.configure({ Task t -> t.dependsOn(generatePomTask) } as Action<Task>)
             }
-            project.tasks.withType(GenerateMavenPom.class) { GenerateMavenPom pomTask ->
+            project.tasks.withType(GenerateMavenPom).configureEach({ GenerateMavenPom pomTask ->
                 // The GenerateMavenPom task is aggressive about setting the destination, instead of fighting it,
                 // just make a copy.
                 ExtraPropertiesExtension ext = pomTask.extensions.getByType(ExtraPropertiesExtension)
@@ -553,8 +560,7 @@ class BuildPlugin implements Plugin<Project> {
                         }
                     }
                 }
-            }
-            generatePomTask.dependsOn = ['generatePomFileForNebulaPublication']
+            } as Action<GenerateMavenPom>)
             PublishingExtension publishing = project.extensions.getByType(PublishingExtension)
             publishing.publications.all { MavenPublication publication -> // we only deal with maven
                 // add exclusions to the pom directly, for each of the transitive deps of this project's deps
@@ -566,7 +572,7 @@ class BuildPlugin implements Plugin<Project> {
                     ShadowExtension shadow = project.extensions.getByType(ShadowExtension)
                     shadow.component(publication)
                 }
-                generatePomTask.dependsOn = ['generatePomFileForShadowPublication']
+                generatePomTask.configure({ Task t -> t.dependsOn = ['generatePomFileForShadowPublication'] } as Action<Task>)
             }
         }
     }
@@ -603,7 +609,7 @@ class BuildPlugin implements Plugin<Project> {
         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) {
@@ -631,9 +637,9 @@ class BuildPlugin implements Plugin<Project> {
 
                 // 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<JavaCompile>)
             // 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
@@ -642,19 +648,23 @@ class BuildPlugin implements Plugin<Project> {
                     compileTask.options.forkOptions.javaHome = compilerJavaHome
                     compileTask.options.compilerArgs << '--release' << JavaVersion.toVersion(compileTask.targetCompatibility).majorVersion
                 }
-            }
+            } as Action<GroovyCompile>)
         }
     }
 
     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<File> 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
             }
@@ -669,21 +679,27 @@ class BuildPlugin implements Plugin<Project> {
 
     /** 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<Jar> 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<Jar>)
+        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<Jar> 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<Jar>)
+        maybeConfigure(project.tasks, BasePlugin.ASSEMBLE_TASK_NAME) { Task t ->
+            t.dependsOn(sourcesJarTask)
+        }
     }
 
     /** Adds additional manifest info to jars */
@@ -691,7 +707,7 @@ class BuildPlugin implements Plugin<Project> {
         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')
             project.plugins.withType(ShadowPlugin).whenPluginAdded {
@@ -716,9 +732,10 @@ class BuildPlugin implements Plugin<Project> {
                         '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}")
                 }
@@ -756,7 +773,9 @@ class BuildPlugin implements Plugin<Project> {
                 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 { Task task ->
+               task.dependsOn 'shadowJar'
+            }
         }
     }
 
@@ -764,7 +783,7 @@ class BuildPlugin implements Plugin<Project> {
         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'
         }
 
@@ -772,7 +791,7 @@ class BuildPlugin implements Plugin<Project> {
         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)
@@ -881,30 +900,37 @@ class BuildPlugin implements Plugin<Project> {
     }
 
     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<DependenciesInfoTask> 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<DependenciesInfoTask>)
         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'))
+            }
         }
     }
 

+ 13 - 5
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
  * </ul>
  *
  */
-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<String, String> mappings
+    private LinkedHashMap<String, String> 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<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>
      * based on dependency coordinates.
      */

+ 6 - 3
buildSrc/src/main/groovy/org/elasticsearch/gradle/plugin/PluginBuildPlugin.groovy

@@ -31,6 +31,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.tasks.Copy
@@ -109,7 +110,7 @@ class PluginBuildPlugin implements Plugin<Project> {
                 addNoticeGeneration(project, extension)
             }
         }
-        project.testingConventions {
+        project.tasks.named('testingConventions').configure {
             naming.clear()
             naming {
                 Tests {
@@ -157,7 +158,7 @@ class PluginBuildPlugin implements Plugin<Project> {
     /** 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')
@@ -241,7 +242,9 @@ class PluginBuildPlugin implements Plugin<Project> {
                 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')

+ 66 - 54
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<Task> precommitTasks = [
+        List<TaskProvider> 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<DependencyLicensesTask> 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.configure {
+                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 {
+            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())
+                }
             }
         }
 
-        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
         // 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
         }
     }

+ 1 - 1
buildSrc/src/main/java/org/elasticsearch/gradle/info/GlobalBuildInfoPlugin.java

@@ -77,7 +77,7 @@ public class GlobalBuildInfoPlugin implements Plugin<Project> {
 
         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);
                 }

+ 9 - 8
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<DependencyLicensesTask> 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<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();
-            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<DependencyLicensesTask> parentTask) {
         this.parentTask = parentTask;
     }
 }

+ 1 - 1
buildSrc/src/main/java/org/elasticsearch/gradle/testclusters/TestClustersPlugin.java

@@ -123,7 +123,7 @@ public class TestClustersPlugin implements Plugin<Project> {
     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
         // specific cluster.
-        project.getTasks().all((Task task) ->
+        project.getTasks().configureEach((Task task) ->
             task.getExtensions().findByType(ExtraPropertiesExtension.class)
                 .set(
                     "useCluster",

+ 38 - 0
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> T maybeCreate(NamedDomainObjectContainer<T> collection, String name, Action<T> 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<? 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;
+    }
 }

+ 28 - 23
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<DependencyLicensesTask> 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> 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<DependencyLicensesTask> createDependencyLicensesTask(Project project) {
+        TaskProvider<DependencyLicensesTask> task =  project.getTasks()
+            .register("dependencyLicenses", DependencyLicensesTask.class, new Action<DependencyLicensesTask>() {
+                @Override
+                public void execute(DependencyLicensesTask dependencyLicensesTask) {
+                    dependencyLicensesTask.setDependencies(getDependencies(project));
+                }
+            });
 
-        task.setDependencies(getDependencies(project));
         return task;
     }
 

+ 10 - 5
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<DependencyLicensesTask> createDependencyLicensesTask(Project project) {
+        TaskProvider<DependencyLicensesTask> task =  project.getTasks()
+            .register("dependencyLicenses", DependencyLicensesTask.class, new Action<DependencyLicensesTask>() {
+                @Override
+                public void execute(DependencyLicensesTask dependencyLicensesTask) {
+                    dependencyLicensesTask.setDependencies(getDependencies(project));
+                }
+            });
 
-        task.setDependencies(getDependencies(project));
         return task;
     }