Build using Toothpick scripts (#122)

Co-authored-by: BillyGalbreath <blake.galbreath@gmail.com>
This commit is contained in:
Jason
2020-12-18 05:04:33 -08:00
committed by GitHub
parent 391f9addfd
commit 69c6484904
77 changed files with 1224 additions and 745 deletions

12
.gitignore vendored
View File

@@ -1,3 +1,7 @@
# JVM crash related
core.*
hs_err_pid*
# Intellij
.idea/
*.iml
@@ -14,6 +18,12 @@ out/
nbproject/
nbactions.xml
# Gradle
!gradle-wrapper.jar
.gradle/
build/
*/build/
# we use maven!
build.xml
@@ -46,3 +56,5 @@ Purpur-Server
Purpur-API
mc-dev
purpurclip.jar
*clip.jar
last-paper

View File

@@ -8,14 +8,15 @@ Patches to Purpur are very simple, but center around the directories 'Purpur-API
Assuming you already have forked the repository:
1. Pull the latest changes from the main repository
2. Type `./purpur patch` in git bash to apply the changes from upstream
3. cd into `Purpur-Server` for server changes, and `Purpur-API` for API changes
2. Update the Paper submodule if necessary: `git submodule update --init --recursive` and `./gradlew setupUpstream`
3. Type `./gradlew applyPatches` to apply the latest Purpur patches
4. cd into `Purpur-Server` for server changes, and `Purpur-API` for API changes
These directories aren't git repositories in the traditional sense:
- Every single commit in Purpur-Server/API is a patch.
- 'origin/master' points to a directory similar to Purpur-Server/API but for Paper
- Typing `git status` should show that we are 10 or 11 commits ahead of master, meaning we have 10 or 11 patches that Purpur doesn't
- Typing `git status` should show that we are 10 or 11 commits ahead of master, meaning we have 10 or 11 patches that Paper doesn't
- If it says something like `212 commits ahead, 207 commits behind`, then type `git fetch` to update purpur
## Adding Patches
@@ -26,7 +27,7 @@ Adding patches to Purpur is very simple:
3. Type `git add .` to add your changes
4. Run `git commit` with the desired patch message
5. `cd ../` to get back to the project root
6. Run `./purpur rebuild` in the main directory to convert your commit into a new patch
6. Run `./gradlew rebuildPatches` in the main directory to convert your commit into a new patch
7. PR your patches back to this repository
Your commit will be converted into a patch that you can then PR into Purpur
@@ -39,18 +40,17 @@ just need to add it to our import script to be ran during the patch process.
1. Save (rebuild) any patches you are in the middle of working on!
2. Identify the names of the files you want to import.
- A complete list of all possible file names can be found at ```./Paper/work/Minecraft/$MCVER/net/minecraft/server```
3. Open the file at `./scripts/importmcdev.sh` and add the name of your file to the script near the end.
4. Update the project to rebuild with the new imports `./purpur up`
5. Re-patch the server `./purpur patch`
6. Edit away!
3. Open the file at `./buildSrc/src/main/kotlin/MCDevImports.kt` and add the name of your file to the `nmsImports` set.
4. Re-patch the server to make the imports take effect `./gradlew applyPatches`
5. Edit away!
This change is temporary! DO NOT COMMIT CHANGES TO THE `importmcdev.sh` FILE!
Once you have made your changes to the new file, and rebuilt patches, you may undo your changes to `importmcdev.sh`
This change is temporary! DO NOT COMMIT CHANGES TO THE `MCDevImports.kt` FILE!
Once you have made your changes to the new file, and rebuilt patches, you may undo your changes to `MCDevImports.kt`
Any file modified in a patch file gets automatically imported, so you only need this temporarily
to import it to create the first patch.
To undo your changes to the file, type `git checkout scripts/importmcdev.sh`, or just remove the import lines you added previously.
To undo your changes to the file, type `git checkout buildSrc/src/main/kotlin/MCDevImports.kt`, or just remove the import lines you added previously.
## Modifying Patches
Modifying previous patches is a bit more complex:
@@ -62,7 +62,7 @@ However, while in the middle of an edit, unless you also reset your API to a rel
1. If you have changes you are working on type `git stash` to store them for later.
- Later you can type `git stash pop` to get them back.
2. Type `git rebase -i upstream/upstream`
2. Type `git rebase -i origin/master`
- It should show something like [this](https://gist.github.com/zachbr/21e92993cb99f62ffd7905d7b02f3159).
3. Replace `pick` with `edit` for the commit/patch you want to modify, and "save" the changes.
- Only do this for one commit at a time.
@@ -72,7 +72,7 @@ However, while in the middle of an edit, unless you also reset your API to a rel
- **MAKE SURE TO ADD `--amend`** or else a new patch will be created.
- You can also modify the commit message here.
7. Type `git rebase --continue` to finish rebasing.
8. Type `./purpur rebuild` in the main directory.
8. Type `./gradlew rebuildPatches` in the main directory.
- This will modify the appropriate patches based on your commits.
9. PR your modifications back to this project.
@@ -83,9 +83,9 @@ This method has the benefit of being able to compile to test your change without
1. Make your change while at HEAD
2. Make a temporary commit. You don't need to make a message for this.
3. Type `git rebase -i upstream/upstream`, move (cut) your temporary commit and move it under the line of the patch you wish to modify.
3. Type `git rebase -i origin/master`, move (cut) your temporary commit and move it under the line of the patch you wish to modify.
4. Change the `pick` with `f` (fixup) or `s` (squash) if you need to edit the commit message
5. Type `./purpur rebuild` in the main directory
5. Type `./gradlew rebuildPatches` in the main directory
- This will modify the appropriate patches based on your commits
6. PR your modifications back to this project.

View File

@@ -49,7 +49,7 @@ Downloads API endpoints:
Everything is licensed under the MIT license, and is free to be used in your own fork.
See [starlis/empirecraft](https://github.com/starlis/empirecraft) and [electronicboy/byof](https://github.com/electronicboy/byof)
See [starlis/empirecraft](https://github.com/starlis/empirecraft), [electronicboy/byof](https://github.com/electronicboy/byof), and [mikroskeemsrealm/Toothpick](https://github.com/mikroskeemsrealm/Toothpick)
for the license of material used/modified by this project.
## bStats
@@ -76,14 +76,15 @@ Purpur API maven dependency:
```
Purpur API gradle dependency:
```groovy
maven {
name 'purpur'
url 'https://repo.pl3x.net/'
```kotlin
repositories {
maven("https://repo.pl3x.net/")
}
```
```groovy
compileOnly 'net.pl3x.purpur:purpur-api:1.16.4-R0.1-SNAPSHOT'
```kotlin
dependencies {
compileOnly("net.pl3x.purpur", "purpur-api", "1.16.4-R0.1-SNAPSHOT")
}
```
Yes, this also includes all API provided by Paper, Spigot, and Bukkit.
@@ -94,14 +95,12 @@ Yes, this also includes all API provided by Paper, Spigot, and Bukkit.
Run the following commands in the root directory:
```
git submodule update --init
./purpur up
./purpur patch
./gradlew applyPatches
```
#### Creating a patch
Patches are effectively just commits in either `Purpur-API` or `Purpur-Server`.
To create one, just add a commit to either repo and run `./purpur rb`, and a
To create one, just add a commit to either repo and run `./gradlew rebuildPatches`, and a
patch will be placed in the patches folder. Modifying commits will also modify its
corresponding patch file.
@@ -110,7 +109,8 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for more detailed information.
#### Compiling
Use the command `./purpur build` to build the api and server. Compiled jars
will be placed under `Purpur-API/target` and `Purpur-Server/target`.
Use the command `./gradlew build` to build the api and server. Compiled jars
will be placed under `Purpur-API/build/libs` and `Purpur-Server/build/libs`.
To get a purpurclip jar, run `./purpur jar`.
To get a purpurclip jar, run `./gradlew paperclip`.
To install the `purpur-api` and `purpur` dependencies to your local maven repo, run `./gradlew publishToMavenLocal`

41
build.gradle.kts Normal file
View File

@@ -0,0 +1,41 @@
plugins {
`java-library`
toothpick
}
toothpick {
forkName = "Purpur"
groupId = "net.pl3x.purpur"
val versionTag = System.getenv("BUILD_NUMBER")
?: "\"${gitCmd("rev-parse", "--short", "HEAD").output}\""
forkVersion = "git-$forkName-$versionTag"
minecraftVersion = "1.16.4"
nmsRevision = "R0.1-SNAPSHOT"
upstream = "Paper"
server {
project = project(":$forkNameLowercase-server")
patchesDir = rootProject.projectDir.resolve("patches/server")
}
api {
project = project(":$forkNameLowercase-api")
patchesDir = rootProject.projectDir.resolve("patches/api")
}
}
subprojects {
repositories {
mavenCentral()
maven("https://repo.aikar.co/content/groups/aikar/")
maven("https://nexus.velocitypowered.com/repository/velocity-artifacts-snapshots/")
maven("https://libraries.minecraft.net")
mavenLocal()
}
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
withSourcesJar()
}
}

26
buildSrc/build.gradle.kts Normal file
View File

@@ -0,0 +1,26 @@
val kotlinxDomVersion = "0.0.10"
val shadowVersion = "6.1.0"
plugins {
`kotlin-dsl`
}
repositories {
mavenCentral()
jcenter()
maven("https://plugins.gradle.org/m2/")
}
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx.dom:$kotlinxDomVersion")
implementation("com.github.jengelman.gradle.plugins:shadow:$shadowVersion")
}
gradlePlugin {
plugins {
register("Toothpick") {
id = "toothpick"
implementationClass = "Toothpick"
}
}
}

View File

@@ -0,0 +1,105 @@
import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar
import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer
import org.gradle.api.Project
import org.gradle.api.plugins.JavaLibraryPlugin
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
import org.gradle.api.publish.maven.tasks.GenerateMavenPom
import org.gradle.api.tasks.bundling.Jar
import org.gradle.api.tasks.testing.Test
import org.gradle.kotlin.dsl.apply
import org.gradle.kotlin.dsl.attributes
import org.gradle.kotlin.dsl.create
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.getValue
import org.gradle.kotlin.dsl.getting
internal fun Project.configureSubprojects() {
subprojects {
apply<JavaLibraryPlugin>()
apply<MavenPublishPlugin>()
extensions.configure(PublishingExtension::class.java) {
publications {
create<MavenPublication>("mavenJava") {
artifactId = if (project.name.endsWith("server")) rootProject.name else project.name
groupId = rootProject.group as String
version = rootProject.version as String
from(components["java"])
pom {
name.set(project.name)
url.set("https://github.com/pl3xgaming/Purpur")
}
}
}
}
when {
project.name.endsWith("server") -> configureServerProject()
project.name.endsWith("api") -> configureApiProject()
}
}
}
private fun Project.configureServerProject() {
apply<ShadowPlugin>()
val generatePomFileForMavenJavaPublication by tasks.getting(GenerateMavenPom::class) {
destination = project.buildDir.resolve("tmp/pom.xml")
}
@Suppress("UNUSED_VARIABLE")
val test by tasks.getting(Test::class) {
// didn't bother to look into why these fail. paper excludes them in paperweight as well though
exclude("org/bukkit/craftbukkit/inventory/ItemStack*Test.class")
}
val shadowJar by tasks.getting(ShadowJar::class) {
dependsOn(generatePomFileForMavenJavaPublication)
transform(Log4j2PluginsCacheFileTransformer::class.java)
manifest {
attributes(
"Main-Class" to "org.bukkit.craftbukkit.Main",
"Implementation-Title" to "CraftBukkit",
"Implementation-Version" to toothpick.forkVersion,
"Implementation-Vendor" to java.text.SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'")
.format(java.util.Date()),
"Specification-Title" to "Bukkit",
"Specification-Version" to "${project.version}",
"Specification-Vendor" to "Bukkit Team"
)
}
from(project.buildDir.resolve("tmp/pom.xml")) {
// dirty hack to make "java -Dpaperclip.install=true -jar paperclip.jar" work without forking paperclip
into("META-INF/maven/io.papermc.paper/paper")
}
// Don't like to do this but sadly have to do this for compatibility reasons
val relocVersion = toothpick.minecraftVersion.replace(".", "_")
relocate("org.bukkit.craftbukkit", "org.bukkit.craftbukkit.v$relocVersion") {
exclude("org.bukkit.craftbukkit.Main*")
}
relocate("net.minecraft.server", "net.minecraft.server.v$relocVersion")
}
tasks.getByName("build") {
dependsOn(shadowJar)
}
}
@Suppress("UNUSED_VARIABLE")
private fun Project.configureApiProject() {
val jar by this.tasks.getting(Jar::class) {
doFirst {
buildDir.resolve("tmp/pom.properties")
.writeText("version=${project.version}")
}
from(buildDir.resolve("tmp/pom.properties")) {
into("META-INF/maven/${project.group}/${project.name}")
}
manifest {
attributes("Automatic-Module-Name" to "org.bukkit")
}
}
}

View File

@@ -0,0 +1,2 @@
const val taskGroup = "toothpick"
const val internalTaskGroup = "toothpick_internal"

View File

@@ -0,0 +1,66 @@
import kotlinx.dom.elements
import kotlinx.dom.parseXml
import kotlinx.dom.search
import org.gradle.api.Project
import org.gradle.api.artifacts.dsl.RepositoryHandler
import org.gradle.kotlin.dsl.DependencyHandlerScope
import org.gradle.kotlin.dsl.maven
import org.gradle.kotlin.dsl.project
fun RepositoryHandler.loadRepositories(project: Project) {
val pomFile = project.projectDir.resolve("pom.xml")
if (!pomFile.exists()) return
val dom = parseXml(pomFile)
val repositoriesBlock = dom.search("repositories").firstOrNull() ?: return
// Load repositories
repositoriesBlock.elements("repository").forEach { repositoryElem ->
val url = repositoryElem.search("url").firstOrNull()?.textContent ?: return@forEach
maven(url)
}
}
fun DependencyHandlerScope.loadDependencies(project: Project) {
val pomFile = project.projectDir.resolve("pom.xml")
if (!pomFile.exists()) return
val dom = parseXml(pomFile)
val dependenciesBlock = dom.search("dependencies").firstOrNull() ?: return
// Load dependencies
dependenciesBlock.elements("dependency").forEach { dependencyElem ->
val groupId = dependencyElem.search("groupId").firstOrNull()!!.textContent
val artifactId = dependencyElem.search("artifactId").firstOrNull()!!.textContent
val version = dependencyElem.search("version").firstOrNull()!!.textContent.applyReplacements(
mapOf(
"project.version" to "${project.toothpick.minecraftVersion}-${project.toothpick.nmsRevision}",
"minecraft.version" to project.toothpick.minecraftVersion
)
)
val scope = dependencyElem.search("scope").firstOrNull()?.textContent
val classifier = dependencyElem.search("classifier").firstOrNull()?.textContent
val dependencyString = "${groupId}:${artifactId}:${version}${classifier?.run { ":$this" } ?: ""}"
project.logger.debug("Read dependency '{}' from '{}'", dependencyString, pomFile.absolutePath)
// Special case API
if (artifactId == "${project.toothpick.forkNameLowercase}-api"
|| artifactId == "${project.toothpick.upstreamLowercase}-api"
) {
if (project.name.endsWith("-server")) {
add("api", project(":${project.toothpick.forkNameLowercase}-api"))
}
return@forEach
}
when (scope) {
"compile", null -> add("api", dependencyString)
"provided" -> {
add("compileOnly", dependencyString)
add("testImplementation", dependencyString)
}
"runtime" -> add("runtimeOnly", dependencyString)
"test" -> add("testImplementation", dependencyString)
}
}
}

View File

@@ -0,0 +1,68 @@
import org.gradle.api.Project
import task.createApplyPatchesTask
import task.createImportMCDevTask
import task.createInitGitSubmodulesTask
import task.createPaperclipTask
import task.createRebuildPatchesTask
import task.createSetupUpstreamTask
import task.createUpdateUpstreamTask
import task.createUpstreamCommitTask
@Suppress("UNUSED_VARIABLE")
internal fun Project.initToothpickTasks() {
if (project.hasProperty("fast")) {
gradle.taskGraph.whenReady {
gradle.taskGraph.allTasks.filter {
it.name == "test" || it.name.contains("javadoc", ignoreCase = true)
}.forEach {
it.onlyIf { false }
}
}
}
tasks.getByName("build") {
doFirst {
val readyToBuild =
upstreamDir.resolve(".git").exists()
&& toothpick.subprojects.values.all { it.projectDir.exists() && it.baseDir.exists() }
if (!readyToBuild) {
error("Workspace has not been setup. Try running `./gradlew applyPatches` first")
}
}
}
val initGitSubmodules = createInitGitSubmodulesTask()
val setupUpstream = createSetupUpstreamTask {
dependsOn(initGitSubmodules)
}
val importMCDev = createImportMCDevTask {
mustRunAfter(setupUpstream)
}
val paperclip = createPaperclipTask {
dependsOn(tasks.getByName("build"))
dependsOn(subprojects.map { it.tasks.getByName("build") })
}
val applyPatches = createApplyPatchesTask {
// If Paper has not been setup yet or if we modified the submodule (i.e. upstream update), patch
if (!lastUpstream.exists()
|| !upstreamDir.resolve(".git").exists()
|| lastUpstream.readText() != gitHash(upstreamDir)
) {
dependsOn(setupUpstream)
}
mustRunAfter(setupUpstream)
dependsOn(importMCDev)
}
val rebuildPatches = createRebuildPatchesTask()
val updateUpstream = createUpdateUpstreamTask {
finalizedBy(setupUpstream)
}
val upstreamCommit = createUpstreamCommitTask()
}

View File

@@ -0,0 +1,28 @@
/**
* This is the set of extra NMS files which will be imported as part of the patch process
*
* See `./Paper/work/Minecraft/$MCVER/net/minecraft/server` for a list of possible files
*
* The `.java` extension is always assumed and should be excluded
*
* NOTE: Do not commit changes to this set! Instead make changes, rebuild patches, and commit the modified patches.
* Files already modified in existing patches will be imported automatically.
*/
val nmsImports = setOf<String>(
// ex:
//"EntityZombieVillager"
)
data class LibraryImport(val group: String, val library: String, val prefix: String, val file: String)
/**
* This is the set of extra files to import into the server workspace from libraries
*
* Changes to this set should be committed to the repo, as these won't be automatically imported.
*/
val libraryImports = setOf<LibraryImport>(
LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier", "CommandDispatcher"),
LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier/tree", "LiteralCommandNode"),
LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier/suggestion", "SuggestionsBuilder"),
LibraryImport("com.mojang", "brigadier", "com/mojang/brigadier/arguments", "BoolArgumentType")
)

View File

@@ -0,0 +1,9 @@
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.create
class Toothpick : Plugin<Project> {
override fun apply(project: Project) {
project.extensions.create<ToothpickExtension>("toothpick", project.objects)
}
}

View File

@@ -0,0 +1,52 @@
import org.gradle.api.Project
import org.gradle.api.model.ObjectFactory
import java.io.File
import java.util.Locale
@Suppress("UNUSED_PARAMETER")
open class ToothpickExtension(objects: ObjectFactory) {
lateinit var project: Project
lateinit var forkName: String
val forkNameLowercase
get() = forkName.toLowerCase(Locale.ENGLISH)
lateinit var forkVersion: String
lateinit var groupId: String
lateinit var minecraftVersion: String
lateinit var nmsRevision: String
lateinit var upstream: String
val upstreamLowercase
get() = upstream.toLowerCase(Locale.ENGLISH)
lateinit var serverProject: ToothpickSubproject
fun server(receiver: ToothpickSubproject.() -> Unit) {
serverProject = ToothpickSubproject()
receiver(serverProject)
}
lateinit var apiProject: ToothpickSubproject
fun api(receiver: ToothpickSubproject.() -> Unit) {
apiProject = ToothpickSubproject()
receiver(apiProject)
}
val subprojects: Map<String, ToothpickSubproject>
get() = if (::forkName.isInitialized) mapOf(
"$forkName-API" to apiProject,
"$forkName-Server" to serverProject
) else emptyMap()
val paperDir: File by lazy {
if (upstream == "Paper") {
project.upstreamDir
} else {
project.upstreamDir.walk().find {
it.name == "Paper" && it.isDirectory
&& it.resolve("work/Minecraft/${minecraftVersion}").exists()
} ?: error("Failed to find Paper directory!")
}
}
val paperWorkDir: File
get() = paperDir.resolve("work/Minecraft/${minecraftVersion}")
}

View File

@@ -0,0 +1,30 @@
import org.gradle.api.Project
import org.gradle.kotlin.dsl.findByType
import java.io.File
import java.nio.file.Path
val Project.toothpick: ToothpickExtension
get() = rootProject.extensions.findByType(ToothpickExtension::class)!!
fun Project.toothpick(receiver: ToothpickExtension.() -> Unit) {
toothpick.project = this
receiver(toothpick)
allprojects {
group = toothpick.groupId
version = "${toothpick.minecraftVersion}-${toothpick.nmsRevision}"
}
configureSubprojects()
initToothpickTasks()
}
val Project.lastUpstream: File
get() = rootProject.projectDir.resolve("last-${toothpick.upstreamLowercase}")
val Project.rootProjectDir: File
get() = rootProject.projectDir
val Project.upstreamDir: File
get() = rootProject.projectDir.resolve(toothpick.upstream)
val Project.projectPath: Path
get() = projectDir.toPath()

View File

@@ -0,0 +1,20 @@
import org.gradle.api.Project
import java.io.File
class ToothpickSubproject {
lateinit var project: Project
val baseDir: File by lazy {
val name = project.name
val upstream = project.toothpick.upstream
val suffix = if (name.endsWith("server")) "Server" else "API"
project.upstreamDir.resolve("$upstream-$suffix")
}
val projectDir: File
get() = project.projectDir
lateinit var patchesDir: File
operator fun component1(): File = baseDir
operator fun component2(): File = projectDir
operator fun component3(): File = patchesDir
}

View File

@@ -0,0 +1,86 @@
import org.gradle.api.Project
import java.io.File
import java.util.LinkedList
import kotlin.streams.asSequence
data class CmdResult(val exitCode: Int, val output: String?)
fun Project.cmd(
vararg args: String,
dir: File = rootProject.projectDir,
printOut: Boolean = false
): CmdResult {
val process = ProcessBuilder()
.command(*args)
.redirectErrorStream(true)
.directory(dir)
.start()
val output = process.inputStream.bufferedReader().use { reader ->
reader.lines().asSequence()
.onEach {
if (printOut) {
logger.lifecycle(it)
} else {
logger.debug(it)
}
}
.toCollection(LinkedList())
.joinToString(separator = "\n")
}
val exit = process.waitFor()
return CmdResult(exit, output)
}
fun ensureSuccess(
cmd: CmdResult,
errorHandler: CmdResult.() -> Unit = {}
): String? {
val (exit, output) = cmd
if (exit != 0) {
errorHandler(cmd)
error("Failed to run command, exit code is $exit")
}
return output
}
fun Project.gitCmd(
vararg args: String,
dir: File = rootProject.projectDir,
printOut: Boolean = false
): CmdResult =
cmd("git", *args, dir = dir, printOut = printOut)
fun Project.bashCmd(
vararg args: String,
dir: File = rootProject.projectDir,
printOut: Boolean = false
): CmdResult =
cmd("bash", "-c", *args, dir = dir, printOut = printOut)
internal fun String.applyReplacements(replacements: Map<String, String>): String {
var result = this
for ((key, value) in replacements) {
result = result.replace("\${$key}", value)
}
return result
}
private fun Project.gitSigningEnabled(repo: File): Boolean =
gitCmd("config", "commit.gpgsign", dir = repo).output?.toBoolean() == true
internal fun Project.temporarilyDisableGitSigning(repo: File): Boolean {
val isCurrentlyEnabled = gitSigningEnabled(repo)
if (isCurrentlyEnabled) {
gitCmd("config", "commit.gpgsign", "false", dir = repo)
}
return isCurrentlyEnabled
}
internal fun Project.reEnableGitSigning(repo: File) {
gitCmd("config", "commit.gpgsign", "true", dir = repo)
}
fun Project.gitHash(repo: File): String =
gitCmd("rev-parse", "HEAD", dir = repo).output ?: ""
val jenkins = System.getenv("JOB_NAME") != null

View File

@@ -0,0 +1,52 @@
package task
import ensureSuccess
import gitCmd
import org.gradle.api.Project
import org.gradle.api.Task
import reEnableGitSigning
import taskGroup
import temporarilyDisableGitSigning
import toothpick
import java.nio.file.Files
internal fun Project.createApplyPatchesTask(
receiver: Task.() -> Unit = {}
): Task = tasks.create("applyPatches") {
receiver(this)
group = taskGroup
doLast {
for ((name, subproject) in toothpick.subprojects) {
val (sourceRepo, projectDir, patchesDir) = subproject
// Reset or initialize subproject
logger.lifecycle(">>> Resetting subproject $name")
if (projectDir.exists()) {
ensureSuccess(gitCmd("reset", "--hard", "origin/master", dir = projectDir))
} else {
ensureSuccess(gitCmd("clone", sourceRepo.absolutePath, projectDir.absolutePath))
}
logger.lifecycle(">>> Done resetting subproject $name")
// Apply patches
val patchPaths = Files.newDirectoryStream(patchesDir.toPath())
.map { it.toFile() }
.filter { it.name.endsWith(".patch") }
.sorted()
.takeIf { it.isNotEmpty() } ?: continue
val patches = patchPaths.map { it.absolutePath }.toTypedArray()
val wasGitSigningEnabled = temporarilyDisableGitSigning(projectDir)
logger.lifecycle(">>> Applying patches to $name")
val gitCommand = arrayListOf("am", "--3way", "--ignore-whitespace", *patches)
ensureSuccess(gitCmd(*gitCommand.toTypedArray(), dir = projectDir, printOut = true)) {
if (wasGitSigningEnabled) reEnableGitSigning(projectDir)
}
if (wasGitSigningEnabled) reEnableGitSigning(projectDir)
logger.lifecycle(">>> Done applying patches to $name")
}
}
}

View File

@@ -0,0 +1,84 @@
package task
import LibraryImport
import ensureSuccess
import gitCmd
import internalTaskGroup
import libraryImports
import nmsImports
import org.gradle.api.Project
import org.gradle.api.Task
import toothpick
internal fun Project.createImportMCDevTask(
receiver: Task.() -> Unit = {}
): Task = tasks.create("importMCDev") {
receiver(this)
group = internalTaskGroup
val upstreamServer = toothpick.serverProject.baseDir
val importLog = arrayListOf("Extra mc-dev imports")
fun importNMS(className: String) {
logger.lifecycle("Importing n.m.s.$className")
importLog.add("Imported n.m.s.$className")
val source = toothpick.paperWorkDir.resolve("spigot/net/minecraft/server/$className.java")
if (!source.exists()) error("Missing NMS: $className")
val target = upstreamServer.resolve("src/main/java/net/minecraft/server/$className.java")
source.copyTo(target)
}
fun importLibrary(import: LibraryImport) {
val (group, lib, prefix, file) = import
logger.lifecycle("Importing $group.$lib $prefix/$file")
importLog.add("Imported $group.$lib $prefix/$file")
val source = toothpick.paperWorkDir.resolve("libraries/$group/$lib/$prefix/$file.java")
if (!source.exists()) error("Missing Base: $lib $prefix/$file")
val targetDir = upstreamServer.resolve("src/main/java/$prefix")
val target = targetDir.resolve("$file.java")
targetDir.mkdirs()
source.copyTo(target)
}
doLast {
logger.lifecycle(">>> Importing mc-dev")
val lastCommitIsMCDev = gitCmd(
"log", "-1", "--oneline",
dir = upstreamServer
).output?.contains("Extra mc-dev imports") == true
if (lastCommitIsMCDev) {
ensureSuccess(
gitCmd(
"reset", "--hard", "origin/master",
dir = upstreamServer,
printOut = true
)
)
}
(toothpick.serverProject.patchesDir.listFiles() ?: error("No patches in server?")).asSequence()
.flatMap { it.readLines().asSequence() }
.filter { it.startsWith("+++ b/src/main/java/net/minecraft/server/") }
.distinct()
.map { it.substringAfter("/server/").substringBefore(".java") }
.filter { !upstreamServer.resolve("src/main/java/net/minecraft/server/$it.java").exists() }
.map { toothpick.paperWorkDir.resolve("spigot/net/minecraft/server/$it.java") }
.filter {
val exists = it.exists()
if (!it.exists()) logger.lifecycle("NMS ${it.nameWithoutExtension} is either missing, or is a new file added through a patch")
exists
}
.map { it.nameWithoutExtension }
.forEach(::importNMS)
// Imports from MCDevImports.kt
nmsImports.forEach(::importNMS)
libraryImports.forEach(::importLibrary)
val add = gitCmd("add", ".", "-A", dir = upstreamServer).exitCode == 0
val commit = gitCmd("commit", "-m", importLog.joinToString("\n"), dir = upstreamServer).exitCode == 0
if (!add || !commit) {
logger.lifecycle(">>> Didn't import any extra files")
}
logger.lifecycle(">>> Done importing mc-dev")
}
}

View File

@@ -0,0 +1,21 @@
package task
import gitCmd
import org.gradle.api.Project
import org.gradle.api.Task
import taskGroup
import upstreamDir
internal fun Project.createInitGitSubmodulesTask(
receiver: Task.() -> Unit = {}
): Task = tasks.create("initGitSubmodules") {
receiver(this)
group = taskGroup
onlyIf { !upstreamDir.resolve(".git").exists() }
doLast {
val exit = gitCmd("submodule", "update", "--init", "--recursive", printOut = true).exitCode
if (exit != 0) {
error("Failed to checkout git submodules: git exited with code $exit")
}
}
}

View File

@@ -0,0 +1,39 @@
package task
import cmd
import ensureSuccess
import jenkins
import org.gradle.api.Project
import org.gradle.api.Task
import rootProjectDir
import taskGroup
import toothpick
internal fun Project.createPaperclipTask(
receiver: Task.() -> Unit = {}
): Task = tasks.create("paperclip") {
receiver(this)
group = taskGroup
doLast {
val workDir = toothpick.paperDir.resolve("work")
val paperclipDir = workDir.resolve("Paperclip")
val vanillaJarPath =
workDir.resolve("Minecraft/${toothpick.minecraftVersion}/${toothpick.minecraftVersion}.jar").absolutePath
val patchedJarPath = toothpick.serverProject.projectDir.resolve(
"build/libs/${toothpick.forkNameLowercase}-server-$version-all.jar"
).absolutePath
logger.lifecycle(">>> Building paperclip")
val paperclipCmd = arrayListOf(
"mvn", "clean", "package",
"-Dmcver=${toothpick.minecraftVersion}",
"-Dpaperjar=$patchedJarPath",
"-Dvanillajar=$vanillaJarPath"
)
if (jenkins) paperclipCmd.add("-Dstyle.color=never")
ensureSuccess(cmd(*paperclipCmd.toTypedArray(), dir = paperclipDir, printOut = true))
val paperClip = paperclipDir.resolve("assembly/target/paperclip-${toothpick.minecraftVersion}.jar")
val destination = rootProjectDir.resolve("${toothpick.forkNameLowercase}-paperclip.jar")
paperClip.copyTo(destination, overwrite = true)
logger.lifecycle(">>> ${toothpick.forkNameLowercase}-paperclip.jar saved to root project directory")
}
}

View File

@@ -0,0 +1,45 @@
package task
import ensureSuccess
import gitCmd
import org.gradle.api.Project
import org.gradle.api.Task
import taskGroup
import toothpick
@Suppress("UNUSED_VARIABLE")
internal fun Project.createRebuildPatchesTask(
receiver: Task.() -> Unit = {}
): Task = tasks.create("rebuildPatches") {
receiver(this)
group = taskGroup
doLast {
for ((name, subproject) in toothpick.subprojects) {
val (sourceRepo, projectDir, patchesDir) = subproject
if (!patchesDir.exists()) {
patchesDir.mkdirs()
}
logger.lifecycle(">>> Rebuilding patches for $name")
// Nuke old patches
patchesDir.listFiles()
?.filter { it.name.endsWith(".patch") }
?.forEach { it.delete() }
// And generate new
ensureSuccess(
gitCmd(
"format-patch",
"--no-stat", "--zero-commit", "--full-index", "--no-signature", "-N",
"-o", patchesDir.absolutePath, "origin/master",
dir = projectDir,
printOut = true
)
)
logger.lifecycle(">>> Done rebuilding patches for $name")
}
}
}

View File

@@ -0,0 +1,29 @@
package task
import bashCmd
import gitHash
import lastUpstream
import org.gradle.api.Project
import org.gradle.api.Task
import taskGroup
import toothpick
import upstreamDir
internal fun Project.createSetupUpstreamTask(
receiver: Task.() -> Unit = {}
): Task = tasks.create("setupUpstream") {
receiver(this)
group = taskGroup
doLast {
// this whole thing assumes we're forking either paper or a byof project atm
val result = bashCmd(
"./${toothpick.upstreamLowercase} patch",
dir = upstreamDir,
printOut = true
)
if (result.exitCode != 0) {
error("Failed to apply upstream patches: script exited with code ${result.exitCode}")
}
lastUpstream.writeText(gitHash(upstreamDir))
}
}

View File

@@ -0,0 +1,23 @@
package task
import ensureSuccess
import gitCmd
import org.gradle.api.Project
import org.gradle.api.Task
import rootProjectDir
import taskGroup
import toothpick
import upstreamDir
internal fun Project.createUpdateUpstreamTask(
receiver: Task.() -> Unit = {}
): Task = tasks.create("updateUpstream") {
receiver(this)
group = taskGroup
doLast {
ensureSuccess(gitCmd("fetch", dir = upstreamDir, printOut = true))
ensureSuccess(gitCmd("reset", "--hard", "origin/master", dir = upstreamDir, printOut = true))
ensureSuccess(gitCmd("add", toothpick.upstream, dir = rootProjectDir, printOut = true))
ensureSuccess(gitCmd("submodule", "update", "--init", "--recursive", dir = upstreamDir, printOut = true))
}
}

View File

@@ -0,0 +1,33 @@
package task
import ensureSuccess
import gitCmd
import org.gradle.api.Project
import org.gradle.api.Task
import taskGroup
import toothpick
import upstreamDir
internal fun Project.createUpstreamCommitTask(
receiver: Task.() -> Unit = {}
): Task = tasks.create("upstreamCommit") {
receiver(this)
group = taskGroup
doLast {
val oldRev = ensureSuccess(gitCmd("ls-tree", "HEAD", toothpick.upstream))
?.substringAfter("commit ")?.substringBefore("\t")
val gitChangelog =
ensureSuccess(gitCmd("log", "--oneline", "$oldRev...HEAD", printOut = true, dir = upstreamDir)) {
logger.lifecycle("No upstream changes to commit?")
}
val commitMessage = """
|Updated Upstream (${toothpick.upstream})
|
|Upstream has released updates that appear to apply and compile correctly
|
|${toothpick.upstream} Changes:
|$gitChangelog
""".trimMargin()
ensureSuccess(gitCmd("commit", "-m", commitMessage, printOut = true))
}
}

View File

@@ -1 +0,0 @@
1.16.4--8ff078813db86d42db9fd900c0f093f05b9594c4

2
gradle.properties Normal file
View File

@@ -0,0 +1,2 @@
org.gradle.daemon=true
org.gradle.jvmargs=-Xmx2G

BIN
gradle/wrapper/gradle-wrapper.jar vendored Normal file

Binary file not shown.

View File

@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

185
gradlew vendored Executable file
View File

@@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

89
gradlew.bat vendored Normal file
View File

@@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -1,68 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: William Blake Galbreath <blake.galbreath@gmail.com>
Date: Sat, 4 May 2019 00:57:16 -0500
Subject: [PATCH] Rebrand
diff --git a/pom.xml b/pom.xml
index 4516ba097e8afc3e422efc368311fa66e967c05a..f0696d8c1dede705f6dd3fd0162864dfd42d2fdf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,20 +1,19 @@
-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
- <groupId>com.tuinity</groupId>
- <artifactId>tuinity-parent</artifactId>
+ <groupId>net.pl3x.purpur</groupId>
+ <artifactId>purpur-parent</artifactId>
<version>dev-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
- <artifactId>tuinity-api</artifactId>
+ <artifactId>purpur-api</artifactId>
<version>1.16.4-R0.1-SNAPSHOT</version>
<packaging>jar</packaging>
- <name>Tuinity-API</name>
- <url>https://github.com/Spottedleaf/Tuinity</url>
+ <name>Purpur-API</name>
+ <url>https://github.com/pl3xgaming/Purpur</url>
<description>An enhanced plugin API for Minecraft servers.</description>
<properties>
@@ -149,7 +148,7 @@
</dependencies>
<build>
- <defaultGoal>clean install</defaultGoal>
+ <defaultGoal>clean install javadoc:javadoc</defaultGoal>
<plugins>
<plugin>
<groupId>net.md-5</groupId>
@@ -227,6 +226,14 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.2.0</version>
+ <executions>
+ <execution>
+ <id>attach-javadocs</id>
+ <goals>
+ <goal>jar</goal>
+ </goals>
+ </execution>
+ </executions>
<configuration>
<links>
<link>https://guava.dev/releases/21.0/api/docs/</link>
@@ -234,6 +241,7 @@
<link>https://javadoc.io/doc/org.jetbrains/annotations-java5/19.0.0/</link>
<link>https://javadoc.io/doc/net.md-5/bungeecord-chat/1.16-R0.3/</link>
</links>
+ <additionalOptions>-Xdoclint:none</additionalOptions>
</configuration>
</plugin>
</plugins>

View File

@@ -5,85 +5,22 @@ Subject: [PATCH] Rebrand
diff --git a/pom.xml b/pom.xml
index 78c2a8bbcc0132f891c8aa545529d20aa0d9eb57..0c982c3f0eb9430fcec47477de1babe6f253f2aa 100644
index 78c2a8bbcc0132f891c8aa545529d20aa0d9eb57..422bed88a0860f768e162a38a1c16265451f5990 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,11 +1,11 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
- <artifactId>tuinity</artifactId>
+ <artifactId>purpur</artifactId>
<packaging>jar</packaging>
<version>1.16.4-R0.1-SNAPSHOT</version>
- <name>Tuinity-Server</name>
- <url>https://github.com/Spottedleaf/Tuinity</url>
+ <name>Purpur-Server</name>
+ <url>https://github.com/pl3xgaming/Purpur</url>
<properties>
<!-- <skipTests>true</skipTests> Paper - This [was] not going to end well -->
@@ -18,16 +18,16 @@
</properties>
<parent>
- <groupId>com.tuinity</groupId>
- <artifactId>tuinity-parent</artifactId>
+ <groupId>net.pl3x.purpur</groupId>
+ <artifactId>purpur-parent</artifactId>
<version>dev-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
@@ -26,8 +26,10 @@
<dependencies>
<dependency>
- <groupId>com.tuinity</groupId>
- <artifactId>tuinity-api</artifactId>
+ <!-- Purpur start - our "upstream" is Paper (not Tuinity), so this is necessary for DependencyLoading.kt to work properly -->
+ <groupId>net.pl3x.purpur</groupId>
+ <artifactId>purpur-api</artifactId>
+ <!-- Purpur end -->
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
@@ -50,6 +50,20 @@
<version>${minecraft.version}-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
+ <!-- Purpur start -->
+ <dependency>
+ <groupId>org.mozilla</groupId>
+ <artifactId>rhino</artifactId>
+ <version>1.7.7.1</version>
+ <scope>compile</scope>
+ </dependency>
+ <dependency>
+ <groupId>cat.inspiracio</groupId>
+ <artifactId>rhino-js-engine</artifactId>
+ <version>1.7.7.1</version>
+ <scope>compile</scope>
+ </dependency>
+ <!-- Purpur end -->
<dependency>
<groupId>net.minecrell</groupId>
<artifactId>terminalconsoleappender</artifactId>
@@ -175,15 +189,15 @@
<!-- This builds a completely 'ready to start' jar with all dependencies inside -->
<build>
- <finalName>tuinity-${minecraft.version}</finalName>
- <defaultGoal>install</defaultGoal> <!-- Paper -->
+ <finalName>purpur-${minecraft.version}</finalName>
+ <defaultGoal>clean install</defaultGoal> <!-- Paper -->
<plugins>
<plugin>
<groupId>com.lukegb.mojo</groupId>
<artifactId>gitdescribe-maven-plugin</artifactId>
<version>1.3</version>
<configuration>
- <outputPrefix>git-Tuinity-</outputPrefix> <!-- Tuinity -->
+ <outputPrefix>git-Purpur-</outputPrefix> <!-- Tuinity -->
<scmDirectory>..</scmDirectory>
</configuration>
<executions>
diff --git a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java b/src/main/java/com/destroystokyo/paper/console/PaperConsole.java
index 74ed02fa9296583977bb721014b10ff8b708b43c..c1280478ee4565003883df9607d4a8a0e8fe4faa 100644
--- a/src/main/java/com/destroystokyo/paper/console/PaperConsole.java

29
pom.xml
View File

@@ -1,29 +0,0 @@
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>net.pl3x.purpur</groupId>
<artifactId>purpur-parent</artifactId>
<version>dev-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Purpur (Parent)</name>
<repositories>
<repository>
<id>aikar</id>
<url>https://repo.aikar.co/content/groups/aikar/</url>
</repository>
<repository>
<id>velocity-snapshots</id>
<url>https://nexus.velocitypowered.com/repository/velocity-artifacts-snapshots/</url>
</repository>
</repositories>
<build>
<defaultGoal>clean install</defaultGoal>
<finalName>${project.artifactId}</finalName>
</build>
<modules>
<module>Purpur-API</module>
<module>Purpur-Server</module>
</modules>
</project>

106
purpur
View File

@@ -1,106 +0,0 @@
#!/usr/bin/env bash
# get base dir regardless of execution location
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
SOURCE="$(readlink "$SOURCE")"
[[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
SOURCE=$([[ "$SOURCE" == /* ]] && echo "$SOURCE" || echo "$PWD/${SOURCE#./}")
basedir=$(dirname "$SOURCE")
. "$basedir"/scripts/init.sh
purpurstash() {
STASHED=$(git stash)
}
purpurunstash() {
if [[ "$STASHED" != "No local changes to save" ]]; then
git stash pop
fi
}
case "$1" in
"p" | "patch" | "apply")
(
set -e
cd "$basedir"
scripts/apply.sh "$basedir"
)
;;
"b" | "bu" | "build")
(
basedir
mvn -N install
cd Purpur-API
mvn -e clean install
cd ../Paper/Paper-MojangAPI
mvn -e clean install
cd ../../Purpur-Server
mvn -e clean install
)
;;
"rb" | "rbp" | "rebuild")
(
set -e
cd "$basedir"
scripts/rebuildpatches.sh "$basedir"
)
;;
"am" | "amend")
(
cd "$basedir"/Purpur-API/
git add .
git commit --amend --no-edit
cd "$basedir"/Purpur-Server/
git add .
git commit --amend --no-edit
cd "$basedir"
scripts/rebuildpatches.sh "$basedir"
)
;;
"up" | "upstream")
(
cd "$basedir"
scripts/upstream.sh "$2"
)
;;
"jar" | "purpurclip")
(
basedir
cd "$basedir"
if [ "$2" != "fast" ]; then
scripts/upstream.sh
./scripts/apply.sh "$basedir"
cd "$basedir"
mvn -N install
cd Purpur-API
mvn -e clean install
cd ../Paper/Paper-MojangAPI
mvn -e clean install
cd ../../Purpur-Server
mvn -e clean install
cd "$basedir"
fi
./scripts/purpurclip.sh
)
;;
*)
echo "Purpur build tool command. This provides a variety of commands to build and manage the Purpur build"
echo "environment. For all of the functionality of this command to be available, you must first run the"
echo "'setup' command. View below for details. For essential building and patching, you do not need to do the setup."
echo ""
echo " Normal commands:"
echo " * p, patch | Apply all patches to top of Paper without building it"
echo " * b, build | Build Purpur API and Server"
echo " * rb, rebuild | Rebuild patches"
echo " * am, amend | Amend current edits to last patches"
echo " * up, upstream | Build Paper upstream, pass arg up to update paper"
echo " * jar, purpurclip | Apply all patches and build the project, purpurclip.jar will be output"
;;
esac
unset -f purpurstash
unset -f purpurunstash

View File

@@ -1,92 +0,0 @@
#!/usr/bin/env bash
# get base dir regardless of execution location
# resolve shell-specifics
case "$(echo "$SHELL" | sed -E 's|/usr(/local)?||g')" in
"/bin/zsh")
RCPATH="$HOME/.zshrc"
SOURCE="${BASH_SOURCE[0]:-${(%):-%N}}"
;;
*)
RCPATH="$HOME/.bashrc"
if [[ -f "$HOME/.bash_aliases" ]]; then
RCPATH="$HOME/.bash_aliases"
fi
SOURCE="${BASH_SOURCE[0]}"
;;
esac
# get base dir regardless of execution location
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
[[ "$SOURCE" != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
. "$(dirname "$SOURCE")/init.sh"
PS1="$"
paperVer=$(cat current-paper)
gpgsign="$(git config commit.gpgsign || echo "false")"
echo "Rebuilding Forked projects.... "
function applyPatch {
what=$1
what_name=$(basename "$what")
target=$2
branch=$3
patch_folder=$4
cd "$basedir/$what" || exit
git fetch --all
git branch -f upstream "$branch" >/dev/null
cd "$basedir" || exit
if [ ! -d "$basedir/$target" ]; then
mkdir "$basedir/$target"
cd "$basedir/$target" || exit
git init
git remote add origin "$5"
cd "$basedir" || exit
fi
cd "$basedir/$target" || exit
# Disable GPG signing before AM, slows things down and doesn't play nicely.
# There is also zero rational or logical reason to do so for these sub-repo AMs.
# Calm down kids, it's re-enabled (if needed) immediately after, pass or fail.
git config commit.gpgsign false
echo "Resetting $target to $what_name..."
git remote rm upstream > /dev/null 2>&1
git remote add upstream "$basedir"/"$what" >/dev/null 2>&1
git checkout master 2>/dev/null || git checkout -b master
git fetch upstream >/dev/null 2>&1
git reset --hard upstream/upstream
echo " Applying patches to $target..."
git am --abort >/dev/null 2>&1
if ! git am --3way --ignore-whitespace "$basedir/patches/$patch_folder/"*.patch
then
echo " Something did not apply cleanly to $target."
echo " Please review above details and finish the apply then"
echo " save the changes with rebuildPatches.sh"
exit 1
else
echo " Patches applied cleanly to $target"
fi
}
function enableCommitSigningIfNeeded {
if [[ "$gpgsign" == "true" ]]; then
git config commit.gpgsign true
fi
}
echo "Importing MC-DEV"
./scripts/importmcdev.sh "$basedir" || exit 1
(
(applyPatch Paper/Paper-API Purpur-API HEAD api "$API_REPO" &&
applyPatch Paper/Paper-Server Purpur-Server HEAD server "$SERVER_REPO") || exit 1
enableCommitSigningIfNeeded
) || (
echo "Failed to apply patches"
enableCommitSigningIfNeeded
exit 1
) || exit 1

View File

@@ -1,37 +0,0 @@
#!/usr/bin/env bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
. "$(dirname "$SOURCE")/init.sh"
cd "$basedir" || exit
paperVer=$(cat current-paper)
minecraftversion=$(grep <"$basedir"/Paper/work/BuildData/info.json minecraftVersion | cut -d '"' -f 4)
decompile="Paper/work/Minecraft/$minecraftversion/spigot"
mkdir -p mc-dev/src/net/minecraft/server
cd mc-dev || exit
if [ ! -d ".git" ]; then
git init
fi
rm src/net/minecraft/server/*.java
cp "$basedir"/"$decompile"/net/minecraft/server/*.java src/net/minecraft/server
base="$basedir/Paper/Paper-Server/src/main/java/net/minecraft/server"
cd "$basedir"/mc-dev/src/net/minecraft/server/ || exit
for file in $(/bin/ls "$base"); do
if [ -f "$file" ]; then
rm -f "$file"
fi
done
cd "$basedir"/mc-dev || exit
git add . -A
git commit . -m "mc-dev"
git tag -a "$paperVer" -m "$paperVer" 2>/dev/null

View File

@@ -1,120 +0,0 @@
#!/usr/bin/env bash
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
. "$(dirname "$SOURCE")/init.sh"
workdir=$basedir/Paper/work
minecraftversion=$(grep <"$basedir"/Paper/work/BuildData/info.json minecraftVersion | cut -d '"' -f 4)
decompiledir=$workdir/Minecraft/$minecraftversion/spigot
nms="net/minecraft/server"
export MODLOG=""
cd "$basedir" || exit
function containsElement() {
local e
for e in "${@:2}"; do
[[ "$e" == "$1" ]] && return 0
done
return 1
}
export importedmcdev=""
function import() {
if [ -f "$basedir/Paper/Paper-Server/src/main/java/net/minecraft/server/$1.java" ]; then
echo "ALREADY IMPORTED $1"
return 0
fi
export importedmcdev="$importedmcdev $1"
file="${1}.java"
target="$basedir/Paper/Paper-Server/src/main/java/$nms/$file"
base="$decompiledir/$nms/$file"
if [[ ! -f "$target" ]]; then
export MODLOG="$MODLOG Imported $file from mc-dev\n"
echo "$(bashColor 1 32) Copying $(bashColor 1 34)$base $(bashColor 1 32)to$(bashColor 1 34) $target $(bashColorReset)"
cp "$base" "$target"
else
echo "$(bashColor 1 33) UN-NEEDED IMPORT STATEMENT:$(bashColor 1 34) $file $(bashColorReset)"
fi
}
function importLibrary() {
group=$1
lib=$2
prefix=$3
shift 3
for file in "$@"; do
file="$prefix/$file"
target="$basedir/Paper/Paper-Server/src/main/java/$file"
targetdir=$(dirname "$target")
mkdir -p "${targetdir}"
base="$workdir/Minecraft/$minecraftversion/libraries/${group}/${lib}/$file"
if [ ! -f "$base" ]; then
echo "Missing $base"
exit 1
fi
export MODLOG="$MODLOG Imported $file from $lib\n"
sed 's/\r$//' "$base" >"$target" || exit 1
done
}
(
cd Paper/Paper-Server/ || exit
lastlog=$(git log -1 --oneline)
if [[ "$lastlog" == *"Purpur-Extra mc-dev Imports"* ]]; then
git reset --hard HEAD^
fi
)
files=$(cat patches/server/* | grep "+++ b/src/main/java/net/minecraft/server/" | sort | uniq | sed 's/\+\+\+ b\/src\/main\/java\/net\/minecraft\/server\///g' | sed 's/.java//g')
nonnms=$(cat patches/server/* | grep "create mode " | grep -Po "src/main/java/net/minecraft/server/(.*?).java" | sort | uniq | sed 's/src\/main\/java\/net\/minecraft\/server\///g' | sed 's/.java//g')
for f in $files; do
containsElement "$f" "${nonnms[@]}"
if [ "$?" == "1" ]; then
if [ ! -f "$basedir/Paper/Paper-Server/src/main/java/net/minecraft/server/$f.java" ]; then
if [ ! -f "$decompiledir/$nms/$f.java" ] && [ true ]; then
echo "$(bashColor 1 31) ERROR!!! Missing NMS$(bashColor 1 34) $f $(bashColorReset)"
else
import "$f"
fi
fi
fi
done
###############################################################################################
###############################################################################################
#################### ADD TEMPORARY ADDITIONS HERE #############################################
###############################################################################################
###############################################################################################
# import Foo
########################################################
########################################################
########################################################
# LIBRARY IMPORTS
# These must always be mapped manually, no automatic stuff
#
# # group # lib # prefix # many files
#importLibrary com.mojang datafixerupper com/mojang/datafixers/util Either.java
importLibrary com.mojang brigadier com/mojang/brigadier CommandDispatcher.java
importLibrary com.mojang brigadier com/mojang/brigadier/tree LiteralCommandNode.java
importLibrary com.mojang brigadier com/mojang/brigadier/suggestion SuggestionsBuilder.java
importLibrary com.mojang brigadier com/mojang/brigadier/arguments BoolArgumentType.java
################
(
cd Paper/Paper-Server/ || exit
rm -rf nms-patches
git add src -A
echo -e "Purpur-Extra mc-dev Imports\n\n$MODLOG" | git commit src -F -
)

View File

@@ -1,45 +0,0 @@
#!/usr/bin/env bash
sourceBase=$(dirname "$SOURCE")/../
cd "${basedir:-$sourceBase}" || exit
basedir=$(pwd -P)
cd - || exit
function bashColor() {
if [ "$2" ]; then
echo -e "\e[$1;$2m"
else
echo -e "\e[$1m"
fi
}
function bashColorReset() {
echo -e "\e[m"
}
function cleanupPatches() {
cd "$1" || exit
for patch in *.patch; do
gitver=$(tail -n 2 "$patch" | grep -ve "^$" | tail -n 1)
diffs=$(git diff --staged "$patch" | grep -E "^(\+|\-)" | grep -Ev "(From [a-z0-9]{32,}|\-\-\- a|\+\+\+ b|.index|Date\: )")
testver=$(echo "$diffs" | tail -n 2 | grep -ve "^$" | tail -n 1 | grep "$gitver")
if [ "x$testver" != "x" ]; then
diffs=$(echo "$diffs" | tail -n +3)
fi
if [ "x$diffs" == "x" ]; then
git reset HEAD "$patch" >/dev/null
git checkout -- "$patch" >/dev/null
fi
done
}
function basedir() {
cd "$basedir" || exit
}
function gethead() {
(
cd "$1" || exit
git log -1 --oneline
)
}

View File

@@ -1,25 +0,0 @@
#!/usr/bin/env bash
# Copied from https://github.com/PaperMC/Paper/blob/d54ce6c17fb7a35238d6b9f734d30a4289886773/scripts/paperclip.sh
# License from Paper applies to this file
(
set -e
basedir="$(cd "$1" && pwd -P)"
workdir="$basedir/Paper/work"
mcver=$(grep <"$workdir/BuildData/info.json" minecraftVersion | cut -d '"' -f 4)
purpurjar="$basedir/Purpur-Server/target/purpur-$mcver.jar"
vanillajar="$workdir/Minecraft/$mcver/$mcver.jar"
(
cd "$workdir/Paperclip"
mvn clean package "-Dmcver=$mcver" "-Dpaperjar=$purpurjar" "-Dvanillajar=$vanillajar"
)
cp "$workdir/Paperclip/assembly/target/paperclip-${mcver}.jar" "$basedir/purpurclip.jar"
echo ""
echo ""
echo ""
echo "Build success!"
echo "Copied final jar to $(cd "$basedir" && pwd -P)/purpurclip.jar"
) || exit 1

View File

@@ -1,40 +0,0 @@
#!/usr/bin/env bash
# get base dir regardless of execution location
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
. "$(dirname "$SOURCE")/init.sh"
PS1="$"
echo "Rebuilding patch files from current fork state..."
function savePatches() {
what=$1
cd "$basedir"/"$what"/ || exit
mkdir -p "$basedir"/patches/"$2"
if [ -d ".git/rebase-apply" ]; then
# in middle of a rebase, be smarter
echo "REBASE DETECTED - PARTIAL SAVE"
last=$(cat ".git/rebase-apply/last")
next=$(cat ".git/rebase-apply/next")
declare -a files=("$basedir/patches/$2/"*.patch)
for i in $(seq -f "%04g" 1 1 "$last"); do
if [ "$i" -lt "$next" ]; then
rm "${files[$(("$i" - 1))]}"
fi
done
else
rm "$basedir"/patches/"$2"/*.patch
fi
git format-patch --no-signature --zero-commit --no-stat --full-index -N -o "$basedir/patches/$2" upstream/upstream
cd "$basedir" || exit
git add -A "$basedir"/patches/"$2"
echo " Patches saved for $what to patches/$2"
}
savePatches Purpur-API api
savePatches Purpur-Server server

View File

@@ -1,58 +0,0 @@
#!/usr/bin/env bash
# get base dir regardless of execution location
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
SOURCE="$(readlink "$SOURCE")"
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE" # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
done
. "$(dirname "$SOURCE")/init.sh"
if [[ "$1" == up* ]]; then
(
cd "$basedir/Paper/" || exit
git fetch && git reset --hard origin/master
cd ../
git add Paper
)
fi
paperVer=$(gethead Paper)
cd "$basedir/Paper/" || exit
./paper patch
cd "Paper-Server" || exit
mcVer=$(mvn -o org.apache.maven.plugins:maven-help-plugin:2.1.1:evaluate -Dexpression=minecraft_version | sed -n -e '/^\[.*\]/ !{ /^[0-9]/ { p; q } }')
basedir
. "$basedir"/scripts/importmcdev.sh
minecraftversion=$(grep <"$basedir"/Paper/work/BuildData/info.json minecraftVersion | cut -d '"' -f 4)
version=$(echo -e "Paper: $paperVer\nmc-dev:$importedmcdev")
tag="${minecraftversion}-${mcVer}-$(echo -e "$version" | shasum | awk '{print $1}')"
echo "$tag" >"$basedir"/current-paper
"$basedir"/scripts/generatesources.sh
cd Paper/ || exit
function tag() {
(
cd "$1" || exit
if [ "$2" == "1" ]; then
git tag -d "$tag" 2>/dev/null
fi
echo -e "$(date)\n\n$version" | git tag -a "$tag" -F - 2>/dev/null
)
}
echo "Tagging as $tag"
echo -e "$version"
forcetag=0
if [ "$(cat "$basedir"/current-paper)" != "$tag" ]; then
forcetag=1
fi
tag Paper-API $forcetag
tag Paper-Server $forcetag

View File

@@ -1,28 +0,0 @@
#!/usr/bin/env bash
(
set -e
PS1="$"
function changelog() {
base=$(git ls-tree HEAD "$1" | cut -d' ' -f3 | cut -f1)
cd "$1" && git log --oneline "${base}"...HEAD
}
paper=$(changelog Paper)
updated=""
logsuffix=""
if [ -n "$paper" ]; then
logsuffix="$logsuffix\n\nPaper Changes:\n$paper"
if [ -z "$updated" ]; then updated="Paper"; else updated="$updated/Paper"; fi
fi
disclaimer="Upstream has released updates that appear to apply and compile correctly"
if [ -n "$1" ]; then
disclaimer=("$@")
fi
log="${UP_LOG_PREFIX}Updated Upstream ($updated)\n\n${disclaimer[*]}${logsuffix}"
echo -e "$log" | git commit -F -
) || exit 1

20
settings.gradle.kts Normal file
View File

@@ -0,0 +1,20 @@
import java.util.Locale
val forkName = "Purpur"
val forkNameLowercase = forkName.toLowerCase(Locale.ENGLISH)
rootProject.name = forkNameLowercase
setupSubproject("$forkNameLowercase-api") {
projectDir = File("$forkName-API")
buildFileName = "../subprojects/api.gradle.kts"
}
setupSubproject("$forkNameLowercase-server") {
projectDir = File("$forkName-Server")
buildFileName = "../subprojects/server.gradle.kts"
}
inline fun setupSubproject(name: String, block: ProjectDescriptor.() -> Unit) {
include(name)
project(":$name").apply(block)
}

View File

@@ -0,0 +1,11 @@
repositories {
loadRepositories(project)
}
dependencies {
loadDependencies(project)
}
java {
withJavadocJar()
}

View File

@@ -0,0 +1,8 @@
repositories {
loadRepositories(project)
}
dependencies {
loadDependencies(project)
implementation("cat.inspiracio", "rhino-js-engine", "1.7.7.1")
}