Last active
March 1, 2022 08:33
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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