mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-10-26 05:50:39 +00:00
Parallelized mod builds
- Mod targets run through bounded Gradle workers with separate caches and daemon slots - Target logs retain verification failures and bounded output summaries - Nested tests use bounded forks and JVM thread counts - Lifecycle tests control deadlines through injected clocks
This commit is contained in:
1 parent
d7059d84a4
commit
fc810221bb
17 files changed
+447
-61
No files matched your search
@@ -0,0 +1,85 @@
|
||||
import org.gradle.api.GradleException;
|
||||
import org.gradle.api.logging.Logger;
|
||||
import org.gradle.api.logging.Logging;
|
||||
import org.gradle.process.ExecOperations;
|
||||
import org.gradle.workers.WorkAction;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public abstract class IrisModdedBuildAction implements WorkAction<IrisModdedBuildParameters> {
|
||||
private static final Logger LOGGER = Logging.getLogger(IrisModdedBuildAction.class);
|
||||
private static final int LOG_TAIL_BYTES = 16 * 1024;
|
||||
private static final int LOG_TAIL_LINES = 40;
|
||||
|
||||
@Inject
|
||||
protected abstract ExecOperations getExecOperations();
|
||||
|
||||
@Override
|
||||
public void execute() {
|
||||
IrisModdedBuildParameters parameters = getParameters();
|
||||
String label = parameters.getLabel().get();
|
||||
Path log = parameters.getLogFile().get().getAsFile().toPath();
|
||||
long started = System.nanoTime();
|
||||
LOGGER.lifecycle("{} started; log: {}", label, log);
|
||||
try {
|
||||
Files.createDirectories(log.getParent());
|
||||
try (OutputStream output = Files.newOutputStream(log)) {
|
||||
getExecOperations().exec(spec -> {
|
||||
spec.setWorkingDir(parameters.getWorkingDirectory().get().getAsFile());
|
||||
spec.commandLine(parameters.getCommandLine().get());
|
||||
spec.environment(parameters.getEnvironment().get());
|
||||
spec.setStandardOutput(output);
|
||||
spec.setErrorOutput(output);
|
||||
}).assertNormalExitValue();
|
||||
}
|
||||
ModdedArtifactVerifier.verify(parameters.getArtifactFile().get().getAsFile(),
|
||||
parameters.getRequiredEntries().get(), parameters.getForbiddenCoreClasses().get());
|
||||
ModdedArtifactVerifier.verifyJavaRuntime(parameters.getArtifactFile().get().getAsFile(),
|
||||
parameters.getJavaRuntime().get());
|
||||
LOGGER.lifecycle("{} succeeded in {} ms", label,
|
||||
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - started));
|
||||
} catch (Exception failure) {
|
||||
appendFailure(log, failure);
|
||||
String details;
|
||||
try {
|
||||
details = logTail(log);
|
||||
} catch (IOException unreadable) {
|
||||
failure.addSuppressed(unreadable);
|
||||
details = "Log could not be read.";
|
||||
}
|
||||
LOGGER.error(label + " failed; log: " + log + System.lineSeparator() + details, failure);
|
||||
throw new GradleException(label + " failed; log: " + log, failure);
|
||||
}
|
||||
}
|
||||
|
||||
static String logTail(Path log) throws IOException {
|
||||
try (RandomAccessFile input = new RandomAccessFile(log.toFile(), "r")) {
|
||||
long offset = Math.max(0L, input.length() - LOG_TAIL_BYTES);
|
||||
input.seek(offset);
|
||||
byte[] bytes = new byte[(int) (input.length() - offset)];
|
||||
input.readFully(bytes);
|
||||
String[] lines = new String(bytes, StandardCharsets.UTF_8).split("\\R");
|
||||
return String.join(System.lineSeparator(), Arrays.copyOfRange(lines,
|
||||
Math.max(0, lines.length - LOG_TAIL_LINES), lines.length));
|
||||
}
|
||||
}
|
||||
|
||||
private static void appendFailure(Path log, Exception failure) {
|
||||
try (PrintWriter output = new PrintWriter(Files.newBufferedWriter(log, StandardCharsets.UTF_8,
|
||||
StandardOpenOption.CREATE, StandardOpenOption.APPEND))) {
|
||||
failure.printStackTrace(output);
|
||||
} catch (IOException unwritable) {
|
||||
failure.addSuppressed(unwritable);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user