Compare commits

...

12 commits

Author SHA1 Message Date
Jake Potrebic
87220867d9
fix issues relating to some root structure changes 2024-09-01 20:22:13 -07:00
Jake Potrebic
59e26185ee
some more work on improving repo merging 2024-09-01 18:20:16 -07:00
Jake Potrebic
200f6efc46
Fully remap all of craftbukkit and spigot patches 2024-09-01 18:20:16 -07:00
Jake Potrebic
d25bd933cb
rebuild per-file against correct bases 2024-09-01 18:20:16 -07:00
Jake Potrebic
98a2838898
handle patching spigot patches 2024-09-01 18:20:16 -07:00
Jake Potrebic
1753f64ad5
More closely line up with the new repo layout 2024-09-01 18:20:16 -07:00
Jake Potrebic
82bb386fcc
update for better handling of spigot + paper server patches 2024-09-01 18:20:16 -07:00
Jake Potrebic
c882e16c63
more work on history stuff 2024-09-01 18:20:15 -07:00
Jake Potrebic
ff948e2f1e
fixes and rebased 2024-09-01 18:19:50 -07:00
Jake Potrebic
a9b2b7ae19
bump to 2.0.0-SNAPSHOT 2024-09-01 18:19:30 -07:00
Jake Potrebic
1e0f77162a
fix a few issues, should work on fresh clones again
also bumb to 1.4.0 for local conflicts
2024-09-01 18:19:15 -07:00
Jake Potrebic
d1b49548ac
Add logic for merging repositories 2024-09-01 18:19:14 -07:00
28 changed files with 1662 additions and 27 deletions

View file

@ -1,5 +1,5 @@
group = io.papermc.paperweight
version = 1.7.3-SNAPSHOT
version = 2.0.0-MERGE-SNAPSHOT
org.gradle.caching = true
org.gradle.parallel = true

View file

