[FEATURE] Update build pipeline, fix multi release jar with proguard

This commit is contained in:
Gravita 2023-10-25 22:41:06 +07:00
parent 79f933646c
commit 62e9276481
15 changed files with 78 additions and 62 deletions

View file

@ -18,7 +18,6 @@
public class BinaryPipeline { public class BinaryPipeline {
public final List<LauncherBuildTask> tasks = new ArrayList<>(); public final List<LauncherBuildTask> tasks = new ArrayList<>();
public final AtomicLong count = new AtomicLong(0);
public final Path buildDir; public final Path buildDir;
public final String nameFormat; public final String nameFormat;
private transient final Logger logger = LogManager.getLogger(); private transient final Logger logger = LogManager.getLogger();
@ -72,11 +71,20 @@ public <T extends LauncherBuildTask> Optional<T> getTaskByClass(Class<T> taskCla
return tasks.stream().filter(taskClass::isInstance).map(taskClass::cast).findFirst(); return tasks.stream().filter(taskClass::isInstance).map(taskClass::cast).findFirst();
} }
public Optional<LauncherBuildTask> getTaskBefore(Predicate<LauncherBuildTask> pred) {
LauncherBuildTask last = null;
for(var e : tasks) {
if(pred.test(e)) {
return Optional.ofNullable(last);
}
last = e;
}
return Optional.empty();
}
public void build(Path target, boolean deleteTempFiles) throws IOException { public void build(Path target, boolean deleteTempFiles) throws IOException {
logger.info("Building launcher binary file"); logger.info("Building launcher binary file");
count.set(0); // set jar number
Path thisPath = null; Path thisPath = null;
boolean isNeedDelete = false;
long time_start = System.currentTimeMillis(); long time_start = System.currentTimeMillis();
long time_this = time_start; long time_this = time_start;
for (LauncherBuildTask task : tasks) { for (LauncherBuildTask task : tasks) {
@ -86,19 +94,17 @@ public void build(Path target, boolean deleteTempFiles) throws IOException {
long time_task_end = System.currentTimeMillis(); long time_task_end = System.currentTimeMillis();
long time_task = time_task_end - time_this; long time_task = time_task_end - time_this;
time_this = time_task_end; time_this = time_task_end;
if (isNeedDelete && deleteTempFiles && oldPath != thisPath) Files.deleteIfExists(oldPath);
isNeedDelete = task.allowDelete();
logger.info("Task {} processed from {} millis", task.getName(), time_task); logger.info("Task {} processed from {} millis", task.getName(), time_task);
} }
long time_end = System.currentTimeMillis(); long time_end = System.currentTimeMillis();
if (isNeedDelete && deleteTempFiles) IOHelper.move(thisPath, target); if (deleteTempFiles) IOHelper.move(thisPath, target);
else IOHelper.copy(thisPath, target); else IOHelper.copy(thisPath, target);
IOHelper.deleteDir(buildDir, false); IOHelper.deleteDir(buildDir, false);
logger.info("Build successful from {} millis", time_end - time_start); logger.info("Build successful from {} millis", time_end - time_start);
} }
public String nextName(String taskName) { public String nextName(String taskName) {
return nameFormat.formatted(taskName, count.getAndIncrement()); return nameFormat.formatted(taskName);
} }
public Path nextPath(String taskName) { public Path nextPath(String taskName) {

View file

@ -7,7 +7,7 @@ public final class EXEL4JLauncherBinary extends LauncherBinary {
public EXEL4JLauncherBinary(LaunchServer server) { public EXEL4JLauncherBinary(LaunchServer server) {
super(server, LauncherBinary.resolve(server, ".exe"), "Launcher-%s-%d.exe"); super(server, LauncherBinary.resolve(server, ".exe"), "Launcher-%s.exe");
} }
@Override @Override

View file

@ -9,7 +9,7 @@
public class EXELauncherBinary extends LauncherBinary { public class EXELauncherBinary extends LauncherBinary {
public EXELauncherBinary(LaunchServer server) { public EXELauncherBinary(LaunchServer server) {
super(server, LauncherBinary.resolve(server, ".exe"), "Launcher-%s-%d.exe"); super(server, LauncherBinary.resolve(server, ".exe"), "Launcher-%s.exe");
} }
@Override @Override

View file

@ -23,7 +23,7 @@ public final class JARLauncherBinary extends LauncherBinary {
public final Map<String, Path> files; public final Map<String, Path> files;
public JARLauncherBinary(LaunchServer server) throws IOException { public JARLauncherBinary(LaunchServer server) throws IOException {
super(server, resolve(server, ".jar"), "Launcher-%s-%d.jar"); super(server, resolve(server, ".jar"), "Launcher-%s.jar");
count = new AtomicLong(0); count = new AtomicLong(0);
runtimeDir = server.dir.resolve(Launcher.RUNTIME_DIR); runtimeDir = server.dir.resolve(Launcher.RUNTIME_DIR);
buildDir = server.dir.resolve("build"); buildDir = server.dir.resolve("build");

View file

@ -74,9 +74,4 @@ public Path process(Path inputFile) throws IOException {
return out; return out;
} }
@Override
public boolean allowDelete() {
return true;
}
} }

View file

@ -68,11 +68,6 @@ private boolean filter(String name) {
return exclusions.stream().anyMatch(name::startsWith); return exclusions.stream().anyMatch(name::startsWith);
} }
@Override
public boolean allowDelete() {
return true;
}
public List<Path> getJars() { public List<Path> getJars() {
return jars; return jars;
} }

View file

@ -81,9 +81,4 @@ public Path process(Path inputFile) throws IOException {
} }
return inputFile; return inputFile;
} }
@Override
public boolean allowDelete() {
return false;
}
} }

View file

@ -43,9 +43,4 @@ public Path process(Path inputFile) throws IOException {
} }
return output; return output;
} }
@Override
public boolean allowDelete() {
return true;
}
} }

