diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt index 00009043b..1e5707fb8 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt @@ -28,6 +28,7 @@ import io.papermc.paperweight.core.extension.PaperweightCoreExtension import io.papermc.paperweight.core.taskcontainers.CoreTasks import io.papermc.paperweight.core.taskcontainers.DevBundleTasks import io.papermc.paperweight.core.taskcontainers.PaperclipTasks +import io.papermc.paperweight.core.tasks.patching.ApplyFilePatches import io.papermc.paperweight.core.tasks.patchroulette.PatchRouletteTasks import io.papermc.paperweight.core.util.coreExt import io.papermc.paperweight.tasks.* @@ -197,6 +198,26 @@ abstract class PaperweightCore : Plugin { coreExt.paper.rejectsDir, layout.projectDirectory.dir("src/minecraft/java"), ) + } else if (coreExt.activeFork.isPresent && coreExt.updatingMinecraft.oldForkCommit.isPresent) { + // old commit fetching for forks through a gradle property + target.tasks.named("applyMinecraftSourcePatches").configure { + additionalRemote = coreExt.activeFork.map { fork -> + layout.cache + .resolve( + "$PAPER_PATH/old${fork.name.capitalized()}/${coreExt.updatingMinecraft.oldForkCommit.get()}/${fork.name}-server/src/minecraft/java" + ) + .absolutePathString() + } + emitRejects = false + } + + PatchRouletteTasks( + target, + coreExt.activeFork.get().name.lowercase(), // TODO: make this lazy + coreExt.minecraftVersion, + coreExt.activeFork.flatMap { it.rejectsDir }, + layout.projectDirectory.dir("src/minecraft/java"), + ) } } } diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/UpdatingMinecraftExtension.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/UpdatingMinecraftExtension.kt index d8164ffc1..87f7577a5 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/UpdatingMinecraftExtension.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/UpdatingMinecraftExtension.kt @@ -26,4 +26,5 @@ import org.gradle.api.provider.Property interface UpdatingMinecraftExtension { val oldPaperCommit: Property + val oldForkCommit: Property } diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/MinecraftPatchingTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/MinecraftPatchingTasks.kt index 8de9acb5a..dad7d6915 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/MinecraftPatchingTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/MinecraftPatchingTasks.kt @@ -30,6 +30,7 @@ import io.papermc.paperweight.core.tasks.patching.ApplyFilePatches import io.papermc.paperweight.core.tasks.patching.ApplyFilePatchesFuzzy import io.papermc.paperweight.core.tasks.patching.FixupFilePatches import io.papermc.paperweight.core.tasks.patching.RebuildFilePatches +import io.papermc.paperweight.core.util.coreExt import io.papermc.paperweight.tasks.* import io.papermc.paperweight.util.* import io.papermc.paperweight.util.constants.* @@ -167,6 +168,11 @@ class MinecraftPatchingTasks( outputDir.set(layout.cache.resolve(paperTaskOutput())) identifier.set(configName) + if (namePart == "Minecraft") { + oldCommit.convention(project.coreExt.updatingMinecraft.oldForkCommit) + oldOutputDir.set(layout.cache.resolve("$PAPER_PATH/old${configName.capitalized()}")) + } + libraryImports.set(importLibFiles.flatMap { it.outputDir }) atFile.set(mergeCollectedAts.flatMap { it.outputFile }) ats.jst.from(project.configurations.named(JST_CONFIG)) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/tasks/SetupForkMinecraftSources.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/tasks/SetupForkMinecraftSources.kt index 673a0b94d..50bd7bf90 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/tasks/SetupForkMinecraftSources.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/tasks/SetupForkMinecraftSources.kt @@ -22,12 +22,17 @@ package io.papermc.paperweight.core.tasks +import io.papermc.paperweight.PaperweightException import io.papermc.paperweight.core.util.ApplySourceATs +import io.papermc.paperweight.core.util.coreExt import io.papermc.paperweight.tasks.* import io.papermc.paperweight.util.* import io.papermc.paperweight.util.constants.paperTaskOutput +import java.util.concurrent.TimeUnit import kotlin.io.path.* import org.eclipse.jgit.api.Git +import org.eclipse.jgit.api.ResetCommand +import org.eclipse.jgit.transport.URIish import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.Property @@ -49,6 +54,10 @@ abstract class SetupForkMinecraftSources : JavaLauncherTask() { @get:OutputDirectory abstract val outputDir: DirectoryProperty + @get:OutputDirectory + @get:Optional + abstract val oldOutputDir: DirectoryProperty + @get:Internal abstract val atWorkingDir: DirectoryProperty @@ -66,9 +75,17 @@ abstract class SetupForkMinecraftSources : JavaLauncherTask() { @get:Input abstract val identifier: Property + @get:Internal + abstract val forkName: Property + + @get:Input + @get:Optional + abstract val oldCommit: Property + override fun init() { super.init() atWorkingDir.set(layout.cache.resolve(paperTaskOutput(name = "${name}_atWorkingDir"))) + forkName.convention(project.coreExt.activeFork.map { it.name.capitalized() }) } @TaskAction @@ -78,6 +95,10 @@ abstract class SetupForkMinecraftSources : JavaLauncherTask() { val git = Git.open(outputDir.path.toFile()) + if (oldCommit.isPresent) { + setupOld() + } + if (atFile.isPresent && atFile.path.readText().isNotBlank()) { println("Applying access transformers...") ats.run( @@ -104,4 +125,82 @@ abstract class SetupForkMinecraftSources : JavaLauncherTask() { git.close() } + + private fun setupOld() { + val name = forkName.get() + logger.lifecycle("Setting up $name commit ${oldCommit.get()} to use as base for 3-way apply...") + + val rootProjectDir = layout.projectDirectory.dir("../").path + val oldDir = oldOutputDir.get().path.resolve(oldCommit.get()) + val oldLog = oldOutputDir.get().path.resolve("${oldCommit.get()}.log") + + val oldGit: Git + if (oldDir.exists()) { + oldGit = Git.open(oldDir.toFile()) + } else { + oldDir.createParentDirectories() + oldGit = Git.init() + .setDirectory(oldDir.toFile()) + .setInitialBranch("main") + .call() + oldGit.remoteRemove().setRemoteName("origin").call() + oldGit.remoteAdd().setName("origin").setUri(URIish(rootProjectDir.absolutePathString())).call() + } + + val upstream = Git.open(rootProjectDir.toFile()) + val upstreamConfig = upstream.repository.config + val upstreamReachableSHA1 = upstreamConfig.getString("uploadpack", null, "allowreachablesha1inwant") + val upstreamConfigContainsUploadPack = upstreamConfig.sections.contains("uploadpack") + try { + // Temporarily allow fetching reachable sha1 refs from the "upstream" repository. + upstreamConfig.setBoolean("uploadpack", null, "allowreachablesha1inwant", true) + upstreamConfig.save() + oldGit.fetch().setDepth(1).setRemote("origin").setRefSpecs(oldCommit.get()).call() + oldGit.reset().setMode(ResetCommand.ResetType.HARD).setRef(oldCommit.get()).call() + } finally { + if (upstreamReachableSHA1 == null) { + if (upstreamConfigContainsUploadPack) { + upstreamConfig.unset("uploadpack", null, "allowreachablesha1inwant") + } else { + upstreamConfig.unsetSection("uploadpack", null) + } + } else { + upstreamConfig.setString("uploadpack", null, "allowreachablesha1inwant", upstreamReachableSHA1) + } + upstreamConfig.save() + upstream.close() + } + + oldGit.close() + + val isWindows = System.getProperty("os.name").lowercase().contains("win") + oldLog.outputStream().use { logOut -> + val args = arrayOf( + "applyAllPatches", + "--console", + "plain", + "--stacktrace", + "-Dpaperweight.debug=true" + ) + val command = if (isWindows) { + listOf("cmd.exe", "/C", "gradlew.bat " + args.joinToString(" ")) + } else { + listOf("./gradlew", *args) + } + val processBuilder = ProcessBuilder(command) + processBuilder.directory(oldDir) + val process = processBuilder.start() + + val outFuture = redirect(process.inputStream, logOut) + val errFuture = redirect(process.errorStream, logOut) + + val exit = process.waitFor() + outFuture.get(500L, TimeUnit.MILLISECONDS) + errFuture.get(500L, TimeUnit.MILLISECONDS) + + if (exit != 0) { + throw PaperweightException("Failed to apply old $name, see log at $oldLog") + } + } + } } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt index fc8c114a3..44c03d027 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt @@ -65,7 +65,7 @@ const val PLUGIN_REMAPPER_REPO_NAME = "paperweightPluginRemapperRepository" const val MACHE_REPO_NAME = "paperweightMacheRepository" const val CACHE_PATH = "caches" -private const val PAPER_PATH = "paperweight" +const val PAPER_PATH = "paperweight" const val LOCK_DIR = "$PAPER_PATH/lock" const val USERDEV_SETUP_LOCK = "$LOCK_DIR/userdev/setup.lock"