Skip to content

Commit

Permalink
add a whole integration test setup, cleanup mache extraction
Browse files Browse the repository at this point in the history
  • Loading branch information
MiniDigger committed Dec 30, 2023
1 parent 461b228 commit 74b0cf8
Show file tree
Hide file tree
Showing 32 changed files with 413 additions and 94 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ class PaperweightCore : Plugin<Project> {

val ext = target.extensions.create(PAPERWEIGHT_EXTENSION, PaperweightCoreExtension::class, target)

target.gradle.sharedServices.registerIfAbsent(DOWNLOAD_SERVICE_NAME, DownloadService::class) {}
target.gradle.sharedServices.registerIfAbsent(DOWNLOAD_SERVICE_NAME, DownloadService::class) {
parameters.projectPath.set(target.projectDir)
}

target.tasks.register<Delete>("cleanCache") {
group = "paper"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ open class PaperweightCoreExtension(project: Project, objects: ObjectFactory, la
val workDir: DirectoryProperty = objects.dirWithDefault(layout, "work")

val minecraftVersion: Property<String> = objects.property()
val minecraftManifestUrl: Property<String> = objects.property<String>().convention(MC_MANIFEST_URL)
val serverProject: Property<Project> = objects.property()

val mainClass: Property<String> = objects.property<String>().convention("org.bukkit.craftbukkit.Main")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ open class InitialTasks(
) {

val downloadMcManifest by tasks.registering<DownloadTask> {
url.set(MC_MANIFEST_URL)
url.set(project.ext.minecraftManifestUrl)
outputFile.set(cache.resolve(MC_MANIFEST))

doNotTrackState("The Minecraft manifest is a changing resource")
Expand Down Expand Up @@ -94,5 +94,6 @@ open class InitialTasks(
serverLibrariesList.set(cache.resolve(SERVER_LIBRARIES_LIST))
serverVersionsList.set(cache.resolve(SERVER_VERSIONS_LIST))
serverLibraryJars.set(cache.resolve(MINECRAFT_JARS_PATH))
serverJar.set(cache.resolve(SERVER_JAR))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,16 @@ import io.papermc.paperweight.tasks.patchremapv2.GeneratePatchRemapMappings
import io.papermc.paperweight.tasks.patchremapv2.RemapCBPatches
import io.papermc.paperweight.tasks.softspoon.ApplyPatches
import io.papermc.paperweight.tasks.softspoon.ApplyPatchesFuzzy
import io.papermc.paperweight.tasks.softspoon.ApplySourceAT
import io.papermc.paperweight.tasks.softspoon.RebuildPatches
import io.papermc.paperweight.util.*
import io.papermc.paperweight.util.constants.*
import io.papermc.paperweight.util.data.*
import io.papermc.paperweight.util.data.mache.*
import java.nio.file.Files
import java.nio.file.Path
import kotlin.io.path.*
import org.gradle.api.Project
import org.gradle.api.tasks.TaskContainer
import org.gradle.kotlin.dsl.*
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.runBlocking
import org.gradle.api.Task
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginExtension
Expand All @@ -43,7 +40,7 @@ open class SoftSpoonTasks(

val macheRemapJar by tasks.registering(RemapJar::class) {
group = "mache"
serverJar.set(layout.cache.resolve(SERVER_JAR_PATH))
serverJar.set(allTasks.extractFromBundler.flatMap { it.serverJar })
serverMappings.set(allTasks.downloadMappings.flatMap { it.outputFile })

codebookClasspath.from(macheCodebook)
Expand Down Expand Up @@ -81,12 +78,12 @@ open class SoftSpoonTasks(
description = "Setup vanilla source dir (apllying mache patches and paper ATs)."

mache.from(project.configurations.named(MACHE_CONFIG))
patches.set(layout.cache.resolve(PATCHES_FOLDER))
patches.set(layout.cache.resolve(PATCHES_FOLDER)) // TODO extract mache
ats.set(mergeCollectedAts.flatMap { it.outputFile })
minecraftClasspath.from(macheMinecraft)

inputFile.set(macheDecompileJar.flatMap { it.outputJar })
predicate.set { Files.isRegularFile(it) && it.toString().endsWith(".java")}
predicate.set { Files.isRegularFile(it) && it.toString().endsWith(".java") }
outputDir.set(layout.cache.resolve(BASE_PROJECT).resolve("sources"))
}

Expand All @@ -95,7 +92,7 @@ open class SoftSpoonTasks(
description = "Setup vanilla resources dir"

inputFile.set(macheDecompileJar.flatMap { it.outputJar })
predicate.set { Files.isRegularFile(it) && !it.toString().endsWith(".java")}
predicate.set { Files.isRegularFile(it) && !it.toString().endsWith(".java") }
outputDir.set(layout.cache.resolve(BASE_PROJECT).resolve("resources"))
}

Expand Down Expand Up @@ -191,65 +188,11 @@ open class SoftSpoonTasks(
}

fun afterEvaluate() {
val download = project.download.get()

// todo all this should be a dependency resolution hook like
// https://github.com/PaperMC/paperweight/blob/88edb5ce16a794cd72d33c0a750fd9f334e5677f/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt#L237-L246
// https://discord.com/channels/289587909051416579/776169605760286730/1155170101599940698
// load mache
mache = this.project.configurations.named(MACHE_CONFIG).get().singleFile.toPath().openZip().use { zip ->
return@use gson.fromJson<MacheMeta>(zip.getPath("/mache.json").readLines().joinToString("\n"))
}
println("Loading mache ${mache.version}")

// download manifests
val mcManifestFile = project.layout.cache.resolve(MC_MANIFEST)
download.download(MC_MANIFEST_URL, mcManifestFile)
val mcManifest = gson.fromJson<MinecraftManifest>(mcManifestFile)

val mcVersionManifestFile = project.layout.cache.resolve(VERSION_JSON)
val mcVersion = mcManifest.versions.firstOrNull { it.id == mache.version }
?: throw RuntimeException("Unknown Minecraft version ${mache.version}")
download.download(mcVersion.url, mcVersionManifestFile, Hash(mcVersion.sha1, HashingAlgorithm.SHA1))
val mcVersionManifest = gson.fromJson<MinecraftVersionManifest>(mcVersionManifestFile)

val bundleJar = project.layout.cache.resolve(BUNDLE_JAR_PATH)
val serverJar = project.layout.cache.resolve(SERVER_JAR_PATH)
// download bundle and mappings
runBlocking {
awaitAll(
download.downloadAsync(
mcVersionManifest.downloads["server"]!!.url,
bundleJar,
Hash(mcVersionManifest.downloads["server"]!!.sha1, HashingAlgorithm.SHA1),
),
download.downloadAsync(
mcVersionManifest.downloads["server_mappings"]!!.url,
project.layout.cache.resolve(SERVER_MAPPINGS),
Hash(mcVersionManifest.downloads["server_mappings"]!!.sha1, HashingAlgorithm.SHA1),
),
)
}

// extract bundle
val libs = bundleJar.openZip().use { zip ->
val versions = zip.getPath("META-INF", "versions.list").readLines()
.map { it.split('\t') }
.associate { it[1] to it[2] }
val serverJarPath = zip.getPath("META-INF", "versions", versions[mache.version])
serverJarPath.copyTo(serverJar, true)

val librariesList = zip.getPath("META-INF", "libraries.list")

return@use librariesList.useLines { lines ->
return@useLines lines.map { line ->
val parts = line.split(whitespace)
if (parts.size != 3) {
throw Exception("libraries.list file is invalid")
}
return@map parts[1]
}.toList()
}
}
println("Loaded mache ${mache.version}")

// setup repos
this.project.repositories {
Expand All @@ -270,16 +213,37 @@ open class SoftSpoonTasks(
mavenCentral()
}

this.project.dependencies {
// setup mc deps
libs.forEach {
"macheMinecraft"(it)
"macheMinecraftExtended"(it)
}
val libsFile = project.layout.cache.resolve(SERVER_LIBRARIES_TXT)

"macheMinecraftExtended"(project.files(project.layout.cache.resolve(FINAL_REMAPPED_CODEBOOK_JAR)))
// setup mc deps
macheMinecraft {
withDependencies {
project.dependencies {
val libs = libsFile.convertToPathOrNull()
if (libs != null && libs.exists()) {
libs.forEachLine { line ->
add(create(line))
}
}
}
}
}
macheMinecraftExtended {
withDependencies {
project.dependencies {
val libs = libsFile.convertToPathOrNull()
if (libs != null && libs.exists()) {
libs.forEachLine { line ->
add(create(line))
}
}
add(create(project.files(project.layout.cache.resolve(FINAL_REMAPPED_CODEBOOK_JAR))))
}
}
}

// setup mache deps
// setup mache deps
this.project.dependencies {
mache.dependencies.codebook.forEach {
"macheCodebook"("${it.group}:${it.name}:${it.version}")
}
Expand All @@ -294,10 +258,10 @@ open class SoftSpoonTasks(
}
}

this.project.ext.serverProject.get().setupServerProject(mache, libs);
this.project.ext.serverProject.get().setupServerProject(libsFile);
}

private fun Project.setupServerProject(mache: MacheMeta, libs: List<String>) {
private fun Project.setupServerProject(libsFile: Path) {
if (!projectDir.exists()) {
return
}
Expand All @@ -307,8 +271,11 @@ open class SoftSpoonTasks(
withDependencies {
dependencies {
// setup mc deps
libs.forEach {
"macheMinecraft"(it)
val libs = libsFile.convertToPathOrNull()
if (libs != null && libs.exists()) {
libs.forEachLine { line ->
add(create(line))
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package io.papermc.paperweight

import io.papermc.paperweight.util.*
import java.net.URL
import java.nio.file.Path
import java.nio.file.Paths
import kotlin.io.path.*
import kotlin.test.Test
import kotlin.test.assertEquals
import org.gradle.testkit.runner.TaskOutcome
import org.junit.jupiter.api.io.CleanupMode
import org.junit.jupiter.api.io.TempDir

class FunctionalTest {

@Test
fun `test simple test project`(@TempDir(cleanup = CleanupMode.ON_SUCCESS) tempDir: Path) {
setupMache("fake_mache", tempDir.resolve("mache.zip"))
setupMojang("fake_mojang", tempDir.resolve("fake_mojang"))

val result = tempDir.copyProject("functional_test")
.gradleRunner()
.withArguments("applyPatches", "dependencies", ":test-server:dependencies", "--stacktrace" , "--scan")
.withDebug(true)
.build()

assertEquals(result.task(":applyPatches")?.outcome, TaskOutcome.SUCCESS)
}

fun setupMache(macheName: String, target: Path) {
val macheDir = Paths.get("src/test/resources/$macheName")
zip(macheDir, target);
}

fun setupMojang(mojangName: String, target: Path) {
val mojangDir = Paths.get("src/test/resources/$mojangName")
mojangDir.copyRecursivelyTo(target)

val serverFolder = target.resolve("server")
ProcessBuilder()
.directory(serverFolder)
.command("javac", serverFolder.resolve("Test.java").toString())
.redirectErrorStream(true)
.start()
.waitFor()

ProcessBuilder()
.directory(serverFolder)
.command("jar", "-cf", "server.jar", "Test.class", "test.json")
.redirectErrorStream(true)
.start()
.waitFor()

val versionFolder = target.resolve("bundle/META-INF/versions/fake/")
versionFolder.createDirectories()
serverFolder.resolve("server.jar").copyTo(versionFolder.resolve("server.jar"))

val oshiFolder = target.resolve("bundle/META-INF/libraries/com/github/oshi/oshi-core/6.4.5/")
oshiFolder.createDirectories()
oshiFolder.resolve("oshi-core-6.4.5.jar").writeBytes(URL("https://libraries.minecraft.net/com/github/oshi/oshi-core/6.4.5/oshi-core-6.4.5.jar").readBytes())
zip(target.resolve("bundle"), target.resolve("bundle.jar"))
}
}
27 changes: 27 additions & 0 deletions paperweight-core/src/test/kotlin/io/papermc/paperweight/util.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package io.papermc.paperweight

import java.nio.file.Path
import java.nio.file.Paths
import kotlin.io.path.*
import org.gradle.testkit.runner.GradleRunner

fun Path.copyProject(resourcesProjectName: String): ProjectFiles {
Paths.get("src/test/resources/$resourcesProjectName")
.copyToRecursively(this, followLinks = false)
return ProjectFiles(this)
}

class ProjectFiles(val projectDir: Path) {
val gradleProperties: Path = resolve("gradle.properties")
val buildGradle: Path = resolve("build.gradle")
val buildGradleKts: Path = resolve("build.gradle.kts")
val settingsGradle: Path = resolve("settings.gradle")
val settingsGradleKts: Path = resolve("settings.gradle.kts")

fun resolve(path: String): Path = projectDir.resolve(path)

fun gradleRunner(): GradleRunner = GradleRunner.create()
.forwardOutput()
.withPluginClasspath()
.withProjectDir(projectDir.toFile())
}
Loading

0 comments on commit 74b0cf8

Please sign in to comment.