From 0fbfdfb260a7f25f4625774f82a1c73042bddd20 Mon Sep 17 00:00:00 2001 From: Alpar Torok Date: Thu, 19 Jul 2018 12:31:15 +0300 Subject: [PATCH 1/6] Task skeleton with test failing due to missing implementation --- .../elasticsearch/gradle/BuildPlugin.groovy | 3 + .../gradle/ElasticsearchBuildResource.java | 39 ++++++ ...ExportElasticsearchBuildResourcesTask.java | 131 ++++++++++++++++++ ...portElasticsearchBuildResourcesTaskIT.java | 62 +++++++++ .../build.gradle | 12 ++ 5 files changed, 247 insertions(+) create mode 100644 buildSrc/src/main/java/org/elasticsearch/gradle/ElasticsearchBuildResource.java create mode 100644 buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java create mode 100644 buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java create mode 100644 buildSrc/src/testKit/elasticsearch-build-resources/build.gradle diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy index 219d00ba64032..99437669d3449 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy @@ -77,6 +77,8 @@ class BuildPlugin implements Plugin { project.pluginManager.apply('nebula.info-scm') project.pluginManager.apply('nebula.info-jar') + project.getTasks().create("exportBuildResources", ExportElasticsearchBuildResourcesTask) + globalBuildInfo(project) configureRepositories(project) configureConfigurations(project) @@ -91,6 +93,7 @@ class BuildPlugin implements Plugin { configureDependenciesInfo(project) } + /** Performs checks on the build environment and prints information about the build environment. */ static void globalBuildInfo(Project project) { if (project.rootProject.ext.has('buildChecksDone') == false) { diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/ElasticsearchBuildResource.java b/buildSrc/src/main/java/org/elasticsearch/gradle/ElasticsearchBuildResource.java new file mode 100644 index 0000000000000..b4c530fe148e3 --- /dev/null +++ b/buildSrc/src/main/java/org/elasticsearch/gradle/ElasticsearchBuildResource.java @@ -0,0 +1,39 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.elasticsearch.gradle; + +/** + * Enumerate resources in the build that are meant for consumption outside of the build code. + */ +public enum ElasticsearchBuildResource { + CHECKSTYLE_CONF("/checkstyle.xml"), + CHECKSTYLE_SURPRESSIONS_CONF("/checkstyle_suppressions.xml") + ; + + private final String fullName; + + ElasticsearchBuildResource(String fullName) { + this.fullName = fullName; + } + + public String getFullName() { + return fullName; + } + +} diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java b/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java new file mode 100644 index 0000000000000..961d0e6922ddf --- /dev/null +++ b/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java @@ -0,0 +1,131 @@ +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.elasticsearch.gradle; + +import org.gradle.api.DefaultTask; +import org.gradle.api.logging.Logger; +import org.gradle.api.logging.Logging; +import org.gradle.api.tasks.Classpath; +import org.gradle.api.tasks.Input; +import org.gradle.api.tasks.OutputFiles; +import org.gradle.api.tasks.SkipWhenEmpty; +import org.gradle.api.tasks.StopExecutionException; +import org.gradle.api.tasks.TaskAction; + +import java.io.File; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * Export Elasticsearch build resources to configurable paths + * + * Wil overwrite existing files and create missing directories. + * Useful for resources that that need to be passed to other processes trough the filesystem or otherwise can't be + * consumed from the classpath. + */ +public class ExportElasticsearchBuildResourcesTask extends DefaultTask { + + private final Logger logger = Logging.getLogger(ExportElasticsearchBuildResourcesTask.class); + + private final Set resources = new HashSet<>(); + + @Input + @SkipWhenEmpty + public Set getResources() { + return Collections.unmodifiableSet(resources); + } + + @Classpath + public String getResourceSourceFiles() { + logger.info("Classpath: {}", System.getProperty("java.class.path")); + return System.getProperty("java.class.path"); + } + + @OutputFiles + public List getOutputFiles() { + return resources.stream() + .map(ExportPair::getOutputFile) + .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)); + } + + public void resource(Map resourcesMap) { + resourcesMap.forEach(this::resource); + } + + public void resource(ElasticsearchBuildResource resource, File outputFile) { + resources.add(new ExportPair(resource, outputFile)); + } + + @TaskAction + public void doExport() { + if (resources.isEmpty()) { + throw new StopExecutionException(); + } + logger.info("exporting resources"); + } + + // Gradle wants this to be Serializable, we achieve this by extending list, + // also alows for variable expansion in Groovy. + public static class ExportPair extends ArrayList { + private final ElasticsearchBuildResource resource; + private final File outputFile; + + public ExportPair(ElasticsearchBuildResource resource, File outputFile) { + this.resource = resource; + this.outputFile = outputFile; + super.add(resource); + super.add(outputFile); + } + + public ElasticsearchBuildResource getResource() { + return resource; + } + + public File getOutputFile() { + return outputFile; + } + + @Override + public boolean add(Object o) { + throw new UnsupportedOperationException(); + } + + @Override + public void add(int index, Object element) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(int index, Collection c) { + throw new UnsupportedOperationException(); + } + } + +} diff --git a/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java b/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java new file mode 100644 index 0000000000000..3e8fe1173ba2e --- /dev/null +++ b/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java @@ -0,0 +1,62 @@ +package org.elasticsearch.gradle; + +/* + * Licensed to Elasticsearch under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import org.elasticsearch.gradle.test.GradleIntegrationTestCase; +import org.gradle.testkit.runner.BuildResult; +import org.gradle.testkit.runner.GradleRunner; +import org.gradle.testkit.runner.TaskOutcome; + +public class ExportElasticsearchBuildResourcesTaskIT extends GradleIntegrationTestCase { + + public void testUpToDate() { + BuildResult result = GradleRunner.create() + .withProjectDir(getProjectDir("elasticsearch-build-resources")) + .withArguments("exportBuildResources", "-s") + .withPluginClasspath() + .build(); + assertEquals(TaskOutcome.UP_TO_DATE, result.task(":exportBuildResources").getOutcome()); + } + + public void testUpToDateWithSourcesConfigured() { + GradleRunner.create() + .withProjectDir(getProjectDir("elasticsearch-build-resources")) + .withArguments("clean", "-s") + .withPluginClasspath() + .build(); + + BuildResult result = GradleRunner.create() + .withProjectDir(getProjectDir("elasticsearch-build-resources")) + .withArguments("exportCheckstyle", "-s", "-i") + .withPluginClasspath() + .build(); + assertEquals(TaskOutcome.SUCCESS, result.task(":exportCheckstyle").getOutcome()); + + result = GradleRunner.create() + .withProjectDir(getProjectDir("elasticsearch-build-resources")) + .withArguments("exportCheckstyle", "-s", "-i") + .withPluginClasspath() + .build(); + assertEquals(TaskOutcome.UP_TO_DATE, result.task(":exportCheckstyle").getOutcome()); + + + } + +} diff --git a/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle b/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle new file mode 100644 index 0000000000000..94f2b74bbb076 --- /dev/null +++ b/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle @@ -0,0 +1,12 @@ +import org.elasticsearch.gradle.ExportElasticsearchBuildResourcesTask + +plugins { + id 'elasticsearch.build' +} + +ext.licenseFile = file("$buildDir/dummy/license") +ext.noticeFile = file("$buildDir/dummy/notice") + +task (exportCheckstyle, type: ExportElasticsearchBuildResourcesTask) { + resource 'CHECKSTYLE_CONF', file("$buildDir/checkstyle-1.xml") +} \ No newline at end of file From 02d7bf02032052820ced9f31f388d75f6394f608 Mon Sep 17 00:00:00 2001 From: Alpar Torok Date: Thu, 19 Jul 2018 17:39:20 +0300 Subject: [PATCH 2/6] Task implementation and complete task --- ...ExportElasticsearchBuildResourcesTask.java | 26 +++++++++++++++++- ...portElasticsearchBuildResourcesTaskIT.java | 27 ++++++++++--------- .../test/GradleIntegrationTestCase.java | 4 +++ .../build.gradle | 8 +++--- 4 files changed, 47 insertions(+), 18 deletions(-) diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java b/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java index 961d0e6922ddf..9d5464484a866 100644 --- a/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java +++ b/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java @@ -18,7 +18,9 @@ */ package org.elasticsearch.gradle; +import groovy.lang.GString; import org.gradle.api.DefaultTask; +import org.gradle.api.GradleException; import org.gradle.api.logging.Logger; import org.gradle.api.logging.Logging; import org.gradle.api.tasks.Classpath; @@ -29,6 +31,9 @@ import org.gradle.api.tasks.TaskAction; import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -78,12 +83,31 @@ public void resource(ElasticsearchBuildResource resource, File outputFile) { resources.add(new ExportPair(resource, outputFile)); } + public void resource(ElasticsearchBuildResource resource, String outputFile) { + resources.add(new ExportPair(resource, getProject().file(outputFile))); + } + + public void resource(ElasticsearchBuildResource resource, GString outputFile) { + resources.add(new ExportPair(resource, getProject().file(outputFile))); + } + @TaskAction public void doExport() { if (resources.isEmpty()) { throw new StopExecutionException(); } - logger.info("exporting resources"); + resources.stream().parallel() + .forEach(pair -> { + try { + try(InputStream is = getClass().getResourceAsStream(pair.getResource().getFullName())) { + Files.copy(is, pair.getOutputFile().toPath()); + } + } catch (IOException e) { + throw new GradleException( + "Can't write resource " + pair.getResource().name() + " to " + pair.getOutputFile() + ); + } + }); } // Gradle wants this to be Serializable, we achieve this by extending list, diff --git a/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java b/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java index 3e8fe1173ba2e..7da95dca2797e 100644 --- a/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java +++ b/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java @@ -24,37 +24,38 @@ import org.gradle.testkit.runner.GradleRunner; import org.gradle.testkit.runner.TaskOutcome; +import java.io.File; + public class ExportElasticsearchBuildResourcesTaskIT extends GradleIntegrationTestCase { - public void testUpToDate() { - BuildResult result = GradleRunner.create() - .withProjectDir(getProjectDir("elasticsearch-build-resources")) - .withArguments("exportBuildResources", "-s") - .withPluginClasspath() - .build(); - assertEquals(TaskOutcome.UP_TO_DATE, result.task(":exportBuildResources").getOutcome()); - } + public static final String PROJECT_NAME = "elasticsearch-build-resources"; public void testUpToDateWithSourcesConfigured() { GradleRunner.create() - .withProjectDir(getProjectDir("elasticsearch-build-resources")) + .withProjectDir(getProjectDir(PROJECT_NAME)) .withArguments("clean", "-s") .withPluginClasspath() .build(); BuildResult result = GradleRunner.create() .withProjectDir(getProjectDir("elasticsearch-build-resources")) - .withArguments("exportCheckstyle", "-s", "-i") + .withArguments("exportBuildResources", "-s", "-i") .withPluginClasspath() .build(); - assertEquals(TaskOutcome.SUCCESS, result.task(":exportCheckstyle").getOutcome()); + assertEquals(TaskOutcome.SUCCESS, result.task(":exportBuildResources").getOutcome()); + assertTrue(new File(getBuildDir(PROJECT_NAME), "checkstyle-1.xml").exists()); + assertTrue(new File(getBuildDir(PROJECT_NAME), "checkstyle-2.xml").exists()); + assertTrue(new File(getBuildDir(PROJECT_NAME), "checkstyle-3.xml").exists()); result = GradleRunner.create() .withProjectDir(getProjectDir("elasticsearch-build-resources")) - .withArguments("exportCheckstyle", "-s", "-i") + .withArguments("exportBuildResources", "-s", "-i") .withPluginClasspath() .build(); - assertEquals(TaskOutcome.UP_TO_DATE, result.task(":exportCheckstyle").getOutcome()); + assertEquals(TaskOutcome.UP_TO_DATE, result.task(":exportBuildResources").getOutcome()); + assertTrue(new File(getBuildDir(PROJECT_NAME), "checkstyle-1.xml").exists()); + assertTrue(new File(getBuildDir(PROJECT_NAME), "checkstyle-2.xml").exists()); + assertTrue(new File(getBuildDir(PROJECT_NAME), "checkstyle-3.xml").exists()); } diff --git a/buildSrc/src/test/java/org/elasticsearch/gradle/test/GradleIntegrationTestCase.java b/buildSrc/src/test/java/org/elasticsearch/gradle/test/GradleIntegrationTestCase.java index 26da663182f7c..f83a88e6ae1b0 100644 --- a/buildSrc/src/test/java/org/elasticsearch/gradle/test/GradleIntegrationTestCase.java +++ b/buildSrc/src/test/java/org/elasticsearch/gradle/test/GradleIntegrationTestCase.java @@ -13,4 +13,8 @@ protected File getProjectDir(String name) { return new File(root, name); } + protected File getBuildDir(String name) { + return new File(getProjectDir(name), "build"); + } + } diff --git a/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle b/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle index 94f2b74bbb076..57ce586bd990c 100644 --- a/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle +++ b/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle @@ -1,5 +1,3 @@ -import org.elasticsearch.gradle.ExportElasticsearchBuildResourcesTask - plugins { id 'elasticsearch.build' } @@ -7,6 +5,8 @@ plugins { ext.licenseFile = file("$buildDir/dummy/license") ext.noticeFile = file("$buildDir/dummy/notice") -task (exportCheckstyle, type: ExportElasticsearchBuildResourcesTask) { +exportBuildResources { resource 'CHECKSTYLE_CONF', file("$buildDir/checkstyle-1.xml") -} \ No newline at end of file + resource 'CHECKSTYLE_CONF', "$buildDir/checkstyle-2.xml" + resource 'checkstyle_conf', file("$buildDir/checkstyle-3.xml") +} From 5bb35ac6175b35ab0e558050887586db84660d07 Mon Sep 17 00:00:00 2001 From: Alpar Torok Date: Wed, 25 Jul 2018 01:13:41 +0300 Subject: [PATCH 3/6] No more whitelist, reduce boilerplate --- ...ExportElasticsearchBuildResourcesTask.java | 116 ++++++------------ ...portElasticsearchBuildResourcesTaskIT.java | 54 ++++++-- .../test/GradleIntegrationTestCase.java | 2 +- .../build.gradle | 23 +++- 4 files changed, 100 insertions(+), 95 deletions(-) diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java b/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java index 9d5464484a866..67d9fd26abab3 100644 --- a/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java +++ b/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java @@ -18,77 +18,73 @@ */ package org.elasticsearch.gradle; -import groovy.lang.GString; import org.gradle.api.DefaultTask; import org.gradle.api.GradleException; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.file.RegularFileProperty; import org.gradle.api.logging.Logger; import org.gradle.api.logging.Logging; import org.gradle.api.tasks.Classpath; import org.gradle.api.tasks.Input; -import org.gradle.api.tasks.OutputFiles; +import org.gradle.api.tasks.OutputDirectory; import org.gradle.api.tasks.SkipWhenEmpty; import org.gradle.api.tasks.StopExecutionException; import org.gradle.api.tasks.TaskAction; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; -import java.util.ArrayList; -import java.util.Collection; +import java.nio.file.Path; import java.util.Collections; import java.util.HashSet; -import java.util.List; -import java.util.Map; import java.util.Set; -import java.util.stream.Collectors; /** * Export Elasticsearch build resources to configurable paths - * + *

* Wil overwrite existing files and create missing directories. * Useful for resources that that need to be passed to other processes trough the filesystem or otherwise can't be * consumed from the classpath. */ public class ExportElasticsearchBuildResourcesTask extends DefaultTask { - private final Logger logger = Logging.getLogger(ExportElasticsearchBuildResourcesTask.class); + private final Logger logger = Logging.getLogger(ExportElasticsearchBuildResourcesTask.class); + + private final Set resources = new HashSet<>(); - private final Set resources = new HashSet<>(); + private DirectoryProperty outputDir; + + public ExportElasticsearchBuildResourcesTask() { + outputDir = getProject().getLayout().directoryProperty( + getProject().getLayout().getBuildDirectory().dir("build-tools-exported") + ); + } + + @OutputDirectory + public DirectoryProperty getOutputDir() { + return outputDir; + } @Input @SkipWhenEmpty - public Set getResources() { + public Set getResources() { return Collections.unmodifiableSet(resources); } @Classpath - public String getResourceSourceFiles() { + public String getResourcesClasspath() { + // This will make sure the task is not considered up to date if the resources are changed. logger.info("Classpath: {}", System.getProperty("java.class.path")); return System.getProperty("java.class.path"); } - @OutputFiles - public List getOutputFiles() { - return resources.stream() - .map(ExportPair::getOutputFile) - .collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList)); - } - - public void resource(Map resourcesMap) { - resourcesMap.forEach(this::resource); - } - - public void resource(ElasticsearchBuildResource resource, File outputFile) { - resources.add(new ExportPair(resource, outputFile)); + public void setOutputDir(DirectoryProperty outputDir) { + this.outputDir = outputDir; } - public void resource(ElasticsearchBuildResource resource, String outputFile) { - resources.add(new ExportPair(resource, getProject().file(outputFile))); - } - - public void resource(ElasticsearchBuildResource resource, GString outputFile) { - resources.add(new ExportPair(resource, getProject().file(outputFile))); + public RegularFileProperty resource(String resource) { + resources.add(resource); + return getProject().getLayout().fileProperty(outputDir.file(resource)); } @TaskAction @@ -97,59 +93,17 @@ public void doExport() { throw new StopExecutionException(); } resources.stream().parallel() - .forEach(pair -> { - try { - try(InputStream is = getClass().getResourceAsStream(pair.getResource().getFullName())) { - Files.copy(is, pair.getOutputFile().toPath()); + .forEach(resourcePath -> { + Path destination = outputDir.get().file(resourcePath).getAsFile().toPath(); + try (InputStream is = getClass().getClassLoader().getResourceAsStream(resourcePath)) { + if (is == null) { + throw new GradleException("Can't export `" + resourcePath + "` from build-tools: not found"); } + Files.copy(is, destination); } catch (IOException e) { - throw new GradleException( - "Can't write resource " + pair.getResource().name() + " to " + pair.getOutputFile() - ); + throw new GradleException("Can't write resource `" + resourcePath + "` to " + destination); } }); } - // Gradle wants this to be Serializable, we achieve this by extending list, - // also alows for variable expansion in Groovy. - public static class ExportPair extends ArrayList { - private final ElasticsearchBuildResource resource; - private final File outputFile; - - public ExportPair(ElasticsearchBuildResource resource, File outputFile) { - this.resource = resource; - this.outputFile = outputFile; - super.add(resource); - super.add(outputFile); - } - - public ElasticsearchBuildResource getResource() { - return resource; - } - - public File getOutputFile() { - return outputFile; - } - - @Override - public boolean add(Object o) { - throw new UnsupportedOperationException(); - } - - @Override - public void add(int index, Object element) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addAll(Collection c) { - throw new UnsupportedOperationException(); - } - - @Override - public boolean addAll(int index, Collection c) { - throw new UnsupportedOperationException(); - } - } - } diff --git a/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java b/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java index 7da95dca2797e..3c269e01903f2 100644 --- a/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java +++ b/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java @@ -21,10 +21,12 @@ import org.elasticsearch.gradle.test.GradleIntegrationTestCase; import org.gradle.testkit.runner.BuildResult; +import org.gradle.testkit.runner.BuildTask; import org.gradle.testkit.runner.GradleRunner; import org.gradle.testkit.runner.TaskOutcome; -import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; public class ExportElasticsearchBuildResourcesTaskIT extends GradleIntegrationTestCase { @@ -38,26 +40,58 @@ public void testUpToDateWithSourcesConfigured() { .build(); BuildResult result = GradleRunner.create() - .withProjectDir(getProjectDir("elasticsearch-build-resources")) + .withProjectDir(getProjectDir(PROJECT_NAME)) .withArguments("exportBuildResources", "-s", "-i") .withPluginClasspath() .build(); - assertEquals(TaskOutcome.SUCCESS, result.task(":exportBuildResources").getOutcome()); - assertTrue(new File(getBuildDir(PROJECT_NAME), "checkstyle-1.xml").exists()); - assertTrue(new File(getBuildDir(PROJECT_NAME), "checkstyle-2.xml").exists()); - assertTrue(new File(getBuildDir(PROJECT_NAME), "checkstyle-3.xml").exists()); + assertTaskSuccessFull(result, ":exportBuildResources"); + assertBuildFileExists(result, PROJECT_NAME, "build-tools-exported/checkstyle.xml"); + result = GradleRunner.create() - .withProjectDir(getProjectDir("elasticsearch-build-resources")) + .withProjectDir(getProjectDir(PROJECT_NAME)) .withArguments("exportBuildResources", "-s", "-i") .withPluginClasspath() .build(); assertEquals(TaskOutcome.UP_TO_DATE, result.task(":exportBuildResources").getOutcome()); - assertTrue(new File(getBuildDir(PROJECT_NAME), "checkstyle-1.xml").exists()); - assertTrue(new File(getBuildDir(PROJECT_NAME), "checkstyle-2.xml").exists()); - assertTrue(new File(getBuildDir(PROJECT_NAME), "checkstyle-3.xml").exists()); + assertBuildFileExists(result, PROJECT_NAME, "build-tools-exported/checkstyle.xml"); + } + + public void testImplicitTaskDependencyCopy() { + BuildResult result = GradleRunner.create() + .withProjectDir(getProjectDir(PROJECT_NAME)) + .withArguments("clean", "sampleCopyAll", "-s", "-i") + .withPluginClasspath() + .build(); + assertTaskSuccessFull(result, ":exportBuildResources"); + assertTaskSuccessFull(result, ":sampleCopyAll"); + assertBuildFileExists(result, PROJECT_NAME, "sampleCopyAll/checkstyle.xml"); + } + public void testImplicitTaskDependencyInputFileOfOther() { + BuildResult result = GradleRunner.create() + .withProjectDir(getProjectDir(PROJECT_NAME)) + .withArguments("clean", "sample", "-s", "-i") + .withPluginClasspath() + .build(); + + assertBuildFileExists(result, PROJECT_NAME, "build-tools-exported/checkstyle.xml"); + } + + private void assertTaskSuccessFull(BuildResult result, String taskName) { + BuildTask task = result.task(taskName); + if (task == null) { + fail("Expected task `" + taskName + "` to be successful, but it did not run"); + } + assertEquals(TaskOutcome.SUCCESS, task.getOutcome()); + } + private void assertBuildFileExists(BuildResult result, String projectName, String path) { + Path absPath = getBuildDir(projectName).toPath().resolve(path); + assertTrue( + result.getOutput() + "\n\nExpected `" + absPath + "` to exists but it did not", + Files.exists(absPath) + ); } } diff --git a/buildSrc/src/test/java/org/elasticsearch/gradle/test/GradleIntegrationTestCase.java b/buildSrc/src/test/java/org/elasticsearch/gradle/test/GradleIntegrationTestCase.java index f83a88e6ae1b0..3b2c7c3d639b6 100644 --- a/buildSrc/src/test/java/org/elasticsearch/gradle/test/GradleIntegrationTestCase.java +++ b/buildSrc/src/test/java/org/elasticsearch/gradle/test/GradleIntegrationTestCase.java @@ -10,7 +10,7 @@ protected File getProjectDir(String name) { throw new RuntimeException("Could not find resources dir for integration tests. " + "Note that these tests can only be ran by Gradle and are not currently supported by the IDE"); } - return new File(root, name); + return new File(root, name).getAbsoluteFile(); } protected File getBuildDir(String name) { diff --git a/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle b/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle index 57ce586bd990c..cc618918a726b 100644 --- a/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle +++ b/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle @@ -6,7 +6,24 @@ ext.licenseFile = file("$buildDir/dummy/license") ext.noticeFile = file("$buildDir/dummy/notice") exportBuildResources { - resource 'CHECKSTYLE_CONF', file("$buildDir/checkstyle-1.xml") - resource 'CHECKSTYLE_CONF', "$buildDir/checkstyle-2.xml" - resource 'checkstyle_conf', file("$buildDir/checkstyle-3.xml") + resource 'checkstyle.xml' + resource 'minimumCompilerVersion' } + +task sampleCopyAll(type: Sync) { + /** Note: no explicit dependency. This works with tasks that use the Provider API a.k.a "Lazy Configuration" **/ + from exportBuildResources + into "$buildDir/sampleCopyAll" +} + +task sample { + // This does not work, task dependencies can't be providers + // dependsOn exportBuildResources.resource('minimumRuntimeVersion') + // Nor does this, despite https://github.com/gradle/gradle/issues/3811 + // dependsOn exportBuildResources.outputDir + // for now it's just + dependsOn exportBuildResources + doLast { + println "This task is using ${file(exportBuildResources.resource('minimumRuntimeVersion'))}" + } +} \ No newline at end of file From 8cfbd6737b14b1dbad7721c914cde6d0819b3578 Mon Sep 17 00:00:00 2001 From: Alpar Torok Date: Tue, 7 Aug 2018 08:12:11 +0300 Subject: [PATCH 4/6] remove unused enum --- .../gradle/ElasticsearchBuildResource.java | 39 ------------------- 1 file changed, 39 deletions(-) delete mode 100644 buildSrc/src/main/java/org/elasticsearch/gradle/ElasticsearchBuildResource.java diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/ElasticsearchBuildResource.java b/buildSrc/src/main/java/org/elasticsearch/gradle/ElasticsearchBuildResource.java deleted file mode 100644 index b4c530fe148e3..0000000000000 --- a/buildSrc/src/main/java/org/elasticsearch/gradle/ElasticsearchBuildResource.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to Elasticsearch under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.elasticsearch.gradle; - -/** - * Enumerate resources in the build that are meant for consumption outside of the build code. - */ -public enum ElasticsearchBuildResource { - CHECKSTYLE_CONF("/checkstyle.xml"), - CHECKSTYLE_SURPRESSIONS_CONF("/checkstyle_suppressions.xml") - ; - - private final String fullName; - - ElasticsearchBuildResource(String fullName) { - this.fullName = fullName; - } - - public String getFullName() { - return fullName; - } - -} From 7a29a1a05c7da82aa3fb32189b7ba44b7b6da3cc Mon Sep 17 00:00:00 2001 From: Alpar Torok Date: Fri, 10 Aug 2018 16:57:48 +0300 Subject: [PATCH 5/6] Rename in accordance with PR --- .../org/elasticsearch/gradle/BuildPlugin.groovy | 2 +- .../ExportElasticsearchBuildResourcesTask.java | 2 +- .../ExportElasticsearchBuildResourcesTaskIT.java | 10 +++++----- .../elasticsearch-build-resources/build.gradle | 12 ++++++------ 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy b/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy index 56b9603f2e447..d05544360c990 100644 --- a/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy +++ b/buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy @@ -87,7 +87,7 @@ class BuildPlugin implements Plugin { project.pluginManager.apply('nebula.info-scm') project.pluginManager.apply('nebula.info-jar') - project.getTasks().create("exportBuildResources", ExportElasticsearchBuildResourcesTask) + project.getTasks().create("buildResources", ExportElasticsearchBuildResourcesTask) globalBuildInfo(project) configureRepositories(project) diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java b/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java index 67d9fd26abab3..190e1b14d8a04 100644 --- a/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java +++ b/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java @@ -82,7 +82,7 @@ public void setOutputDir(DirectoryProperty outputDir) { this.outputDir = outputDir; } - public RegularFileProperty resource(String resource) { + public RegularFileProperty take(String resource) { resources.add(resource); return getProject().getLayout().fileProperty(outputDir.file(resource)); } diff --git a/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java b/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java index 3c269e01903f2..d95b3a0771fbe 100644 --- a/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java +++ b/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java @@ -41,19 +41,19 @@ public void testUpToDateWithSourcesConfigured() { BuildResult result = GradleRunner.create() .withProjectDir(getProjectDir(PROJECT_NAME)) - .withArguments("exportBuildResources", "-s", "-i") + .withArguments("buildResources", "-s", "-i") .withPluginClasspath() .build(); - assertTaskSuccessFull(result, ":exportBuildResources"); + assertTaskSuccessFull(result, ":buildResources"); assertBuildFileExists(result, PROJECT_NAME, "build-tools-exported/checkstyle.xml"); result = GradleRunner.create() .withProjectDir(getProjectDir(PROJECT_NAME)) - .withArguments("exportBuildResources", "-s", "-i") + .withArguments("buildResources", "-s", "-i") .withPluginClasspath() .build(); - assertEquals(TaskOutcome.UP_TO_DATE, result.task(":exportBuildResources").getOutcome()); + assertEquals(TaskOutcome.UP_TO_DATE, result.task(":buildResources").getOutcome()); assertBuildFileExists(result, PROJECT_NAME, "build-tools-exported/checkstyle.xml"); } @@ -63,7 +63,7 @@ public void testImplicitTaskDependencyCopy() { .withArguments("clean", "sampleCopyAll", "-s", "-i") .withPluginClasspath() .build(); - assertTaskSuccessFull(result, ":exportBuildResources"); + assertTaskSuccessFull(result, ":buildResources"); assertTaskSuccessFull(result, ":sampleCopyAll"); assertBuildFileExists(result, PROJECT_NAME, "sampleCopyAll/checkstyle.xml"); } diff --git a/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle b/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle index cc618918a726b..0e41bb21961e2 100644 --- a/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle +++ b/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle @@ -5,14 +5,14 @@ plugins { ext.licenseFile = file("$buildDir/dummy/license") ext.noticeFile = file("$buildDir/dummy/notice") -exportBuildResources { - resource 'checkstyle.xml' - resource 'minimumCompilerVersion' +buildResources { + take 'checkstyle.xml' + take 'minimumCompilerVersion' } task sampleCopyAll(type: Sync) { /** Note: no explicit dependency. This works with tasks that use the Provider API a.k.a "Lazy Configuration" **/ - from exportBuildResources + from buildResources into "$buildDir/sampleCopyAll" } @@ -22,8 +22,8 @@ task sample { // Nor does this, despite https://github.com/gradle/gradle/issues/3811 // dependsOn exportBuildResources.outputDir // for now it's just - dependsOn exportBuildResources + dependsOn buildResources doLast { - println "This task is using ${file(exportBuildResources.resource('minimumRuntimeVersion'))}" + println "This task is using ${file(buildResources.take('minimumRuntimeVersion'))}" } } \ No newline at end of file From 43ce30788040c0deb750ac94fe48a32ce66cc391 Mon Sep 17 00:00:00 2001 From: Alpar Torok Date: Fri, 10 Aug 2018 17:52:46 +0300 Subject: [PATCH 6/6] clarify and extend tests --- ...ExportElasticsearchBuildResourcesTask.java | 5 ++ ...portElasticsearchBuildResourcesTaskIT.java | 42 +++++++--------- .../test/GradleIntegrationTestCase.java | 48 +++++++++++++++++++ .../build.gradle | 13 ++++- 4 files changed, 81 insertions(+), 27 deletions(-) diff --git a/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java b/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java index 190e1b14d8a04..7306d2832a9be 100644 --- a/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java +++ b/buildSrc/src/main/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTask.java @@ -83,6 +83,11 @@ public void setOutputDir(DirectoryProperty outputDir) { } public RegularFileProperty take(String resource) { + if (getState().getExecuted() || getState().getExecuting()) { + throw new GradleException("buildResources can't be configured after the task ran. " + + "Make sure task is not used after configuration time" + ); + } resources.add(resource); return getProject().getLayout().fileProperty(outputDir.file(resource)); } diff --git a/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java b/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java index d95b3a0771fbe..323ea903063da 100644 --- a/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java +++ b/buildSrc/src/test/java/org/elasticsearch/gradle/ExportElasticsearchBuildResourcesTaskIT.java @@ -21,12 +21,7 @@ import org.elasticsearch.gradle.test.GradleIntegrationTestCase; import org.gradle.testkit.runner.BuildResult; -import org.gradle.testkit.runner.BuildTask; import org.gradle.testkit.runner.GradleRunner; -import org.gradle.testkit.runner.TaskOutcome; - -import java.nio.file.Files; -import java.nio.file.Path; public class ExportElasticsearchBuildResourcesTaskIT extends GradleIntegrationTestCase { @@ -44,17 +39,18 @@ public void testUpToDateWithSourcesConfigured() { .withArguments("buildResources", "-s", "-i") .withPluginClasspath() .build(); - assertTaskSuccessFull(result, ":buildResources"); + assertTaskSuccessfull(result, ":buildResources"); assertBuildFileExists(result, PROJECT_NAME, "build-tools-exported/checkstyle.xml"); - + assertBuildFileExists(result, PROJECT_NAME, "build-tools-exported/checkstyle_suppressions.xml"); result = GradleRunner.create() .withProjectDir(getProjectDir(PROJECT_NAME)) .withArguments("buildResources", "-s", "-i") .withPluginClasspath() .build(); - assertEquals(TaskOutcome.UP_TO_DATE, result.task(":buildResources").getOutcome()); + assertTaskUpToDate(result, ":buildResources"); assertBuildFileExists(result, PROJECT_NAME, "build-tools-exported/checkstyle.xml"); + assertBuildFileExists(result, PROJECT_NAME, "build-tools-exported/checkstyle_suppressions.xml"); } public void testImplicitTaskDependencyCopy() { @@ -63,9 +59,11 @@ public void testImplicitTaskDependencyCopy() { .withArguments("clean", "sampleCopyAll", "-s", "-i") .withPluginClasspath() .build(); - assertTaskSuccessFull(result, ":buildResources"); - assertTaskSuccessFull(result, ":sampleCopyAll"); + assertTaskSuccessfull(result, ":buildResources"); + assertTaskSuccessfull(result, ":sampleCopyAll"); assertBuildFileExists(result, PROJECT_NAME, "sampleCopyAll/checkstyle.xml"); + // This is a side effect of compile time reference + assertBuildFileExists(result, PROJECT_NAME, "sampleCopyAll/checkstyle_suppressions.xml"); } public void testImplicitTaskDependencyInputFileOfOther() { @@ -75,23 +73,17 @@ public void testImplicitTaskDependencyInputFileOfOther() { .withPluginClasspath() .build(); + assertTaskSuccessfull(result, ":sample"); assertBuildFileExists(result, PROJECT_NAME, "build-tools-exported/checkstyle.xml"); + assertBuildFileExists(result, PROJECT_NAME, "build-tools-exported/checkstyle_suppressions.xml"); } - private void assertTaskSuccessFull(BuildResult result, String taskName) { - BuildTask task = result.task(taskName); - if (task == null) { - fail("Expected task `" + taskName + "` to be successful, but it did not run"); - } - assertEquals(TaskOutcome.SUCCESS, task.getOutcome()); - } - - private void assertBuildFileExists(BuildResult result, String projectName, String path) { - Path absPath = getBuildDir(projectName).toPath().resolve(path); - assertTrue( - result.getOutput() + "\n\nExpected `" + absPath + "` to exists but it did not", - Files.exists(absPath) - ); + public void testIncorrectUsage() { + BuildResult result = GradleRunner.create() + .withProjectDir(getProjectDir(PROJECT_NAME)) + .withArguments("noConfigAfterExecution", "-s", "-i") + .withPluginClasspath() + .buildAndFail(); + assertOutputContains("buildResources can't be configured after the task ran"); } - } diff --git a/buildSrc/src/test/java/org/elasticsearch/gradle/test/GradleIntegrationTestCase.java b/buildSrc/src/test/java/org/elasticsearch/gradle/test/GradleIntegrationTestCase.java index 6cad8bc422bee..f00ab406a6c10 100644 --- a/buildSrc/src/test/java/org/elasticsearch/gradle/test/GradleIntegrationTestCase.java +++ b/buildSrc/src/test/java/org/elasticsearch/gradle/test/GradleIntegrationTestCase.java @@ -1,8 +1,13 @@ package org.elasticsearch.gradle.test; +import org.gradle.testkit.runner.BuildResult; +import org.gradle.testkit.runner.BuildTask; import org.gradle.testkit.runner.GradleRunner; +import org.gradle.testkit.runner.TaskOutcome; import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -61,4 +66,47 @@ protected void assertOutputDoesNotContain(String output, String... lines) { } } + protected void assertTaskSuccessfull(BuildResult result, String taskName) { + BuildTask task = result.task(taskName); + if (task == null) { + fail("Expected task `" + taskName + "` to be successful, but it did not run"); + } + assertEquals( + "Expected task to be successful but it was: " + task.getOutcome() + + "\n\nOutput is:\n" + result.getOutput() , + TaskOutcome.SUCCESS, + task.getOutcome() + ); + } + + protected void assertTaskUpToDate(BuildResult result, String taskName) { + BuildTask task = result.task(taskName); + if (task == null) { + fail("Expected task `" + taskName + "` to be up-to-date, but it did not run"); + } + assertEquals( + "Expected task to be up to date but it was: " + task.getOutcome() + + "\n\nOutput is:\n" + result.getOutput() , + TaskOutcome.UP_TO_DATE, + task.getOutcome() + ); + } + + protected void assertBuildFileExists(BuildResult result, String projectName, String path) { + Path absPath = getBuildDir(projectName).toPath().resolve(path); + assertTrue( + result.getOutput() + "\n\nExpected `" + absPath + "` to exists but it did not" + + "\n\nOutput is:\n" + result.getOutput(), + Files.exists(absPath) + ); + } + + protected void assertBuildFileDoesNotExists(BuildResult result, String projectName, String path) { + Path absPath = getBuildDir(projectName).toPath().resolve(path); + assertFalse( + result.getOutput() + "\n\nExpected `" + absPath + "` bo to exists but it did" + + "\n\nOutput is:\n" + result.getOutput(), + Files.exists(absPath) + ); + } } diff --git a/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle b/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle index 0e41bb21961e2..c0e3ac93133d3 100644 --- a/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle +++ b/buildSrc/src/testKit/elasticsearch-build-resources/build.gradle @@ -7,7 +7,6 @@ ext.noticeFile = file("$buildDir/dummy/notice") buildResources { take 'checkstyle.xml' - take 'minimumCompilerVersion' } task sampleCopyAll(type: Sync) { @@ -23,7 +22,17 @@ task sample { // dependsOn exportBuildResources.outputDir // for now it's just dependsOn buildResources + // we have to refference it at configuration time in order to be picked up + ext.checkstyle_suppressions = buildResources.take('checkstyle_suppressions.xml') doLast { - println "This task is using ${file(buildResources.take('minimumRuntimeVersion'))}" + println "This task is using ${file(checkstyle_suppressions)}" + } +} + +task noConfigAfterExecution { + dependsOn buildResources + doLast { + println "This should cause an error because we are refferencing " + + "${buildResources.take('checkstyle_suppressions.xml')} after the `buildResources` task has ran." } } \ No newline at end of file