View file

@ -7,6 +7,4 @@ public interface LauncherBuildTask {
String getName(); String getName();
Path process(Path inputFile) throws IOException; Path process(Path inputFile) throws IOException;
boolean allowDelete();
} }

View file

@ -51,7 +51,7 @@ public String getName() {
@Override @Override
public Path process(Path inputJar) throws IOException { public Path process(Path inputJar) throws IOException {
Path outputJar = server.launcherBinary.nextPath("main"); Path outputJar = server.launcherBinary.nextPath(this);
try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(outputJar))) { try (ZipOutputStream output = new ZipOutputStream(IOHelper.newOutput(outputJar))) {
BuildContext context = new BuildContext(output, reader.getCp(), this); BuildContext context = new BuildContext(output, reader.getCp(), this);
initProps(); initProps();
@ -161,11 +161,6 @@ public byte[] transformClass(byte[] bytes, String classname, BuildContext contex
return result; return result;
} }
@Override
public boolean allowDelete() {
return true;
}
@FunctionalInterface @FunctionalInterface
public interface Transformer { public interface Transformer {
byte[] transform(byte[] input, String classname, BuildContext context); byte[] transform(byte[] input, String classname, BuildContext context);

View file

@ -53,11 +53,6 @@ public Path process(Path inputFile) throws IOException {
return result; return result;
} }
@Override
public boolean allowDelete() {
return false;
}
public void tryUnpack() throws IOException { public void tryUnpack() throws IOException {
logger.info("Unpacking launcher native guard list and runtime"); logger.info("Unpacking launcher native guard list and runtime");
UnpackHelper.unpackZipNoCheck("runtime.zip", server.launcherBinary.runtimeDir); UnpackHelper.unpackZipNoCheck("runtime.zip", server.launcherBinary.runtimeDir);

View file

@ -104,9 +104,4 @@ private void autoSign(Path inputFile, Path signedFile) throws IOException {
} }
} }
} }
@Override
public boolean allowDelete() {
return true;
}
} }

View file