@ -39,6 +39,9 @@ open class PaperweightCoreExtension(project: Project, objects: ObjectFactory, la
@Suppress("MemberVisibilityCanBePrivate")
val workDir: DirectoryProperty = objects.dirWithDefault(layout, "work")
@Suppress("unused")
val superDir: DirectoryProperty = objects.dirFrom(workDir, "SuperPaper")
val minecraftVersion: Property<String> = objects.property()
val serverProject: Property<Project> = objects.property()

View file

@ -26,12 +26,23 @@ import io.papermc.paperweight.DownloadService
import io.papermc.paperweight.core.ext
import io.papermc.paperweight.core.extension.PaperweightCoreExtension
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.tasks.mm.*
import io.papermc.paperweight.tasks.mm.filterrepo.FinalizePaperHistory
import io.papermc.paperweight.tasks.mm.filterrepo.MergeGitRepos
import io.papermc.paperweight.tasks.mm.filterrepo.MoveCommits
import io.papermc.paperweight.tasks.mm.filterrepo.RewriteCommits
import io.papermc.paperweight.util.*
import io.papermc.paperweight.util.constants.*
import java.nio.file.Path
import kotlin.io.path.*
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.Directory
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFile
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.TaskContainer
import org.gradle.kotlin.dsl.*
@ -180,4 +191,226 @@ open class AllTasks(
inputMappings.set(patchReobfMappings.flatMap { it.outputMappings })
outputMappings.set(cache.resolve(RELOCATED_PATCHED_REOBF_MOJANG_SPIGOT_MAPPINGS))
}
/*
API Tasks
cloneRepos -> create fresh clones from the work/ dirs
applySpigotApiPatches -> apply patches from the spigot repo on top of the bukkit API
rewriteBukkitSpigotHistory -> rewrites all api commits to have a set author
applyPaperApiPatches -> applies all paper API patches
finalizeApiHistory -> move all api commits to a subdirectory
Server Tasks
cloneRepos -> create fresh clones from the work/ dirs
importMcDevFiles -> import mc dev files from spigot and brig
applyUnmappedCraftBukkitPatches -> Apply CB per-file patches
setupCraftBukkit -> moves patches and re-creates library diff as patches
remapCraftBukkit -> remaps CB source and nms
spigotDecompilerMojmapSetup -> sets up a directory for vanilla source
decompiled with spigot's decompiler mapped to mojang+yarn for diffing
against for per-file patches
spigotDecompilerMojmapImportMcDev -> imports file used by cb and spigot
spigotDecompilerMojmapRemap -> remaps vanilla source decompiled with
spigot's decompiler to mojang+yarn
rebuildCraftBukkitPerFilePatches -> rebuilds per-file patches for CB
remapSpigot ->
applies spigot patches 1 by one, remapping after each and then
rebuilding per-file patches
rewriteCraftBukkitSpigotHistory -> rewrite commits to update the author
importPaperMcDevFiles -> import mc dev files needed for paper patches
applyPaperServerPatches ->
Applies paper patches 1 at a time, rebuilding per-file patches after each apply
Then amends the created commit to the changes to per-file are part of the commit
finalizeServerHistory -> move all server commits to a subdirectory
*/
val cloneBranchName = "for-clone"
val cloneRepos by tasks.registering<CloneRepos> {
dependsOn(initSubmodules)
cloneBranch.set(cloneBranchName)
craftBukkitDir.set(extension.craftBukkit.craftBukkitDir)
bukkitDir.set(extension.craftBukkit.bukkitDir)
paperClone.set(objects.dirFrom(extension.workDir, "PaperClone"))
}
private val libraryFilesToImportForCb = listOf(
"com/mojang/brigadier/CommandDispatcher.java",
"com/mojang/brigadier/tree/CommandNode.java"
)
val importMcDevFiles by tasks.registering<ImportMcDevFiles> {
mustRunAfter(spigotDecompilerMojmapRemap)
configureForCb(cloneRepos.flatMap { it.craftBukkitClone }, extension.spigot.craftBukkitPatchDir)
}
val applyUnmappedCraftBukkitPatches by tasks.registering<ApplyPerFilePatches> {
targetDir.set(importMcDevFiles.flatMap { it.outputDir })
perFilePatches.set(targetDir.dir("nms-patches"))
}
val setupCraftBukkit by tasks.registering<SetupCraftBukkit> {
targetDir.set(applyUnmappedCraftBukkitPatches.flatMap { it.outputDir })
perFilePatches.set(targetDir.dir("nms-patches"))
recreateAsPatches.set(libraryFilesToImportForCb.map { "src/main/java/$it" })
sourceForPatchRecreation.set(spigotDecompileJar.flatMap { it.decompiledSource })
newPerFilePatchesDirectory.set(targetDir.dir(SOURCE_PATCHES))
}
@Suppress("DuplicatedCode")
val remapCraftBukkit by tasks.registering<RemapCraftBukkit> {
inputSources.set(setupCraftBukkit.flatMap { it.outputDir })
mappings.set(cleanupSourceMappings.flatMap { it.outputMappings }) // spigot-mojang+yarn
vanillaJar.set(extractFromBundler.flatMap { it.serverJar })
mojangMappedVanillaJar.set(fixJar.flatMap { it.outputJar })
vanillaRemappedSpigotJar.set(filterSpigotExcludes.flatMap { it.outputZip })
spigotDeps.from(downloadSpigotDependencies.map { it.outputDir.asFileTree })
additionalAts.set(mergePaperAts.flatMap { it.outputFile })
bukkitApiDir.set(extension.craftBukkit.bukkitDir)
}
val spigotDecompilerMojmapSetup by tasks.registering<SpigotDecompilerMojMapSetup> {
group = "spigot-decompiler-mojmap"
this.dir.set(layout.cacheDir(SPIGOT_DECOMPILER_MOJMAP_SRC_WRK))
}
abstract class SpigotDecompilerMojMapSetup : BaseTask() {
@get:OutputDirectory
abstract val dir: DirectoryProperty
@TaskAction
fun run() {
dir.path.createDirectories()
}
}
val spigotDecompilerMojmapImportMcDev by tasks.registering<ImportMcDevFiles> {
group = "spigot-decompiler-mojmap"
configureForCb(spigotDecompilerMojmapSetup.flatMap { it.dir }, extension.spigot.craftBukkitPatchDir, extension.craftBukkit.patchDir)
}
private fun ImportMcDevFiles.configureForCb(targetDir: Provider<out Directory>, perCommitPatches: DirectoryProperty, perFilePatches: DirectoryProperty? = null) {
this.targetDir.set(targetDir)
perFilePatchDir.set(perFilePatches ?: this.targetDir.map { it.dir("nms-patches") })
perCommitPatchDir.set(perCommitPatches)
filesToImport.set(libraryFilesToImportForCb.map { "brigadier $it" })
configure(spigotDecompileJar.flatMap { it.outputJar }, spigotDecompileJar.flatMap { it.decompiledSource })
sourceMcDevJarSrc.set(spigotDecompileJar.flatMap { it.decompiledSource })
}
@Suppress("DuplicatedCode")
val spigotDecompilerMojmapRemap by tasks.registering<RemapGeneralSources> {
group = "spigot-decompiler-mojmap"
inputSources.set(spigotDecompilerMojmapImportMcDev.flatMap { it.outputDir })
mappings.set(cleanupSourceMappings.flatMap { it.outputMappings }) // spigot-mojang+yarn
vanillaJar.set(extractFromBundler.flatMap { it.serverJar })
mojangMappedVanillaJar.set(fixJar.flatMap { it.outputJar })
vanillaRemappedSpigotJar.set(filterSpigotExcludes.flatMap { it.outputZip })
spigotDeps.from(downloadSpigotDependencies.map { it.outputDir.asFileTree })
additionalAts.set(mergePaperAts.flatMap { it.outputFile })
remappedOutputSources.set(layout.cacheDir(SPIGOT_DECOMPILER_MOJMAP_SRC))
}
val rebuildCraftBukkitPerFilePatches by tasks.registering<RebuildPerFilePatches> {
targetDir.set(remapCraftBukkit.flatMap { it.remappedOutputSources })
directoriesToPatch.set(listOf("src/main/java/net/minecraft", "src/main/java/com/mojang/brigadier"))
commitMsg = "Remap CraftBukkit to Mojang+Yarn Mappings"
spigotDecompiledSource.set(spigotDecompilerMojmapRemap.flatMap { it.remappedOutputSources })
sourcePatchDir.set(targetDir.dir(SOURCE_PATCHES))
}
val remapSpigot by tasks.registering<RemapSpigot> {
remappedCraftBukkitSource.set(rebuildCraftBukkitPerFilePatches.flatMap { it.outputDir })
unmappedCraftBukkitSource.set(extension.craftBukkit.craftBukkitDir)
spigotPerCommitPatches.set(extension.spigot.craftBukkitPatchDir)
unmappedCbCopy.set(remapCraftBukkit.flatMap { it.unmappedCopy })
directoriesToPatch.set(listOf("src/main/java/net/minecraft", "src/main/java/com/mojang/brigadier"))
spigotDecompiledSource.set(spigotDecompilerMojmapRemap.flatMap { it.remappedOutputSources })
mappings.set(cleanupSourceMappings.flatMap { it.outputMappings })
vanillaJar.set(extractFromBundler.flatMap { it.serverJar })
mojangMappedVanillaJar.set(fixJar.flatMap { it.outputJar })
vanillaRemappedSpigotJar.set(filterSpigotExcludes.flatMap { it.outputZip })
spigotDeps.from(downloadSpigotDependencies.map { it.outputDir.asFileTree })
additionalAts.set(mergePaperAts.flatMap { it.outputFile })
spigotApiDir.set(patchSpigotApi.flatMap { it.outputDir })
sourcePatchDir.set(remappedCraftBukkitSource.dir(SOURCE_PATCHES))
unneededFiles.set(listOf("applyPatches.sh", "CONTRIBUTING.md", "makePatches.sh", "README.md", "checkstyle.xml"))
}
val rewriteCraftBukkitSpigotHistory by tasks.registering<RewriteCommits> {
targetDir.set(remapSpigot.flatMap { it.remappedSpigotSource })
commitCallback.value(RewriteCommits.CRAFTBUKKIT_CALLBACK)
}
val importPaperMcDevFiles by tasks.registering<ImportMcDevFiles> {
targetDir.set(rewriteCraftBukkitSpigotHistory.flatMap { it.outputDir })
perCommitPatchDir.set(extension.paper.spigotServerPatchDir)
configure(decompileJar.flatMap { it.outputJar }, decompileJar.flatMap { it.decompiledSource })
devImports.set(extension.paper.devImports.fileExists(project))
}
private fun ImportMcDevFiles.configure(jar: Provider<out RegularFile>, source: Provider<out Directory>) {
sourceMcDevJar.set(jar)
mcLibrariesDir.set(downloadMcLibrariesSources.flatMap { it.outputDir })
spigotLibrariesDir.set(downloadSpigotDependencies.flatMap { it.outputSourcesDir })
libraryOutputDir.set(source)
}
val applyPaperServerPatches by tasks.registering<ApplyServerSourceAndNmsPatches> {
targetDir.set(importPaperMcDevFiles.flatMap { it.outputDir })
patchesToApply.set(extension.paper.spigotServerPatchDir)
directoriesToPatch.set(listOf("src/main/java/net/minecraft", "src/main/java/com/mojang", "src/main/resources/data/minecraft"))
spigotDecompiledSource.set(spigotDecompilerMojmapRemap.flatMap { it.remappedOutputSources })
paperDecompiledSource.set(decompileJar.flatMap { it.decompiledSource })
sourcePatchDir.set(targetDir.dir(SOURCE_PATCHES))
dataPatchDir.set(targetDir.dir(DATA_PATCHES))
}
val finalizeServerHistory by tasks.registering<MoveCommits> {
repoDir.set(applyPaperServerPatches.flatMap { it.outputDir })
toDir.value("paper-server")
}
val applySpigotApiPatches by tasks.registering<ApplyApiPatches> {
bukkitDir.set(cloneRepos.flatMap { it.bukkitClone })
patchesDir.set(extension.spigot.bukkitPatchDir)
}
val rewriteBukkitSpigotHistory by tasks.registering<RewriteCommits> {
targetDir.set(applySpigotApiPatches.flatMap { it.outputDir })
commitCallback.value(RewriteCommits.BUKKIT_CALLBACK)
}
val applyPaperApiPatches by tasks.registering<ApplyApiPatches> {
bukkitDir.set(rewriteBukkitSpigotHistory.flatMap { it.outputDir })
patchesDir.set(extension.paper.spigotApiPatchDir)
unneededFiles.set(listOf("README.md", "checkstyle.xml"))
}
val finalizeApiHistory by tasks.registering<MoveCommits> {
repoDir.set(applyPaperApiPatches.flatMap { it.outputDir })
toDir.value("paper-api")
}
val rewriteAikarPaperHistory by tasks.registering<RewriteCommits> {
targetDir.set(cloneRepos.flatMap { it.paperClone })
commitCallback.value(RewriteCommits.PAPER_CALLBACK)
}
val rewriteSpigotPaperHistory by tasks.registering<RewritePartialPaperHistory> {
paperDir.set(rewriteAikarPaperHistory.flatMap { it.outputDir })
}
val finalizePaperHistory by tasks.registering<FinalizePaperHistory> {
paperDir.set(rewriteSpigotPaperHistory.flatMap { it.outputDir })
deletions.value(listOf("work", "patches", ".gitmodules"))
}
@Suppress("unused")
val mergeGitRepos by tasks.registering<MergeGitRepos> {
cloneBranch.set(cloneBranchName)
bukkitDir.set(finalizeApiHistory.flatMap { it.outputDir })
craftBukkitDir.set(finalizeServerHistory.flatMap { it.outputDir })
paperDir.set(finalizePaperHistory.flatMap { it.outputDir })
outputDir.set(extension.superDir)
}
}

View file

@ -26,6 +26,7 @@ import com.github.salomonbrys.kotson.fromJson
import io.papermc.paperweight.core.ext
import io.papermc.paperweight.core.extension.PaperweightCoreExtension
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.tasks.mm.ResetSubmodules
import io.papermc.paperweight.util.*
import org.gradle.api.Project
import org.gradle.api.provider.Provider
@ -44,6 +45,8 @@ open class GeneralTasks(
offlineMode.set(project.offlineMode())
}
val resetSubmodules by tasks.registering<ResetSubmodules>()
val buildDataInfo: Provider<BuildDataInfo> = project.contents(extension.craftBukkit.buildDataInfo) {
gson.fromJson(it)
}

View file

