Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rework AT rebasing to use jgit #270

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import io.papermc.paperweight.core.util.coreExt
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.tasks.mache.DecompileJar
import io.papermc.paperweight.tasks.mache.RemapJar
import io.papermc.paperweight.tasks.softspoon.ProcessNewSourceAT
import io.papermc.paperweight.util.*
import io.papermc.paperweight.util.constants.*
import io.papermc.paperweight.util.data.mache.*
Expand Down Expand Up @@ -124,6 +125,16 @@ class CoreTasks(
outputDir.set(layout.cache.resolve(BASE_PROJECT).resolve("resources"))
}

val processNewSourceAT by tasks.registering(ProcessNewSourceAT::class) {
description = "Processes new source ATs"

base.set(layout.cache.resolve(BASE_PROJECT).resolve("sources"))
input.set(layout.projectDirectory.dir("src/vanilla/java"))
atFile.set(project.coreExt.paper.additionalAts.fileExists(project))
ats.jstClasspath.from(project.configurations.named(MACHE_MINECRAFT_CONFIG))
ats.jst.from(project.configurations.named(JST_CONFIG))
}

fun afterEvaluate() {
setupPatchingTasks()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,6 @@ class MinecraftPatchingTasks(
input.set(outputSrc)
patches.set(sourcePatchDir)
gitFilePatches.set([email protected])

ats.jstClasspath.from(project.configurations.named(MACHE_MINECRAFT_CONFIG))
ats.jst.from(project.configurations.named(JST_CONFIG))
atFile.set(additionalAts.fileExists(project))
atFileOut.set(additionalAts.fileExists(project))
}

val rebuildResourcePatches = tasks.register<RebuildFilePatches>(rebuildResourcePatchesName) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import codechicken.diffpatch.util.archiver.ArchiveFormat
import io.papermc.paperweight.core.util.ApplySourceATs
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import io.papermc.paperweight.util.constants.*
import java.nio.file.Path
import java.util.function.Predicate
import kotlin.io.path.*
Expand Down Expand Up @@ -81,7 +82,7 @@ abstract class SetupMinecraftSources : JavaLauncherTask() {
val git: Git
if (outputPath.resolve(".git/HEAD").isRegularFile()) {
git = Git.open(outputPath.toFile())
git.reset().setRef("ROOT").setMode(ResetCommand.ResetType.HARD).call()
git.reset().setRef(MACHE_TAG_ROOT).setMode(ResetCommand.ResetType.HARD).call()
} else {
outputPath.createDirectories()

Expand All @@ -90,10 +91,10 @@ abstract class SetupMinecraftSources : JavaLauncherTask() {
.setInitialBranch("main")
.call()

val rootIdent = PersonIdent("ROOT", "[email protected]")
git.commit().setMessage("ROOT").setAllowEmpty(true).setAuthor(rootIdent).setSign(false).call()
git.tagDelete().setTags("ROOT").call()
git.tag().setName("ROOT").setTagger(rootIdent).setSigned(false).call()
val rootIdent = PersonIdent(MACHE_TAG_ROOT, "[email protected]")
git.commit().setMessage(MACHE_TAG_ROOT).setAllowEmpty(true).setAuthor(rootIdent).setSign(false).call()
git.tagDelete().setTags(MACHE_TAG_ROOT).call()
git.tag().setName(MACHE_TAG_ROOT).setTagger(rootIdent).setSigned(false).call()
}

if (macheOld.isPresent) {
Expand Down Expand Up @@ -130,7 +131,7 @@ abstract class SetupMinecraftSources : JavaLauncherTask() {
println("Setup git repo...")
if (!macheOld.isPresent) {
// skip this if we are diffing against old, since it would be a commit without mache patches
commitAndTag(git, "Vanilla")
commitAndTag(git, MACHE_TAG_VANILLA)
}

if (!mache.isEmpty) {
Expand All @@ -147,7 +148,7 @@ abstract class SetupMinecraftSources : JavaLauncherTask() {
.build()
.operate()

commitAndTag(git, "Mache")
commitAndTag(git, MACHE_TAG_PATCHES)

if (result.exit != 0) {
throw Exception("Failed to apply ${result.summary.failedMatches} mache patches")
Expand All @@ -165,13 +166,13 @@ abstract class SetupMinecraftSources : JavaLauncherTask() {
atFile.path,
temporaryDir.toPath(),
)
commitAndTag(git, "ATs", "paper ATs")
commitAndTag(git, MACHE_TAG_ATS, "paper ATs")
}

if (libraryImports.isPresent) {
libraryImports.path.copyRecursivelyTo(outputPath)

commitAndTag(git, "Imports", "paper Imports")
commitAndTag(git, MACHE_TAG_IMPORTS, "paper Imports")
}

git.close()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ package io.papermc.paperweight.core.tasks.patching
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import kotlin.io.path.createDirectories
import io.papermc.paperweight.util.constants.*
import javax.inject.Inject
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
Expand Down Expand Up @@ -84,7 +86,7 @@ abstract class ApplyFeaturePatches : ControllableOutputTask() {
if (git("checkout", "main").runSilently(silenceErr = true) != 0) {
git("checkout", "-b", "main").runSilently(silenceErr = true)
}
git("reset", "--hard", "file").executeSilently(silenceErr = true)
git("reset", "--hard", MACHE_TAG_FILE).executeSilently(silenceErr = true)
git("gc").runSilently(silenceErr = true)

applyGitPatches(git, "server repo", repoPath, patches.path, printOutput.get(), verbose.get())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import codechicken.diffpatch.util.LoggingOutputStream
import codechicken.diffpatch.util.PatchMode
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import io.papermc.paperweight.util.constants.*
import java.io.PrintStream
import java.nio.file.Path
import java.time.Instant
Expand Down Expand Up @@ -185,8 +186,8 @@ abstract class ApplyFilePatches : BaseTask() {
.setAllowEmpty(true)
.setSign(false)
.call()
git.tagDelete().setTags("file").call()
git.tag().setName("file").setTagger(ident).setSigned(false).call()
git.tagDelete().setTags(MACHE_TAG_FILE).call()
git.tag().setName(MACHE_TAG_FILE).setTagger(ident).setSigned(false).call()
git.close()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ package io.papermc.paperweight.core.tasks.patching

import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import io.papermc.paperweight.util.constants.*
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
Expand All @@ -44,7 +45,7 @@ abstract class FixupFilePatches : BaseTask() {
fun run() {
val git = Git(repo)
git("add", ".").executeOut()
git("commit", "--fixup", "file").executeOut()
git("commit", "--fixup", MACHE_TAG_FILE).executeOut()
git("-c", "sequence.editor=:", "rebase", "-i", "--autosquash", upstream.get()).executeOut()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
package io.papermc.paperweight.tasks.softspoon

import io.papermc.paperweight.PaperweightException
import io.papermc.paperweight.core.util.ApplySourceATs
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import io.papermc.paperweight.util.constants.*
import java.nio.file.Path
import kotlin.io.path.*
import org.cadixdev.at.AccessTransformSet
import org.cadixdev.at.io.AccessTransformFormats
import org.cadixdev.bombe.type.signature.MethodSignature
import org.eclipse.jgit.api.RebaseCommand
import org.eclipse.jgit.lib.RebaseTodoLine
import org.eclipse.jgit.merge.MergeStrategy
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Nested
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.UntrackedTask
import org.gradle.kotlin.dsl.*

@UntrackedTask(because = "Always process when requested")
abstract class ProcessNewSourceAT : JavaLauncherTask() {

@get:InputDirectory
abstract val input: DirectoryProperty

@get:InputDirectory
abstract val base: DirectoryProperty

@get:Optional
@get:InputFile
abstract val atFile: RegularFileProperty

@get:Nested
val ats: ApplySourceATs = objects.newInstance()

@TaskAction
fun run() {
val inputDir = input.convertToPath()
val baseDir = base.convertToPath()

// find ATs, cleanup comment, apply to base
val newATs = handleAts(baseDir, inputDir, atFile)
println("ran handleAts, base should be patched")
System.`in`.read()

// save work and jump to AT commit
val git = Git(inputDir)
git("stash", "push").executeSilently(silenceErr = true)
git("checkout", MACHE_TAG_ATS).executeSilently(silenceErr = true)

// apply new ATs to source
newATs.forEach { (path, ats) ->
val source = inputDir.resolve(path)
// TODO for some reason this does nothing
applyNewATs(source, ats)
}
println("applied new ATs to source")
System.`in`.read()

// commit new ATs
git("add", ".").executeSilently(silenceErr = true)
git("commit", "--amend", "--no-edit").executeSilently(silenceErr = true)

// TODO fix the tag

// clean up tree: drop the old file commit and rebase the new file commit onto it
git("switch", "-").executeSilently(silenceErr = true)
println("switched back to main")
System.`in`.read()
org.eclipse.jgit.api.Git.open(inputDir.toFile()).rebase()
.setUpstream(MACHE_TAG_ATS)
.setStrategy(MergeStrategy.THEIRS)
.runInteractively(object : RebaseCommand.InteractiveHandler {
override fun prepareSteps(steps: MutableList<RebaseTodoLine>) {
// drop the first commit
steps.removeAt(0)
}

override fun modifyCommitMessage(message: String): String {
return message
}
})
.call()

println("finished rebase")
System.`in`.read()

git("stash", "pop").executeSilently(silenceErr = true)
}

private fun handleAts(
baseDir: Path,
inputDir: Path,
atFile: RegularFileProperty
): MutableList<Pair<String, AccessTransformSet>> {
val oldAts = AccessTransformFormats.FML.read(atFile.path)

// handle AT
val newATs = mutableListOf<Pair<String, AccessTransformSet>>()
baseDir.walk()
.map { it.relativeTo(baseDir).invariantSeparatorsPathString }
.filter { it.endsWith(".java") }
.forEach {
val ats = AccessTransformSet.create()
val source = inputDir.resolve(it)
val decomp = baseDir.resolve(it)
val className = it.replace(".java", "")
if (findATInSource(source, ats, className)) {
applyNewATs(decomp, ats)
newATs.add(it to ats)
}
oldAts.merge(ats)
}

AccessTransformFormats.FML.writeLF(
atFile.path,
oldAts,
"# This file is auto generated, any changes may be overridden!\n# See CONTRIBUTING.md on how to add access transformers.\n"
)

return newATs
}

private fun applyNewATs(decomp: Path, newAts: AccessTransformSet) {
if (newAts.classes.isEmpty()) {
println("new ats empty?!") //TODO remove
return
}
println("apply new ats to $decomp, $newAts") //TODO remove

val at = temporaryDir.toPath().resolve("ats.cfg").createParentDirectories()
AccessTransformFormats.FML.writeLF(at, newAts)
ats.run(
launcher.get(),
decomp,
decomp,
at,
temporaryDir.toPath().resolve("jst_work").cleanDir(),
singleFile = true,
)
}

private fun findATInSource(source: Path, newAts: AccessTransformSet, className: String): Boolean {
val sourceLines = source.readLines()
var foundNew = false
val fixedLines = ArrayList<String>(sourceLines.size)
sourceLines.forEach { line ->
if (!line.contains("// Paper-AT: ")) {
fixedLines.add(line)
return@forEach
}

foundNew = true

val split = line.split("// Paper-AT: ")
val at = split[1]
try {
val atClass = newAts.getOrCreateClass(className)
val parts = at.split(" ")
val accessTransform = atFromString(parts[0])
val name = parts[1]
val index = name.indexOf('(')
if (index == -1) {
atClass.mergeField(name, accessTransform)
} else {
atClass.mergeMethod(MethodSignature.of(name.substring(0, index), name.substring(index)), accessTransform)
}
logger.lifecycle("Found new AT in $className: $at -> $accessTransform")
} catch (ex: Exception) {
throw PaperweightException("Found invalid AT '$at' in class $className")
}

fixedLines.add(split[0].trimEnd())
}

if (foundNew) {
source.writeText(fixedLines.joinToString("\n", postfix = "\n"), Charsets.UTF_8)
}

return foundNew
}
}
Loading
Loading