Yatopia/buildSrc/src/main/kotlin/task/ApplyPatches.kt

103 lines
4.4 KiB
Kotlin

package task
import ensureSuccess
import forkName
import gitCmd
import org.gradle.api.Project
import org.gradle.api.Task
import reEnableGitSigning
import taskGroup
import temporarilyDisableGitSigning
import toothpick
import upstreams
import java.io.File
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
internal fun Project.createApplyPatchesTask(
receiver: Task.() -> Unit = {}
): Task = tasks.create("applyPatches") {
receiver(this)
group = taskGroup
fun checkCursed(project: Project): Boolean {
return project.properties.getOrDefault("cursed", "false").toString().toBoolean()
}
fun applyPatches(patchDir: Path, applyName: String, name: String, wasGitSigningEnabled: Boolean, projectDir: File): Boolean {
if (Files.notExists(patchDir)) return true
val patchPaths = Files.newDirectoryStream(patchDir)
.map { it.toFile() }
.filter { it.name.endsWith(".patch") }
.sorted()
.takeIf { it.isNotEmpty() } ?: return true
val patches = patchPaths.map { it.absolutePath }.toTypedArray()
logger.lifecycle(">>> Applying $applyName patches to $name")
gitCmd("am", "--abort")
//Cursed Apply Mode that makes fixing stuff a lot easier
if (checkCursed(project)) {
for (patch in patches) {
val gitCommand = arrayListOf("am", "--3way", "--ignore-whitespace",
"--rerere-autoupdate", "--whitespace=fix", "--reject", "-C0", patch)
if (gitCmd(*gitCommand.toTypedArray(), dir = projectDir, printOut = true).exitCode != 0) {
gitCmd("add", ".", dir = projectDir, printOut = true)
gitCmd("am", "--continue", dir = projectDir, printOut = true)
}
}
} else {
val gitCommand = arrayListOf("am", "--3way", "--ignore-whitespace",
"--rerere-autoupdate", "--whitespace=fix", *patches)
ensureSuccess(gitCmd(*gitCommand.toTypedArray(), dir = projectDir, printOut = true)) {
if (wasGitSigningEnabled) reEnableGitSigning(projectDir)
}
}
return false;
}
doLast {
for ((name, subproject) in toothpick.subprojects) {
val (sourceRepo, projectDir, patchesDir) = subproject
val folder = (if (patchesDir.endsWith("server")) "server" else "api")
// Reset or initialize subproject
logger.lifecycle(">>> Resetting subproject $name")
if (projectDir.exists()) {
ensureSuccess(gitCmd("fetch", "origin", dir = projectDir))
ensureSuccess(gitCmd("reset", "--hard", "origin/master", dir = projectDir))
} else {
ensureSuccess(gitCmd("clone", sourceRepo.absolutePath, projectDir.absolutePath, printOut = true))
}
logger.lifecycle(">>> Done resetting subproject $name")
val wasGitSigningEnabled = temporarilyDisableGitSigning(projectDir)
for (upstream in upstreams) {
if (((folder == "server" && upstream.serverList?.isEmpty() != false) || (folder == "api" && upstream.apiList?.isEmpty() != false)) && !upstream.useBlackList) continue
if (((folder == "server" && upstream.getRepoServerPatches()?.isEmpty() != false) || (folder == "api" && upstream.getRepoAPIPatches()?.isEmpty() != false)) && upstream.useBlackList) continue
project.gitCmd("branch", "-D", "${upstream.name}-$folder", dir = projectDir)
project.gitCmd("checkout", "-b", "${upstream.name}-$folder", dir = projectDir)
// Apply patches
val patchDir = Paths.get("${upstream.patchPath}/$folder")
if (applyPatches(patchDir, upstream.name, name, wasGitSigningEnabled, projectDir)) continue
}
// project.gitCmd("branch", "-D", "$forkName-$folder", dir = projectDir)
// project.gitCmd("checkout", "-b", "$forkName-$folder", dir = projectDir)
project.gitCmd("branch", "-D", "master", dir = projectDir)
project.gitCmd("checkout", "-b", "master", dir = projectDir)
val patchDir = patchesDir.toPath()
// Apply patches
if (applyPatches(patchDir, forkName, name, wasGitSigningEnabled, projectDir)) continue
if (wasGitSigningEnabled) reEnableGitSigning(projectDir)
logger.lifecycle(">>> Done applying patches to $name")
}
}
}