Skip to content

Instantly share code, notes, and snippets.

@orbyfied
Last active March 1, 2022 08:33
Show Gist options
  • Save orbyfied/9b353248b43bc502517934e540522d49 to your computer and use it in GitHub Desktop.
Save orbyfied/9b353248b43bc502517934e540522d49 to your computer and use it in GitHub Desktop.
Distributes any module builds to servers in the parent directory of the root build.gradle
/*
Copyright 2022 - orbyfied (https://www.github.com/orbyfied)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
How to use:
0. Make sure the relative path from your root project directory
to your servers is ../servers/*
1. Copy this code into your root build.gradle
If you dont have a root build.gradle just create it without the Java plugin
2. Put this code in any distributed submodules build.gradle
```
// required for autobuild
task("buildDefault") {
dependsOn("shadowJar") // for shadowJar
dependsOn("jar") // for normal jar
}
```
The module name describes how the module should be distributed: anything ending with "api" won't be
distributed to anything but is rather excpected to be implemented in a project distributed to all
servers. Anything ending in "core" will be distributed to all servers (proxy and normals). Anything
ending in "proxy" will be distributed to the proxy server, and anything ending in "server" will be
distributed to all servers. You can also have it distribute to a specific server, by making your module
name "server-<servername>".
*/
void println(Object o) {
System.out.println(o);
}
void print(Object o) {
System.out.print(o);
}
String pfn(Path p) {
return p.getFileName().toString();
}
void copyf(Path a, Path b) {
Files.copy(a, b, StandardCopyOption.REPLACE_EXISTING);
}
void copyToServer(Path jar, Path server) {
copyf(jar, server.resolve("plugins").resolve(pfn(jar)));
}
enum ModuleType {
API(false, false, false),
CORE(true, true, false),
SERVER(false, true, false),
PROXY(true, false, false),
SPECIFIC(false, false, true);
private boolean forAllProxies;
private boolean forAllServers;
private boolean isSpecific;
ModuleType(boolean forAllProxies, boolean forAllServers, boolean isSpecific) {
this.forAllProxies = forAllProxies;
this.forAllServers = forAllServers;
this.isSpecific = isSpecific;
}
boolean isForAllProxies() {
return forAllProxies
}
boolean isForAllServers() {
return forAllServers
}
boolean isSpecific() {
return isSpecific
}
static ModuleType typeOf(Path path) {
String pathName = path.toFile().getName();
if (pathName.endsWith("api")) return API;
if (pathName.endsWith("core")) return CORE;
if (pathName.endsWith("server")) return SERVER;
if (pathName.endsWith("proxy")) return PROXY;
if (pathName.startsWith("server")) return SPECIFIC;
return null;
}
}
// deploys all plugin builds to their respective servers
task("deployServerLocal") {
doFirst {
long t1 = System.currentTimeMillis();
// create process builder
final ProcessBuilder pb = new ProcessBuilder();
// here
Path here = rootDir.toPath()
// servers directory
Path serversDir = here.toAbsolutePath().parent.resolve("servers");
// list modules
List<Path> modules = Files.list(here)
.filter(path1 -> Files.exists(path1.resolve("build.gradle")))
.collect(Collectors.toList());
println("DEPLOY(local): Listed " + modules.size() + " modules");
// collect servers
List<Path> mcServers = Files.list(serversDir)
.filter(path1 -> !pfn(path1).equals("Proxy"))
.collect(Collectors.toList());
println("DEPLOY(local): Listed " + mcServers.size() + " Minecraft instance servers.");
// collect proxy server
Path proxyServer = serversDir.resolve("Proxy");
println("DEPLOY(local): Listed proxy server: " + proxyServer);
// status
int success = 0;
int failed = 0;
// iterate over modules
// build and distribute jars
for (Path modulePath : modules) {
// get name and project
String name = pfn(modulePath)
// get module type
ModuleType type = ModuleType.typeOf(modulePath);
println("DEPLOY(local): Distributing module " + name + " with type: " + type);
// get jar file
Path build = modulePath.resolve("build");
Path libs = build != null ? build.resolve("libs") : null;
List<Path> lfs = null;
if (Files.exists(libs))
lfs = Files.list(libs)
.filter(path1 -> pfn(path1).endsWith(".jar"))
.collect(Collectors.toList());
if (lfs == null || lfs.size() == 0) { // lfs is null if libs or build doesnt exist
// try to build module if no build exists yet
print("DEPLOY(local): Attempting to build module " + name + ": ");
try {
// run gradlew commands
pb.command("cmd.exe", "/c", "cd ${projectDir}")
.command("cmd.exe", "/c", "gradlew :${name}:buildDefault")
.start().waitFor(15, TimeUnit.SECONDS)
lfs = Files.list(libs)
.filter(path1 -> pfn(path1).endsWith(".jar"))
.collect(Collectors.toList());
print("OK\n")
} catch (Exception e) {
// catch any errors
print("ERR: " + e + "\n")
println("DEPLOY(local): No build found for module " + name + " (build/libs/*.jar)");
failed++;
continue;
}
}
// get jar path
Path jar = lfs.get(0);
// distribute
List<Throwable> stackTracesToPrint = new ArrayList<>();
boolean hasOne = false;
print("DEPLOY(local): Distributing " + name + " to ");
if (type.isForAllServers()) { // distribute to servers
hasOne = true
print("SERVERS:")
try {
// copy to all servers
for (Path p : mcServers) copyToServer(jar, p);
print("OK ");
} catch (Exception e) {
print("FAILED ");
stackTracesToPrint.add(e);
}
}
if (type.isForAllProxies()) { // distribute to proxy
hasOne = true
print("PROXY:")
try {
// copy to proxy
copyToServer(jar, proxyServer);
print("OK ");
} catch (Exception e) {
print("FAILED ");
stackTracesToPrint.add(e);
}
}
if (type.isSpecific()) { // distribute to specific server
hasOne = true
print("SERVER");
// get server name from module name
String[] elems = name.split("-");
if (elems.length < 2) {
print(":FAILED invalid server name format")
failed++;
} else {
String serverName = elems[1];
print("(" + serverName + "):")
Path path = serversDir.resolve(serverName);
if (!Files.exists(path)) {
print("FAILED server does not exist")
failed++;
} else {
try {
copyToServer(jar, path);
print("OK")
} catch (Exception e) {
print("ERR")
stackTracesToPrint.add(e)
}
}
}
}
if (!hasOne) {
print("NONE")
}
print("\n")
// print stack traces
for (Throwable t : stackTracesToPrint) {
t.printStackTrace();
}
// success
success++;
}
long t2 = System.currentTimeMillis();
long t = t2 - t1;
println("DEPLOY(local): (i) Finished in " + t + "ms: " + success + " done, " + failed + " failed");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment