Fix build cache misses caused by embedded reaper jar (#45404)

(cherry picked from commit 788feced760bc2a5f453ebb07f1dbb288c6232b2)
This commit is contained in:
Mark Vieira 2019-08-09 21:09:16 -07:00
parent b5c3c9767c
commit 491880edde
No known key found for this signature in database
GPG Key ID: CA947EF7E6D4B105
7 changed files with 81 additions and 18 deletions

View File

@ -86,18 +86,8 @@ compileMinimumRuntimeJava {
sourceCompatibility = 8
}
normalization {
runtimeClasspath {
// Ignore the embedded JAR as we track this separately below as a runtime dependency
ignore 'META-INF/*.jar'
}
}
jar {
from sourceSets.minimumRuntime.output
into('META-INF') {
from configurations.reaper
}
}
javadoc {
@ -135,7 +125,6 @@ dependencies {
testCompile "junit:junit:${props.getProperty('junit')}"
testCompile "com.carrotsearch.randomizedtesting:randomizedtesting-runner:${props.getProperty('randomizedrunner')}"
testCompile 'com.github.tomakehurst:wiremock-jre8-standalone:2.23.2'
reaper project('reaper')
minimumRuntimeCompile "junit:junit:${props.getProperty('junit')}"
minimumRuntimeCompile localGroovy()
minimumRuntimeCompile gradleApi()
@ -189,9 +178,11 @@ if (project != rootProject) {
configurations {
distribution
reaper
}
dependencies {
reaper project('reaper')
distribution project(':distribution:archives:windows-zip')
distribution project(':distribution:archives:oss-windows-zip')
distribution project(':distribution:archives:darwin-tar')
@ -203,6 +194,9 @@ if (project != rootProject) {
// for external projects we want to remove the marker file indicating we are running the Elasticsearch project
processResources {
exclude 'buildSrc.marker'
into('META-INF') {
from configurations.reaper
}
}
String localDownloads = "${rootProject.buildDir}/local-downloads"

View File

@ -1,4 +1,5 @@
jar {
archiveName = "${project.name}.jar"
manifest {
attributes 'Main-Class': 'org.elasticsearch.gradle.reaper.Reaper'
}

View File

@ -19,6 +19,7 @@
package org.elasticsearch.gradle;
import org.elasticsearch.gradle.tool.ClasspathUtils;
import org.gradle.api.GradleException;
import org.gradle.api.logging.Logger;
import org.gradle.internal.jvm.Jvm;
@ -27,11 +28,16 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UncheckedIOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ReaperService {
private static final String REAPER_CLASS = "org/elasticsearch/gradle/reaper/Reaper.class";
private static final Pattern REAPER_JAR_PATH_PATTERN = Pattern.compile("file:(.*)!/" + REAPER_CLASS);
private Logger logger;
private Path buildDir;
private Path inputDir;
@ -103,13 +109,7 @@ public class ReaperService {
private synchronized void ensureReaperStarted() {
if (reaperProcess == null) {
try {
// copy the reaper jar
Path jarPath = buildDir.resolve("reaper").resolve("reaper.jar");
Files.createDirectories(jarPath.getParent());
InputStream jarInput = ReaperPlugin.class.getResourceAsStream("/META-INF/reaper.jar");
try (OutputStream out = Files.newOutputStream(jarPath)) {
jarInput.transferTo(out);
}
Path jarPath = locateReaperJar();
// ensure the input directory exists
Files.createDirectories(inputDir);
@ -134,6 +134,41 @@ public class ReaperService {
}
}
private Path locateReaperJar() {
if (ClasspathUtils.isElasticsearchProject()) {
// when running inside the Elasticsearch build just pull find the jar in the runtime classpath
URL main = this.getClass().getClassLoader().getResource(REAPER_CLASS);
String mainPath = main.getFile();
Matcher matcher = REAPER_JAR_PATH_PATTERN.matcher(mainPath);
if (matcher.matches()) {
return Path.of(matcher.group(1));
} else {
throw new RuntimeException("Unable to locate " + REAPER_CLASS + " on build classpath.");
}
} else {
// copy the reaper jar
Path jarPath = buildDir.resolve("reaper").resolve("reaper.jar");
try {
Files.createDirectories(jarPath.getParent());
} catch (IOException e) {
throw new UncheckedIOException("Unable to create reaper JAR output directory " + jarPath.getParent(), e);
}
try (
OutputStream out = Files.newOutputStream(jarPath);
InputStream jarInput = this.getClass().getResourceAsStream("/META-INF/reaper.jar");
) {
logger.info("Copying reaper.jar...");
jarInput.transferTo(out);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
return jarPath;
}
}
private void ensureReaperAlive() {
if (reaperProcess.isAlive() == false) {
throw new IllegalStateException("Reaper process died unexpectedly! Check the log at " + logFile.toString());

View File

@ -0,0 +1 @@
implementation-class=org.elasticsearch.gradle.ReaperPlugin

View File

@ -0,0 +1,21 @@
package org.elasticsearch.gradle;
import org.elasticsearch.gradle.test.GradleIntegrationTestCase;
import org.gradle.testkit.runner.BuildResult;
import org.gradle.testkit.runner.GradleRunner;
import org.junit.Before;
public class ReaperPluginIT extends GradleIntegrationTestCase {
private GradleRunner runner;
@Before
public void setup() {
runner = getGradleRunner("reaper");
}
public void testCanLaunchReaper() {
BuildResult result = runner.withArguments(":launchReaper", "-S", "--info").build();
assertTaskSuccessful(result, ":launchReaper");
assertOutputContains(result.getOutput(), "Copying reaper.jar...");
}
}

View File

@ -0,0 +1,11 @@
plugins {
id 'elasticsearch.reaper'
}
task launchReaper {
doLast {
def reaper = project.extensions.getByName('reaper')
reaper.registerCommand('test', 'true')
reaper.unregister('test')
}
}