@ -59,11 +59,6 @@ public Path process(Path inputFile) throws IOException {
return output; return output;
} }
@Override
public boolean allowDelete() {
return true;
}
private Path setConfig() { private Path setConfig() {
Path path = server.launcherEXEBinary.nextPath(getName()); Path path = server.launcherEXEBinary.nextPath(getName());
Config config = new Config(); Config config = new Config();

View file

@ -15,9 +15,7 @@
import proguard.ConfigurationParser; import proguard.ConfigurationParser;
import proguard.ProGuard; import proguard.ProGuard;
import java.io.IOException; import java.io.*;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
@ -26,6 +24,9 @@
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
public class ProGuardComponent extends Component implements AutoCloseable, Reconfigurable { public class ProGuardComponent extends Component implements AutoCloseable, Reconfigurable {
private static final Logger logger = LogManager.getLogger(); private static final Logger logger = LogManager.getLogger();
@ -36,6 +37,7 @@ public class ProGuardComponent extends Component implements AutoCloseable, Recon
public transient ProguardConf proguardConf; public transient ProguardConf proguardConf;
private transient LaunchServer launchServer; private transient LaunchServer launchServer;
private transient ProGuardBuildTask buildTask; private transient ProGuardBuildTask buildTask;
private transient ProGuardMultiReleaseFixer fixerTask;
public static boolean checkFXJMods(Path path) { public static boolean checkFXJMods(Path path) {
if (!IOHelper.exists(path.resolve("javafx.base.jmod"))) if (!IOHelper.exists(path.resolve("javafx.base.jmod")))
@ -75,7 +77,9 @@ public void init(LaunchServer launchServer) {
this.launchServer = launchServer; this.launchServer = launchServer;
proguardConf = new ProguardConf(launchServer, this); proguardConf = new ProguardConf(launchServer, this);
this.buildTask = new ProGuardBuildTask(launchServer, proguardConf, this); this.buildTask = new ProGuardBuildTask(launchServer, proguardConf, this);
this.fixerTask = new ProGuardMultiReleaseFixer(launchServer, this, "ProGuard.".concat(componentName));
launchServer.launcherBinary.addAfter((v) -> v.getName().startsWith(modeAfter), buildTask); launchServer.launcherBinary.addAfter((v) -> v.getName().startsWith(modeAfter), buildTask);
launchServer.launcherBinary.addAfter((v) -> v.getName().equals("ProGuard.".concat(componentName)), fixerTask);
} }
@Override @Override
@ -111,6 +115,59 @@ public void invoke(String... args) throws Exception {
return null; return null;
} }
public static class ProGuardMultiReleaseFixer implements LauncherBuildTask {
private final LaunchServer server;
private final ProGuardComponent component;
private final String proguardTaskName;
public ProGuardMultiReleaseFixer(LaunchServer server, ProGuardComponent component, String proguardTaskName) {
this.server = server;
this.component = component;
this.proguardTaskName = proguardTaskName;
}
@Override
public String getName() {
return "ProGuardMultiReleaseFixer.".concat(component.componentName);
}
@Override
public Path process(Path inputFile) throws IOException {
LauncherBuildTask task = server.launcherBinary.getTaskBefore((x) -> proguardTaskName.equals(x.getName())).get();
Path lastPath = server.launcherBinary.nextPath(task);
if(Files.notExists(lastPath)) {
logger.error("{} not exist. Multi-Release JAR fix not applied!", lastPath);
return inputFile;
}
Path outputPath = server.launcherBinary.nextPath(this);
try(ZipOutputStream output = new ZipOutputStream(new FileOutputStream(outputPath.toFile()))) {
try(ZipInputStream input = new ZipInputStream(new FileInputStream(inputFile.toFile()))) {
ZipEntry entry = input.getNextEntry();
while(entry != null) {
ZipEntry newEntry = new ZipEntry(entry.getName());
output.putNextEntry(newEntry);
input.transferTo(output);
entry = input.getNextEntry();
}
}
try(ZipInputStream input = new ZipInputStream(new FileInputStream(lastPath.toFile()))) {
ZipEntry entry = input.getNextEntry();
while(entry != null) {
if(!entry.getName().startsWith("META-INF/versions")) {
entry = input.getNextEntry();
continue;
}
ZipEntry newEntry = new ZipEntry(entry.getName());
output.putNextEntry(newEntry);
input.transferTo(output);
entry = input.getNextEntry();
}
}
}
return outputPath;
}
}
public static class ProGuardBuildTask implements LauncherBuildTask { public static class ProGuardBuildTask implements LauncherBuildTask {
private final LaunchServer server; private final LaunchServer server;
private final ProGuardComponent component; private final ProGuardComponent component;
@ -157,11 +214,6 @@ public Path process(Path inputFile) throws IOException {
IOHelper.copy(inputFile, outputJar); IOHelper.copy(inputFile, outputJar);
return outputJar; return outputJar;
} }
@Override
public boolean allowDelete() {
return true;
}
} }
public static class ProguardConf { public static class ProguardConf {

View file

@ -14,6 +14,6 @@
verLog4j = '2.20.0' verLog4j = '2.20.0'
verMySQLConn = '8.1.0' verMySQLConn = '8.1.0'
verPostgreSQLConn = '42.6.0' verPostgreSQLConn = '42.6.0'
verProguard = '7.4.0-beta02' verProguard = '7.4.0'
verLaunch4j = '3.50' verLaunch4j = '3.50'
} }