@ -25,6 +25,7 @@ package io.papermc.paperweight.tasks
import com.github.salomonbrys.kotson.fromJson
import io.papermc.paperweight.util.*
import io.papermc.paperweight.util.constants.*
import java.nio.file.Files
import java.nio.file.Path
import javax.inject.Inject
import kotlin.io.path.*
@ -38,6 +39,7 @@ import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
abstract class ApplyPaperPatches : ControllableOutputTask() {
@ -92,10 +94,14 @@ abstract class ApplyPaperPatches : ControllableOutputTask() {
@get:Input
abstract val verbose: Property<Boolean>
@get:OutputFile
abstract val remapSourcesPatch: RegularFileProperty
override fun init() {
upstreamBranch.convention("master")
ignoreGitIgnore.convention(Git.ignoreProperty(providers)).finalizeValueOnRead()
verbose.convention(providers.verboseApplyPatches())
remapSourcesPatch.convention(objects.fileProperty().convention(layout.cacheFile("$INITIAL_PAPER_PATCHES/remap.patch")))
}
@TaskAction
@ -137,17 +143,6 @@ abstract class ApplyPaperPatches : ControllableOutputTask() {
into(testDir)
}
val patches = patchDir.path.listDirectoryEntries("*.patch")
McDev.importMcDev(
patches = patches,
decompJar = sourceMcDevJar.path,
importsFile = devImports.pathOrNull,
targetDir = sourceDir,
dataTargetDir = mcDataDir,
librariesDirs = listOf(spigotLibrariesDir.path, mcLibrariesDir.path),
printOutput = printOutput.get()
)
val caseOnlyChanges = caseOnlyClassNameChanges.path.bufferedReader(Charsets.UTF_8).use { reader ->
gson.fromJson<List<ClassNameChange>>(reader)
}
@ -158,8 +153,25 @@ abstract class ApplyPaperPatches : ControllableOutputTask() {
git("mv", "-f", obfFile.toString(), deobfFile.toString()).runSilently(silenceErr = true)
}
git(*Git.add(ignoreGitIgnore, ".")).executeSilently()
git("commit", "-m", "Initial", "--author=Initial Source <auto@mated.null>").executeSilently()
val remapSources = git("format-patch", "--no-stat", "-N", "--zero-commit", "--full-index", "--no-signature", "HEAD~1")
remapSourcesPatch.path.deleteForcefully()
Files.move(outputFile.resolve(remapSources.getText().trim()), remapSourcesPatch.path)
git("reset", "--soft", "HEAD~1").executeSilently()
unneededFiles.orNull?.forEach { path -> outputFile.resolve(path).deleteRecursive() }
val patches = patchDir.path.listDirectoryEntries("*.patch")
McDev.importMcDev(
patches = patches,
decompJar = sourceMcDevJar.path,
importsFile = devImports.pathOrNull,
targetDir = sourceDir,
dataTargetDir = mcDataDir,
librariesDirs = listOf(spigotLibrariesDir.path, mcLibrariesDir.path),
printOutput = printOutput.get()
)
git(*Git.add(ignoreGitIgnore, ".")).executeSilently()
git("commit", "-m", "Initial", "--author=Initial Source <auto@mated.null>").executeSilently()
git("tag", "-d", "base").runSilently(silenceErr = true)

View file

@ -29,11 +29,13 @@ import java.util.jar.Attributes
import java.util.jar.Manifest
import kotlin.io.path.*
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.FileCollection
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.*
import org.gradle.jvm.toolchain.JavaLauncher
import org.gradle.kotlin.dsl.support.unzipTo
val vineFlowerArgList: List<String> = listOf(
"--synthetic-not-set=true",
@ -142,6 +144,9 @@ abstract class RunVineFlower : JavaLauncherTask() {
@get:OutputFile
abstract val outputJar: RegularFileProperty
@get:OutputDirectory
abstract val decompiledSource: DirectoryProperty
@get:Internal
abstract val jvmargs: ListProperty<String>
@ -150,6 +155,7 @@ abstract class RunVineFlower : JavaLauncherTask() {
jvmargs.convention(listOf("-Xmx4G"))
outputJar.convention(defaultOutput())
decompiledSource.convention(objects.directoryProperty().convention(layout.cacheDir(PAPER_DECOMPILED_SOURCE_FOLDER)))
}
@TaskAction
@ -165,5 +171,27 @@ abstract class RunVineFlower : JavaLauncherTask() {
launcher.get(),
jvmargs.get()
)
decompiledSource.path.deleteRecursive()
outputJar.get().path.openZip().use { zipFile ->
zipFile.walk().use { stream ->
for (zipEntry in stream) {
if (!zipEntry.isRegularFile()) continue
// substring(1) trims the leading /
val path = zipEntry.invariantSeparatorsPathString.substring(1)
val targetFile = decompiledSource.path.resolve(path)
if (!targetFile.parent.exists()) {
targetFile.parent.createDirectories()
}
zipEntry.copyTo(targetFile)
if (zipEntry.startsWith("/data/minecraft")) {
var content = targetFile.readText(Charsets.UTF_8)
if (!content.endsWith("\n")) {
content += "\n"
targetFile.writeText(content, Charsets.UTF_8)
}
}
}
}
}
}
}

View file

@ -27,13 +27,16 @@ import io.papermc.paperweight.util.*
import io.papermc.paperweight.util.constants.*
import java.util.concurrent.ThreadLocalRandom
import kotlin.io.path.*
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
import org.gradle.api.tasks.Classpath
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.support.unzipTo
@CacheableTask
abstract class SpigotDecompileJar : JavaLauncherTask() {
@ -50,6 +53,9 @@ abstract class SpigotDecompileJar : JavaLauncherTask() {
@get:OutputFile
abstract val outputJar: RegularFileProperty
@get:OutputDirectory
abstract val decompiledSource: DirectoryProperty
@get:Input
abstract val memory: Property<String>
@ -58,6 +64,7 @@ abstract class SpigotDecompileJar : JavaLauncherTask() {
memory.convention("4G")
outputJar.convention(defaultOutput())
decompiledSource.convention(objects.directoryProperty().convention(layout.cacheDir(SPIGOT_DECOMPILED_JAR_SRC)))
}
@TaskAction
@ -92,6 +99,7 @@ abstract class SpigotDecompileJar : JavaLauncherTask() {
ensureDeleted(outputJarFile)
decomp.resolve(inputJarFile.name).moveTo(outputJarFile)
unzipTo(decompiledSource.get().asFile, outputJarFile.toFile())
} finally {
decomp.deleteRecursive()
}

View file

@ -0,0 +1,49 @@
package io.papermc.paperweight.tasks.mm
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
abstract class ApplyApiPatches : BaseTask() {
@get:InputDirectory
abstract val bukkitDir: DirectoryProperty
@get:InputDirectory
abstract val patchesDir: DirectoryProperty
@get:Optional
@get:Input
abstract val unneededFiles: ListProperty<String>
@get:OutputDirectory
abstract val outputDir: DirectoryProperty
override fun init() {
group = "mm"
outputDir.convention(bukkitDir)
}
@TaskAction
fun run() {
Git.checkForGit()
Git(bukkitDir).let { git ->
if (unneededFiles.isPresent && unneededFiles.get().size > 0) {
unneededFiles.get().forEach { path -> outputDir.path.resolve(path).deleteRecursive() }
git(*Git.add(false, ".")).executeSilently()
git("commit", "-m", "Removed unneeded files", "--author=Initial Source <auto@mated.null>").executeSilently()
}
patchesDir.asFileTree.files.sorted().forEach { patch ->
git("am", patch.absolutePath).execute()
}
}
}
}

View file

@ -0,0 +1,43 @@
package io.papermc.paperweight.tasks.mm
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import java.nio.file.Files
import kotlin.io.path.*
import kotlin.streams.asSequence
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
abstract class ApplyPerFilePatches : BaseTask() {
@get:InputDirectory
abstract val targetDir: DirectoryProperty
@get:InputDirectory
abstract val perFilePatches: DirectoryProperty
@get:OutputDirectory
abstract val outputDir: DirectoryProperty
override fun init() {
super.init()
group = "mm"
outputDir.convention(targetDir)
}
@TaskAction
fun run() {
val patchesToApplyDir = perFilePatches.path
val patchList = Files.walk(patchesToApplyDir).use { it.asSequence().filter { file -> file.isRegularFile() }.toSet() }
val basePatchDirFile = targetDir.path.resolve("src/main/java")
val git = Git(targetDir.path)
for (file in patchList) {
val javaName = javaFileName(patchesToApplyDir, file)
println("Patching ${javaName.removeSuffix(".java")}")
val dirPrefix = basePatchDirFile.relativeTo(outputDir.path).invariantSeparatorsPathString
git("apply", "--ignore-whitespace", "--directory=$dirPrefix", file.absolutePathString()).execute()
}
}
}

View file

@ -0,0 +1,115 @@
package io.papermc.paperweight.tasks.mm
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import java.nio.file.Files
import java.nio.file.Path
import kotlin.io.path.*
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.*
abstract class ApplyServerSourceAndNmsPatches : BaseTask() {
@get:InputDirectory
abstract val targetDir: DirectoryProperty
@get:InputDirectory
abstract val patchesToApply: DirectoryProperty
@get:Input
abstract val directoriesToPatch: ListProperty<String>
@get:InputDirectory
abstract val spigotDecompiledSource: DirectoryProperty
@get:InputDirectory
@get:Optional
abstract val paperDecompiledSource: DirectoryProperty
@get:OutputDirectory
abstract val sourcePatchDir: DirectoryProperty
@get:OutputDirectory
abstract val dataPatchDir: DirectoryProperty
@get:Optional
@get:Input
abstract val unneededFiles: ListProperty<String>
@get:OutputDirectory
abstract val outputDir: DirectoryProperty
override fun init() {
group = "mm"
outputDir.convention(targetDir)
directoriesToPatch.convention(objects.listProperty(String::class))
}
private fun createPerFileDiff(patchDir: Path, files: Iterable<String>, prefix: String, splitPrefix: String = prefix) {
files.map { "$prefix$it" }.filter { directoriesToPatch.get().any { dir -> it.startsWith(dir) } } .forEach { file ->
val patchedFile = targetDir.file(file).get().asFile
val fileName = patchedFile.absolutePath.split(splitPrefix, limit = 2)[1]
var nmsFile = spigotDecompiledSource.file(fileName).get().path
if (paperDecompiledSource.isPresent && Files.notExists(nmsFile)) {
nmsFile = paperDecompiledSource.file(fileName).get().path
}
if (Files.notExists(nmsFile)) {
// we add new files within src/main/resources/data/minecraft/ but they don't exist in the nms source
return@forEach
}
val patchFile = patchDir.resolve(fileName).resolveSibling((patchedFile.name + ".patch")) // keep extension
val commandText =
listOf<String>("diff", "-u", "--label", "a/$fileName", nmsFile.absolutePathString(), "--label", "b/$fileName", patchedFile.absolutePath)
val processBuilder = ProcessBuilder(commandText).directory(targetDir.path)
val command = Command(processBuilder, commandText.joinToString(" "), arrayOf(0, 1))
val output = command.getText()
Files.createDirectories(patchFile.parent)
patchFile.bufferedWriter().use {
it.write(output)
}
}
}
@TaskAction
fun run() {
Git.checkForGit()
Git(targetDir).let { git ->
val sourcePatchesDir = sourcePatchDir.path
val dataPatchesDir = dataPatchDir.path
patchesToApply.asFileTree.files.sorted().forEach { patch ->
val patchName = patch.name.split("-", limit = 2)[1]
println("Applying Patch: $patchName")
val excludeArray = directoriesToPatch.get().map { "--exclude=$it/**" }.toTypedArray()
git("am", "--ignore-whitespace", "--include=src/main/resources/data/minecraft/datapacks/paper/**", *excludeArray, "--include=**", patch.toPath().absolutePathString()).execute()
val includeArray = directoriesToPatch.get().map { "--include=$it/**" }.toTypedArray()
git("apply", "--ignore-whitespace", "--exclude=src/main/resources/data/minecraft/datapacks/paper/**", *includeArray, patch.toPath().absolutePathString()).execute()
val (sourceFiles, dataFiles) = McDev.readPatchLines(listOf(patch.toPath()))
createPerFileDiff(sourcePatchesDir, sourceFiles, "src/main/java/")
createPerFileDiff(dataPatchesDir, dataFiles, "src/main/resources/data/minecraft/", "src/main/resources/")
if (sourceFiles.isNotEmpty() || dataFiles.isNotEmpty()) {
git("add", sourcePatchesDir.absolutePathString(), dataPatchesDir.absolutePathString()).execute()
git("commit", "--amend", "--no-edit").execute()
}
}
if (unneededFiles.isPresent && unneededFiles.get().size > 0) {
unneededFiles.get().forEach { path ->
outputDir.path.resolve(path).deleteRecursive()
git(*Git.add(false, path)).executeSilently()
}
git("commit", "-m", "Removed unneeded files", "--author=Initial Source <auto@mated.null>").executeSilently()
}
}
}
}

View file

@ -0,0 +1,61 @@
package io.papermc.paperweight.tasks.mm
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import kotlin.io.path.*
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.UntrackedTask
@UntrackedTask(because = "Git")
abstract class CloneRepos : BaseTask() {
@get:Input
abstract val cloneBranch: Property<String>
@get:InputDirectory
abstract val craftBukkitDir: DirectoryProperty
@get:InputDirectory
abstract val bukkitDir: DirectoryProperty
@get:OutputDirectory
abstract val craftBukkitClone: DirectoryProperty
@get:OutputDirectory
abstract val bukkitClone: DirectoryProperty
@get:OutputDirectory
abstract val paperClone: DirectoryProperty
override fun init() {
group = "mm"
craftBukkitClone.convention(project, craftBukkitDir.map {
it.path.resolveSibling("CraftBukkitClone")
})
bukkitClone.convention(project, bukkitDir.map {
it.path.resolveSibling("BukkitClone")
})
}
@TaskAction
fun run() {
Git.checkForGit()
listOf(
Pair(craftBukkitClone, craftBukkitDir),
Pair(bukkitClone, bukkitDir),
Pair(paperClone, project.rootProject.rootDir)
).forEach {
it.first.path.deleteRecursive()
Git(it.second).let { git ->
git("branch", "-f", cloneBranch.get(), "HEAD").runSilently(silenceErr = true)
git("clone", ".", it.first.path.absolutePathString(), "--branch", cloneBranch.get()).execute()
}
}
}
}

View file

@ -0,0 +1,108 @@
package io.papermc.paperweight.tasks.mm
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import java.nio.file.Files
import java.nio.file.Path
import kotlin.io.path.*
import kotlin.streams.asSequence
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
abstract class ImportMcDevFiles : BaseTask() {
@get:InputFile
abstract val sourceMcDevJar: RegularFileProperty
@get:InputDirectory
@get:Optional
abstract val sourceMcDevJarSrc: DirectoryProperty
@get:InputDirectory
@get:Optional
abstract val perCommitPatchDir: DirectoryProperty
@get:InputDirectory
@get:Optional
abstract val perFilePatchDir: DirectoryProperty
@get:Optional
@get:InputFile
abstract val devImports: RegularFileProperty
@get:Optional
@get:Input
abstract val filesToImport: ListProperty<String>
@get:InputDirectory
abstract val mcLibrariesDir: DirectoryProperty
@get:InputDirectory
abstract val spigotLibrariesDir: DirectoryProperty
@get:InputDirectory
abstract val targetDir: DirectoryProperty
@get:OutputDirectory
abstract val outputDir: DirectoryProperty
@get:OutputDirectory
abstract val libraryOutputDir: DirectoryProperty
override fun init() {
group = "mm"
outputDir.convention(targetDir)
}
@TaskAction
fun run() {
Git.checkForGit()
val patches = perCommitPatchDir.map { it.path.listDirectoryEntries("*.patch") }.orElse(emptyList()).get()
McDev.importMcDev(
patches = patches,
decompJar = sourceMcDevJar.path,
importsFile = importsFile(),
targetDir = targetDir.path.resolve("src/main/java"),
dataTargetDir = targetDir.path.resolve("src/main/resources"),
librariesDirs = listOf(spigotLibrariesDir.path, mcLibrariesDir.path),
secondaryLibraryTargetDir = libraryOutputDir.path
)
if (perFilePatchDir.isPresent && sourceMcDevJarSrc.isPresent) {
val perFilePatches = perFilePatchDir.path
val patchList = Files.walk(perFilePatches).use { it.asSequence().filter { file -> file.isRegularFile() }.toSet() }
if (patchList.isNotEmpty()) {
val basePatchDirFile = targetDir.path.resolve("src/main/java")
// Copy in patch targets
for (file in patchList) {
val javaName = javaFileName(perFilePatches, file)
val out = basePatchDirFile.resolve(javaName)
val sourcePath = sourceMcDevJarSrc.path.resolve(javaName)
out.parent.createDirectories()
sourcePath.copyTo(out, true)
}
}
}
}
private fun importsFile(): Path? {
if (devImports.isPresent) {
return devImports.path
} else if (filesToImport.isPresent) {
val temp = createTempFile("importMcDevFile", "txt")
temp.writeLines(filesToImport.get())
return temp
}
return null
}
}

View file

@ -0,0 +1,84 @@
package io.papermc.paperweight.tasks.mm
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import java.io.File
import java.nio.file.Files
import java.nio.file.Path
import kotlin.io.path.*
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
abstract class RebuildPerFilePatches : BaseTask() {
@get:InputDirectory
abstract val targetDir: DirectoryProperty
@get:InputDirectory
abstract val spigotDecompiledSource: DirectoryProperty
@get:Input
abstract val directoriesToPatch: ListProperty<String>
@get:Input
abstract val commitMsg: Property<String>
@get:OutputDirectory
abstract val sourcePatchDir: DirectoryProperty
@get:OutputDirectory
abstract val outputDir: DirectoryProperty
override fun init() {
group = "mm"
outputDir.convention(targetDir)
}
@TaskAction
fun run() {
Git.checkForGit()
val sourcePatchesDir = sourcePatchDir.path
sourcePatchesDir.resolve("net/minecraft").deleteRecursive()
rebuildPerFilePatches(targetDir.asFileTree.matching {
directoriesToPatch.get().forEach { include("$it/**/*.java") }
}, spigotDecompiledSource, sourcePatchesDir)
Git(targetDir).let { git ->
git("add", sourcePatchesDir.absolutePathString(), "src/test", "src/main/java/org").execute()
git("commit", "-m", commitMsg.get(), "--author=Initial Source <auto@mated.null>").execute()
}
}
companion object {
fun rebuildPerFilePatches(source: Iterable<File>, originalSource: DirectoryProperty, patchDir: Path) {
source.forEach { sourceFile ->
createPerFilePatch(sourceFile.toPath(), originalSource, patchDir)
}
}
private fun createPerFilePatch(patchedFile: Path, originalSource: DirectoryProperty, patchDir: Path) {
val fileName = patchedFile.absolutePathString().split("src/main/java/", limit = 2)[1]
val nmsFile = originalSource.file(fileName).path
val patchFile = patchDir.resolve(fileName).resolveSibling((patchedFile.name + ".patch")) // keep extension
val commandText = listOf("diff", "-u", "--label", "a/$fileName", nmsFile.absolutePathString(), "--label", "b/$fileName", patchedFile.absolutePathString())
val processBuilder = ProcessBuilder(commandText)
val command = Command(processBuilder, commandText.joinToString(" "), arrayOf(0, 1))
val output = command.getText()
patchFile.deleteRecursive()
Files.createDirectories(patchFile.parent)
patchFile.bufferedWriter().use {
it.write(output)
}
}
}
}

View file

@ -0,0 +1,134 @@
package io.papermc.paperweight.tasks.mm
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import io.papermc.paperweight.util.constants.*
import javax.inject.Inject
import kotlin.io.path.*
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.*
import org.gradle.kotlin.dsl.*
import org.gradle.workers.WorkerExecutor
abstract class RemapCraftBukkit : JavaLauncherTask() {
@get:InputDirectory
abstract val inputSources: DirectoryProperty
@get:InputFile
@get:PathSensitive(PathSensitivity.NONE)
abstract val mappings: RegularFileProperty
@get:CompileClasspath
abstract val vanillaJar: RegularFileProperty
@get:CompileClasspath
abstract val mojangMappedVanillaJar: RegularFileProperty
@get:CompileClasspath
abstract val vanillaRemappedSpigotJar: RegularFileProperty
@get:CompileClasspath
abstract val spigotDeps: ConfigurableFileCollection
@get:InputDirectory
@get:PathSensitive(PathSensitivity.RELATIVE)
abstract val bukkitApiDir: DirectoryProperty
@get:Optional
@get:InputFile
@get:PathSensitive(PathSensitivity.NONE)
abstract val additionalAts: RegularFileProperty
@get:OutputDirectory
abstract val remappedOutputSources: DirectoryProperty
@get:OutputDirectory
abstract val unmappedCopy: DirectoryProperty
@get:OutputFile
abstract val generatedAt: RegularFileProperty
@get:Inject
abstract val workerExecutor: WorkerExecutor
override fun init() {
super.init()
group = "mm"
remappedOutputSources.convention(inputSources)
unmappedCopy.convention(layout.cacheDir(UNMAPPED_CB_SOURCE_COPY))
generatedAt.convention(defaultOutput("at"))
}
@TaskAction
fun run() {
unmappedCopy.path.deleteRecursive()
inputSources.path.copyRecursivelyTo(unmappedCopy.path)
val outputParentDir = remappedOutputSources.path
val outputSourcesDir = outputParentDir.resolve("src/main/java")
val outputTestsDir = outputParentDir.resolve("src/test/java")
val srcOut = findOutputDir(outputSourcesDir).apply { createDirectories() }
val testOut = findOutputDir(outputTestsDir).apply { createDirectories() }
try {
val queue = workerExecutor.processIsolation {
forkOptions.jvmArgs("-Xmx2G")
forkOptions.executable(launcher.get().executablePath.path.absolutePathString())
}
val srcDir = inputSources.path.resolve("src/main/java")
queue.submit(RemapSources.RemapAction::class) {
classpath.from(vanillaRemappedSpigotJar.path)
classpath.from(mojangMappedVanillaJar.path)
classpath.from(vanillaJar.path)
classpath.from(bukkitApiDir.dir("src/main/java").path)
classpath.from(spigotDeps.files.filter { it.toPath().isLibraryJar })
additionalAts.set(this@RemapCraftBukkit.additionalAts.pathOrNull)
mappings.set(this@RemapCraftBukkit.mappings.path)
inputDir.set(srcDir)
cacheDir.set(this@RemapCraftBukkit.layout.cache)
outputDir.set(srcOut)
generatedAtOutput.set(this@RemapCraftBukkit.generatedAt.path)
}
val testSrc = inputSources.path.resolve("src/test/java")
queue.submit(RemapSources.RemapAction::class) {
classpath.from(vanillaRemappedSpigotJar.path)
classpath.from(mojangMappedVanillaJar.path)
classpath.from(vanillaJar.path)
classpath.from(bukkitApiDir.dir("src/main/java").path)
classpath.from(spigotDeps.files.filter { it.toPath().isLibraryJar })
classpath.from(srcDir)
additionalAts.set(this@RemapCraftBukkit.additionalAts.pathOrNull)
mappings.set(this@RemapCraftBukkit.mappings.path)
inputDir.set(testSrc)
cacheDir.set(this@RemapCraftBukkit.layout.cache)
outputDir.set(testOut)
}
queue.await()
outputSourcesDir.deleteRecursive()
srcOut.copyRecursivelyTo(outputSourcesDir)
outputTestsDir.deleteRecursive()
testOut.copyRecursivelyTo(outputTestsDir)
} finally {
srcOut.deleteRecursive()
testOut.deleteRecursive()
}
}
}

View file

@ -0,0 +1,103 @@
package io.papermc.paperweight.tasks.mm
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.tasks.RemapSources
import io.papermc.paperweight.util.*
import io.papermc.paperweight.util.constants.*
import javax.inject.Inject
import kotlin.io.path.*
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.CompileClasspath
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.InputFile
import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskAction
import org.gradle.kotlin.dsl.*
import org.gradle.workers.WorkerExecutor
abstract class RemapGeneralSources : JavaLauncherTask() {
@get:InputDirectory
abstract val inputSources: DirectoryProperty
@get:InputFile
@get:PathSensitive(PathSensitivity.NONE)
abstract val mappings: RegularFileProperty
@get:CompileClasspath
abstract val vanillaJar: RegularFileProperty
@get:CompileClasspath
abstract val mojangMappedVanillaJar: RegularFileProperty
@get:CompileClasspath
abstract val vanillaRemappedSpigotJar: RegularFileProperty
@get:CompileClasspath
abstract val spigotDeps: ConfigurableFileCollection
@get:Optional
@get:InputFile
@get:PathSensitive(PathSensitivity.NONE)
abstract val additionalAts: RegularFileProperty
@get:OutputDirectory
abstract val remappedOutputSources: DirectoryProperty
@get:OutputDirectory
@get:Optional
abstract val unmappedCopy: DirectoryProperty
@get:Inject
abstract val workerExecutor: WorkerExecutor
override fun init() {
super.init()
group = "mm"
}
@TaskAction
fun run() {
if (unmappedCopy.isPresent) {
unmappedCopy.path.deleteRecursive()
inputSources.path.copyRecursivelyTo(unmappedCopy.path)
}
val sourcesDir = inputSources.path
val srcOut = findOutputDir(remappedOutputSources.path).apply { createDirectories() }
try {
val queue = workerExecutor.processIsolation {
forkOptions.jvmArgs("-Xmx2G")
forkOptions.executable(launcher.get().executablePath.path.absolutePathString())
}
queue.submit(RemapSources.RemapAction::class) {
classpath.from(vanillaRemappedSpigotJar.path)
classpath.from(mojangMappedVanillaJar.path)
classpath.from(vanillaJar.path)
classpath.from(spigotDeps.files.filter { it.toPath().isLibraryJar })
additionalAts.set(this@RemapGeneralSources.additionalAts.pathOrNull)
mappings.set(this@RemapGeneralSources.mappings.path)
inputDir.set(sourcesDir)
cacheDir.set(this@RemapGeneralSources.layout.cache)
outputDir.set(srcOut)
}
queue.await()
sourcesDir.deleteRecursive()
remappedOutputSources.path.deleteRecursive()
srcOut.copyRecursivelyTo(remappedOutputSources.path)
} finally {
srcOut.deleteRecursive()
}
}
}

View file

@ -0,0 +1,204 @@
package io.papermc.paperweight.tasks.mm
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import io.papermc.paperweight.util.constants.*
import java.nio.file.Files
import java.nio.file.Path
import javax.inject.Inject
import kotlin.io.path.*
import org.gradle.api.file.ConfigurableFileCollection
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.file.RegularFileProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.*
import org.gradle.kotlin.dsl.*
import org.gradle.workers.WorkerExecutor
abstract class RemapSpigot : JavaLauncherTask() {
@get:InputDirectory
abstract val remappedCraftBukkitSource: DirectoryProperty
@get:InputDirectory
abstract val unmappedCraftBukkitSource: DirectoryProperty
@get:InputDirectory
abstract val spigotPerCommitPatches: DirectoryProperty
@get:InputDirectory
abstract val unmappedCbCopy: DirectoryProperty
@get:InputDirectory
abstract val spigotDecompiledSource: DirectoryProperty
@get:Input
abstract val directoriesToPatch: ListProperty<String>
@get:InputFile
@get:PathSensitive(PathSensitivity.NONE)
abstract val mappings: RegularFileProperty
@get:CompileClasspath
abstract val vanillaJar: RegularFileProperty
@get:CompileClasspath
abstract val mojangMappedVanillaJar: RegularFileProperty
@get:CompileClasspath
abstract val vanillaRemappedSpigotJar: RegularFileProperty
@get:CompileClasspath
abstract val spigotDeps: ConfigurableFileCollection
@get:InputDirectory
@get:PathSensitive(PathSensitivity.RELATIVE)
abstract val spigotApiDir: DirectoryProperty
@get:Optional
@get:InputFile
@get:PathSensitive(PathSensitivity.NONE)
abstract val additionalAts: RegularFileProperty
@get:Optional
@get:Input
abstract val unneededFiles: ListProperty<String>
@get:OutputFile
abstract val generatedAt: RegularFileProperty
@get:OutputDirectory
abstract val sourcePatchDir: DirectoryProperty
@get:OutputDirectory
abstract val remappedSpigotSource: DirectoryProperty
@get:Inject
abstract val workerExecutor: WorkerExecutor
override fun init() {
super.init()
group = "mm"
generatedAt.convention(defaultOutput("at"))
remappedSpigotSource.convention(remappedCraftBukkitSource)
}
@TaskAction
fun run() {
Git.checkForGit()
val unmappedCbSourceWork = layout.cacheDir(UNMAPPED_CB_SOURCE_WORK).path
unmappedCbSourceWork.deleteRecursive()
val remappedCbSpigotSourceWork = layout.cacheDir(REMAPPED_CB_SPIGOT_SOURCE_WORK).path
remappedCbSpigotSourceWork.deleteRecursive()
Git(unmappedCraftBukkitSource).let { git ->
git("clone", ".", unmappedCbSourceWork.absolutePathString()).execute()
}
unmappedCbCopy.path.copyRecursivelyTo(unmappedCbSourceWork, true)
val mappedGit = Git(remappedCraftBukkitSource)
val unmappedGit = Git(unmappedCbSourceWork)
val queue = workerExecutor.processIsolation {
forkOptions.jvmArgs("-Xmx2G")
forkOptions.executable(launcher.get().executablePath.path.absolutePathString())
}
// var count = 0
spigotPerCommitPatches.asFileTree.files.sorted().forEach { patch ->
// count++
// if (count > 3) return@forEach
val patchName = patch.name.split("-", limit = 2)[1]
println("Applying Spigot Patch: $patchName")
mappedGit("am", "--exclude=src/*/java/**", patch.toPath().absolutePathString()).execute() // apply empty commit to keep commit info
unmappedGit("apply", "--ignore-whitespace", "--include=src/*/java/**", patch.toPath().absolutePathString()).execute() // apply full commit to unmapped work cb dir
val outputSourcesDir = remappedCbSpigotSourceWork.resolve("src/main/java")
val outputTestsDir = remappedCbSpigotSourceWork.resolve("src/test/java")
val srcOut = findOutputDir(outputSourcesDir).apply { createDirectories() }
val testOut = findOutputDir(outputTestsDir).apply { createDirectories() }
try {
val srcDir = unmappedCbSourceWork.resolve("src/main/java")
queue.submit(RemapSources.RemapAction::class) {
classpath.from(vanillaRemappedSpigotJar.path)
classpath.from(mojangMappedVanillaJar.path)
classpath.from(vanillaJar.path)
classpath.from(spigotApiDir.dir("src/main/java").path)
classpath.from(spigotDeps.files.filter { it.toPath().isLibraryJar })
additionalAts.set(this@RemapSpigot.additionalAts.pathOrNull)
mappings.set(this@RemapSpigot.mappings.path)
inputDir.set(srcDir)
cacheDir.set(this@RemapSpigot.layout.cache)
outputDir.set(srcOut)
generatedAtOutput.set(this@RemapSpigot.generatedAt.path)
}
val testSrc = unmappedCbSourceWork.resolve("src/test/java")
queue.submit(RemapSources.RemapAction::class) {
classpath.from(vanillaRemappedSpigotJar.path)
classpath.from(mojangMappedVanillaJar.path)
classpath.from(vanillaJar.path)
classpath.from(spigotApiDir.dir("src/main/java").path)
classpath.from(spigotDeps.files.filter { it.toPath().isLibraryJar })
classpath.from(srcDir)
additionalAts.set(this@RemapSpigot.additionalAts.pathOrNull)
mappings.set(this@RemapSpigot.mappings.path)
inputDir.set(testSrc)
cacheDir.set(this@RemapSpigot.layout.cache)
outputDir.set(testOut)
}
queue.await()
srcOut.copyRecursivelyTo(outputSourcesDir, true)
srcOut.deleteRecursive()
testOut.copyRecursivelyTo(outputTestsDir, true)
testOut.deleteRecursive()
} finally {
srcOut.deleteRecursive()
testOut.deleteRecursive()
}
rebuildSource("main", remappedCbSpigotSourceWork, mappedGit)
rebuildSource("test", remappedCbSpigotSourceWork, mappedGit)
mappedGit("add", sourcePatchDir.path.absolutePathString(), "src/test", "src/main/java/org").execute()
mappedGit("commit", "--amend", "--no-edit").execute()
}
if (unneededFiles.isPresent && unneededFiles.get().size > 0) {
unneededFiles.get().forEach { path ->
remappedSpigotSource.path.resolve(path).deleteRecursive()
mappedGit(*Git.add(false, path)).executeSilently()
}
mappedGit("commit", "-m", "Removed unneeded files", "--author=Initial Source <auto@mated.null>").executeSilently()
}
}
private fun rebuildSource(type: String, outputDir: Path, git: Git) {
val commandText = listOf("diff", "-ruN", remappedCraftBukkitSource.path.resolve("src/$type/java").absolutePathString(), outputDir.resolve("src/$type/java").absolutePathString())
val cmd = Command(ProcessBuilder(commandText), commandText.joinToString(" "), arrayOf(0, 1))
val output = cmd.getText()
.replace(Regex("^--- ${remappedCraftBukkitSource.path.absolutePathString()}/", RegexOption.MULTILINE), "--- a/")
.replace(Regex("^\\+\\+\\+ ${outputDir.absolutePathString()}/", RegexOption.MULTILINE), "+++ b/")
val tempPatch = Files.createTempFile("spigot", "patch")
tempPatch.bufferedWriter().use {
it.write(output)
}
git("apply", "--allow-empty", tempPatch.absolutePathString()).execute()
RebuildPerFilePatches.rebuildPerFilePatches(
remappedCraftBukkitSource.asFileTree
.matching { directoriesToPatch.get().forEach { include("$it/**/*.java") } },
spigotDecompiledSource,
sourcePatchDir.path
)
tempPatch.deleteRecursive()
}
}

View file

@ -0,0 +1,24 @@
package io.papermc.paperweight.tasks.mm
import io.papermc.paperweight.util.*
import javax.inject.Inject
import org.gradle.api.DefaultTask
import org.gradle.api.file.ProjectLayout
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.UntrackedTask
@UntrackedTask(because = "Git")
abstract class ResetSubmodules : DefaultTask() {
@get:Inject
abstract val layout: ProjectLayout
init {
group = "mm"
}
@TaskAction
fun run() {
layout.resetSubmodules()
}
}

View file

@ -0,0 +1,66 @@
package io.papermc.paperweight.tasks.mm
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.tasks.mm.filterrepo.RewriteCommits
import io.papermc.paperweight.util.*
import java.nio.file.Files
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.UntrackedTask
@UntrackedTask(because = "git")
abstract class RewritePartialPaperHistory : BaseTask() {
companion object {
const val REPLACE_TEXT = """
regex:@@\s-\d+,\d+\s\+\d+,\d+\s@@==>@@ -0,0 +0,0 @@
regex:index\s([a-fA-F0-9]{40})\.\.([a-fA-F0-9]{40})==>index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
"""
}
@get:InputDirectory
abstract val paperDir: DirectoryProperty
@get:OutputDirectory
abstract val outputDir: DirectoryProperty
override fun init() {
group = "mm"
outputDir.convention(paperDir)
}
@TaskAction
fun run() {
Git.checkForGit()
Git(paperDir).let { git ->
var firstCommit = git("log", "--grep=Rename to PaperSpigot", "--format=%H").getText().trim()
val lastRenameCommit = git("log", "-1", "--format=%H", "$firstCommit~1").getText().trim()
val firstRenameCommit = git("rev-list", "--max-parents=0", "HEAD").getText().trim()
val commitsToRewrite = git("rev-list", "--ancestry-path", "$firstRenameCommit..$lastRenameCommit").getText()
.trim().lines().map {
"commit.original_id == b'${it}'"
}
println("Commits to rewrite: ${commitsToRewrite.size}")
val callbackArg = """
${RewriteCommits.UTILS}
if ${commitsToRewrite.joinToString(" or ")}:
${RewriteCommits.COMMIT_MSG.lines().joinToString("\n") { " $it" }}
commit.author_name = b'Spigot'
commit.author_email = b'spigot@github.com'
${RewriteCommits.RESET_CALLBACK}""".trimIndent()
git("filter-repo", "--force", "--commit-callback", callbackArg).executeOut()
firstCommit = git("log", "--grep=Rename to PaperSpigot", "--format=%H").getText().trim()
println("Removing index and line number changes from patch diff")
val tempFile = Files.createTempFile("paperweight", "filter-repo")
Files.writeString(tempFile, REPLACE_TEXT.trimIndent())
git("filter-repo", "--replace-text", tempFile.toAbsolutePath().toString(), "--refs", "$firstCommit..HEAD").executeOut()
Files.deleteIfExists(tempFile)
}
}
}

View file

@ -0,0 +1,79 @@
package io.papermc.paperweight.tasks.mm
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import java.nio.file.Files
import kotlin.io.path.*
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
abstract class SetupCraftBukkit : BaseTask() {
@get:InputDirectory
abstract val targetDir: DirectoryProperty
@get:InputDirectory
abstract val perFilePatches: DirectoryProperty
@get:InputDirectory
abstract val sourceForPatchRecreation: DirectoryProperty
@get:Input
abstract val recreateAsPatches: ListProperty<String>
@get:OutputDirectory
abstract val newPerFilePatchesDirectory: DirectoryProperty
@get:OutputDirectory
abstract val outputDir: DirectoryProperty
override fun init() {
group = "mm"
outputDir.convention(targetDir)
}
@TaskAction
fun run() {
Git.checkForGit()
// move to new patch location
val patchesToApplyDir = perFilePatches.path
val git = Git(targetDir.path)
val newPatchesDir = newPerFilePatchesDirectory.path;
newPatchesDir.deleteRecursive()
project.copy {
from(patchesToApplyDir)
into(newPatchesDir)
}
targetDir.path.resolve("nms-patches").deleteRecursive() // delete old directory
git("add", "nms-patches", newPatchesDir.absolutePathString()).execute()
// converts files that CB had previously included in their entirety from external libraries
// to patches of the original library source files
recreateAsPatches.get().forEach { toRecreate ->
val patchedFile = targetDir.file(toRecreate).path
val fileName = patchedFile.absolutePathString().split("src/main/java/", limit = 2)[1]
val nmsFile = sourceForPatchRecreation.get().file(fileName).asFile
val patchFile = newPatchesDir.resolve(fileName).resolveSibling((patchedFile.name + ".patch")) // keep extension
val commandText =
listOf<String>("diff", "-u", "--label", "a/$fileName", nmsFile.absolutePath, "--label", "b/$fileName", patchedFile.absolutePathString())
val processBuilder = ProcessBuilder(commandText).directory(targetDir.get().asFile)
val command = Command(processBuilder, commandText.joinToString(" "), arrayOf(0, 1))
val output = command.getText()
Files.createDirectories(patchFile.parent)
patchFile.bufferedWriter().use {
it.write(output)
}
git("rm", "--cached", toRecreate).execute()
git("add", patchFile.absolutePathString()).execute()
}
git("commit", "-m", "Move CraftBukkit per-file patches", "--author=Initial <auto@mated.null>").execute()
}
}

View file

@ -0,0 +1,44 @@
package io.papermc.paperweight.tasks.mm.filterrepo
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.UntrackedTask
import org.gradle.kotlin.dsl.*
@UntrackedTask(because = "git")
abstract class FinalizePaperHistory : BaseTask() {
@get:InputDirectory
abstract val paperDir: DirectoryProperty
@get:Input
abstract val deletions: ListProperty<String>
@get:OutputDirectory
abstract val outputDir: DirectoryProperty
override fun init() {
group = "mm"
outputDir.convention(paperDir)
deletions.convention(objects.listProperty())
}
@TaskAction
fun run() {
Git.checkForGit()
val deletionsArr = deletions.get().toTypedArray()
if (deletionsArr.isEmpty()) {
return
}
Git(paperDir).let { git ->
git("rm", "-r", *deletionsArr).execute()
git("commit", "-m", "OWW! That fork is HARD!", "--author=Automated <auto@mated.null>").execute()
}
}
}

View file

@ -0,0 +1,64 @@
package io.papermc.paperweight.tasks.mm.filterrepo
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import java.nio.file.Files
import kotlin.io.path.*
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
abstract class MergeGitRepos : BaseTask() {
@get:Input
abstract val cloneBranch: Property<String>
@get:InputDirectory
abstract val bukkitDir: DirectoryProperty
@get:InputDirectory
abstract val craftBukkitDir: DirectoryProperty
@get:InputDirectory
abstract val paperDir: DirectoryProperty
@get:OutputDirectory
abstract val outputDir: DirectoryProperty
override fun init() {
group = "mm"
}
@TaskAction
fun run() {
Git.checkForGit()
val paperGit = Git(paperDir)
val currentBranch = paperGit("rev-parse", "--abbrev-ref", "HEAD").getText().trim()
outputDir.path.deleteRecursive()
Files.createDirectories(outputDir.path)
Git(outputDir).let { git ->
git("init").execute()
git("remote", "add", "bukkit", bukkitDir.path.absolutePathString()).execute()
git("remote", "add", "craftbukkit", craftBukkitDir.path.absolutePathString()).execute()
git("remote", "add", "paper", paperDir.path.absolutePathString()).execute()
git("fetch", "--all").execute()
git("merge", "bukkit/${cloneBranch.get()}", "--no-edit").execute()
git("merge", "craftbukkit/${cloneBranch.get()}", "--no-edit", "--allow-unrelated-histories").execute()
git("commit", "--amend", "--no-edit", "--author=Initial Source <auto@mated.null>").execute()
git("merge", "paper/$currentBranch", "--no-edit", "--allow-unrelated-histories").execute()
git("commit", "--amend", "--no-edit", "--author=Initial Source <auto@mated.null>").execute()
}
// bukkitDir.path.deleteRecursively()
// craftBukkitDir.path.deleteRecursively()
// paperDir.path.deleteRecursively()
}
}

View file

@ -0,0 +1,34 @@
package io.papermc.paperweight.tasks.mm.filterrepo
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
abstract class MoveCommits : BaseTask() {
@get:InputDirectory
abstract val repoDir: DirectoryProperty
@get:Input
abstract val toDir: Property<String>
@get:OutputDirectory
abstract val outputDir: DirectoryProperty
override fun init() {
group = "mm"
outputDir.convention(repoDir)
}
@TaskAction
fun run() {
Git.checkForGit()
Git(repoDir)("filter-repo", "--to-subdirectory-filter", toDir.get(), "--force", "--commit-callback", RewriteCommits.RESET_CALLBACK).executeOut()
}
}

View file

@ -0,0 +1,110 @@
package io.papermc.paperweight.tasks.mm.filterrepo
import io.papermc.paperweight.tasks.*
import io.papermc.paperweight.util.*
import org.gradle.api.file.DirectoryProperty
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputDirectory
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction
import org.gradle.api.tasks.UntrackedTask
import org.gradle.kotlin.dsl.*
@UntrackedTask(because = "git")
abstract class RewriteCommits : BaseTask() {
companion object {
const val UTILS = """
def insert_into_commit_msg(text):
msg_split = commit.message.decode("utf-8").split("\n")
idx = min([i for i,x in enumerate(msg_split) if x.find("Co-authored-by:") != -1 or x.find("By:") != -1 or x.find("Also-by:") != -1], default=None)
if idx is not None:
msg_split.insert(idx, text.decode("utf-8"))
commit.message = "\n".join(msg_split).encode("utf-8")
else:
commit.message = commit.message + b'\n' + text
def replace_in_commit_msg(match, replace):
commit.message = commit.message.decode("utf-8").replace(match, replace).encode("utf-8")
"""
const val RESET_CALLBACK = """
commit.committer_name = commit.author_name
commit.committer_email = commit.author_email
commit.committer_date = commit.author_date
"""
@Suppress("MemberVisibilityCanBePrivate")
const val COMMIT_MSG = """
insert_into_commit_msg(b'By: ' + commit.author_name + b' <' + commit.author_email + b'>')
replace_in_commit_msg("Co-authored-by:", "Also-by:")
"""
const val CRAFTBUKKIT_CALLBACK = """
$UTILS
$COMMIT_MSG
commit.author_name = b'CraftBukkit/Spigot'
commit.author_email = b'craftbukkit.spigot@github.com'
$RESET_CALLBACK
"""
const val BUKKIT_CALLBACK = """
$UTILS
$COMMIT_MSG
commit.author_name = b'Bukkit/Spigot'
commit.author_email = b'bukkit.spigot@github.com'
$RESET_CALLBACK
"""
private const val MOVE_BACK_CALLBACK = """
$UTILS
import time
date = commit.author_date.decode('utf-8').split(' ')
commit.author_date = f'{int(date[0]) - 500000000} {date[1]}'.encode('utf-8')
insert_into_commit_msg(b'Original-Date: ' + time.ctime(int(date[0])).encode("utf-8"))
"""
const val PAPER_CALLBACK = """
msg = commit.message.decode('utf-8')
author = commit.author_email.decode('utf-8')
if author == 'aikar@aikar.co' and (msg.startswith('[CI-SKIP] [Auto]') or msg.startswith('[Auto]')):
commit.author_name = b'Automated'
commit.author_email = b'auto@mated.null'
$MOVE_BACK_CALLBACK
$RESET_CALLBACK
"""
}
@get:InputDirectory
abstract val targetDir: DirectoryProperty
@get:Input
abstract val paths: ListProperty<String>
@get:Input
abstract val pathGlobs: ListProperty<String>
@get:Input
abstract val commitCallback: Property<String>
@get:OutputDirectory
abstract val outputDir: DirectoryProperty
override fun init() {
group = "mm"
outputDir.convention(targetDir)
paths.convention(objects.listProperty())
pathGlobs.convention(objects.listProperty())
commitCallback.convention(RESET_CALLBACK)
}
@TaskAction
fun run() {
Git.checkForGit()
val pathsArr = paths.get().map { "--path=$it" }.toTypedArray()
val pathGlobsArr = pathGlobs.get().map { "--path-glob=$it" }.toTypedArray()
Git(targetDir)("filter-repo", *pathsArr, *pathGlobsArr, "--force", "--commit-callback", commitCallback.get()).executeOut()
}
}

View file

@ -38,6 +38,7 @@ object McDev {
decompJar: Path,
importsFile: Path?,
targetDir: Path,
secondaryLibraryTargetDir: Path? = null,
dataTargetDir: Path? = null,
librariesDirs: List<Path> = listOf(),
printOutput: Boolean = true
@ -134,16 +135,16 @@ object McDev {
val libFile = libFiles.firstOrNull { it.name == libraryFileName }
?: throw PaperweightException("Failed to find library: $libraryFileName for class $importFilePath")
val outputFile = targetDir.resolve(importFilePath)
if (outputFile.exists()) {
continue
}
outputFile.parent.createDirectories()
listOf(targetDir, secondaryLibraryTargetDir).mapNotNull { it?.resolve(importFilePath) }
.filter { it.notExists() }
.forEach { outputFile ->
outputFile.parent.createDirectories()
libFile.openZip().use { zipFile ->
val libEntry = zipFile.getPath(importFilePath)
libEntry.copyTo(outputFile)
}
libFile.openZip().use { zipFile ->
val libEntry = zipFile.getPath(importFilePath)
libEntry.copyTo(outputFile)
}
}
}
}
@ -170,7 +171,7 @@ object McDev {
}
}
private fun readPatchLines(patches: Iterable<Path>): Pair<Set<String>, Set<String>> {
fun readPatchLines(patches: Iterable<Path>): Pair<Set<String>, Set<String>> {
val srcResult = hashSetOf<String>()
val dataResult = hashSetOf<String>()

View file

@ -117,6 +117,20 @@ const val MC_DEV_SOURCES_DIR = "$PAPER_PATH/mc-dev-sources"
const val IVY_REPOSITORY = "$PAPER_PATH/ivyRepository"
const val MM = "$PAPER_PATH/mm"
const val INITIAL_PATCHES = "$MM/initial-patches"
const val INITIAL_PAPER_PATCHES = "$INITIAL_PATCHES/paper"
const val SPIGOT_DECOMPILER_MOJMAP_SRC_WRK = "$MM/spigotDecompilerMojmapSourceWork"
const val SPIGOT_DECOMPILER_MOJMAP_SRC = "$MM/spigotDecompilerMojmapSource"
const val UNMAPPED_CB_SOURCE_COPY = "$MM/unmappedCbSourceCopy"
const val UNMAPPED_CB_SOURCE_WORK = "$MM/unmappedCbSourceWork"
const val REMAPPED_CB_SPIGOT_SOURCE_WORK = "$MM/remappedCbSpigotSourceWork"
const val PAPER_DECOMPILED_SOURCE_FOLDER = "$MM/decompiled"
const val SPIGOT_DECOMPILED_JAR_SRC = "$MM/spigotDecompiledJar"
const val PATCHES_DIR = "patches"
const val SOURCE_PATCHES = "$PATCHES_DIR/sources"
const val DATA_PATCHES = "$PATCHES_DIR/resources"
const val DOWNLOAD_SERVICE_NAME = "paperweightDownloadService"
fun paperSetupOutput(name: String, ext: String) = "$SETUP_CACHE/$name.$ext"

View file

@ -111,7 +111,7 @@ private fun Path.fixWindowsPermissionsForDeletion() {
}
}
fun Path.copyRecursivelyTo(target: Path) {
fun Path.copyRecursivelyTo(target: Path, overwrite: Boolean = false) {
target.createDirectories()
if (!exists()) {
return
@ -122,7 +122,7 @@ fun Path.copyRecursivelyTo(target: Path) {
if (f.isDirectory()) {
targetPath.createDirectories()
} else {
f.copyTo(targetPath)
f.copyTo(targetPath, overwrite)
}
}
}
@ -248,6 +248,10 @@ fun relativeMove(baseDir: Path, file: Path, outputDir: Path) {
relativeCopyOrMove(baseDir, file, outputDir, true)
}
fun javaFileName(rootDir: Path, file: Path): String {
return file.relativeTo(rootDir).toString().replaceAfterLast('.', "java")
}
private fun relativeCopyOrMove(baseDir: Path, file: Path, outputDir: Path, move: Boolean) {
val destination = outputDir.resolve(file.relativeTo(baseDir).invariantSeparatorsPathString)
destination.parent.createDirectories()

View file

@ -105,7 +105,7 @@ class Git(private val repo: Path, private val env: Map<String, String> = emptyMa
}
}
class Command(private val processBuilder: ProcessBuilder, private val command: String) {
class Command(private val processBuilder: ProcessBuilder, private val command: String, private val validExitCodes: Array<Int> = arrayOf(0)) {
private var outStream: OutputStream = UselessOutputStream
private var errStream: OutputStream = UselessOutputStream
@ -115,7 +115,7 @@ class Command(private val processBuilder: ProcessBuilder, private val command: S
// Override all settings for debug
setup(DelegatingOutputStream(outStream, System.out), DelegatingOutputStream(errStream, System.err))
println()
println("$ (pwd) ${processBuilder.directory().absolutePath}")
println("$ (pwd) ${processBuilder.directory()?.absolutePath}")
println("$ $command")
}
try {
@ -159,7 +159,7 @@ class Command(private val processBuilder: ProcessBuilder, private val command: S
fun execute() {
val res = run()
if (res != 0) {
if (res !in validExitCodes) {
throw PaperweightException("Command finished with $res exit code: $command")
}
}

View file

@ -95,6 +95,7 @@ val ProjectLayout.cache: Path
get() = projectDirectory.dir(".gradle/$CACHE_PATH").path
fun ProjectLayout.cacheDir(path: String) = projectDirectory.dir(".gradle/$CACHE_PATH").dir(path)
fun ProjectLayout.cacheFile(path: String) = projectDirectory.dir(".gradle/$CACHE_PATH").file(path)
fun ProjectLayout.maybeInitSubmodules(offline: Boolean, logger: Logger) {
if (offline) {
@ -112,6 +113,12 @@ fun ProjectLayout.initSubmodules() {
fun Project.offlineMode(): Boolean = gradle.startParameter.isOffline
fun ProjectLayout.resetSubmodules() {
Git.checkForGit()
Git(projectDirectory.path)("submodule", "deinit", "-f", ".").executeOut()
initSubmodules()
}
fun <T : FileSystemLocation> Provider<out T>.fileExists(project: Project): Provider<out T?> {
return flatMap { project.provider { it.takeIf { f -> f.path.exists() } } }
}