Make patched file filtering incremental & compile against filtered jar (#237)
* Make patched file filtering incremental This makes it more reasonable to compile against * Compile against the filtered jar * Add missing `$` to inner class glob patterns * Fix base path being split by collection add function
This commit is contained in:
parent
8c3c62d89d
commit
754562481d
3 changed files with 163 additions and 96 deletions
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project.
|
||||
*
|
||||
* Copyright (c) 2023 Kyle Wood (DenWav)
|
||||
* Contributors
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 only, no later versions.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.*
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.stream.Collectors
|
||||
import kotlin.io.path.*
|
||||
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.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.work.ChangeType
|
||||
import org.gradle.work.Incremental
|
||||
import org.gradle.work.InputChanges
|
||||
|
||||
abstract class FilterPatchedFiles : BaseTask() {
|
||||
|
||||
@get:InputDirectory
|
||||
@get:Incremental
|
||||
abstract val inputSrcDir: DirectoryProperty
|
||||
|
||||
@get:InputDirectory
|
||||
@get:Incremental
|
||||
abstract val inputResourcesDir: DirectoryProperty
|
||||
|
||||
@get:InputFile
|
||||
abstract val vanillaJar: RegularFileProperty
|
||||
|
||||
@get:OutputFile
|
||||
abstract val outputJar: RegularFileProperty
|
||||
|
||||
override fun init() {
|
||||
outputJar.convention(defaultOutput())
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run(changes: InputChanges) {
|
||||
if (!changes.isIncremental) {
|
||||
return runFull()
|
||||
}
|
||||
val srcAdded = changes.added(inputSrcDir)
|
||||
val srcRemoved = changes.removed(inputSrcDir)
|
||||
val resourceAdded = changes.added(inputResourcesDir)
|
||||
val resourceRemoved = changes.removed(inputResourcesDir)
|
||||
if (srcAdded.isEmpty() && srcRemoved.isEmpty() && resourceAdded.isEmpty() && resourceRemoved.isEmpty()) {
|
||||
logger.info("No adds or removes, not doing work.")
|
||||
didWork = false
|
||||
return
|
||||
}
|
||||
vanillaJar.path.openZip().use { vanillaFs ->
|
||||
val vanillaRoot = vanillaFs.rootDirectories.single()
|
||||
outputJar.path.openZip().use { outputFs ->
|
||||
val outputRoot = outputFs.rootDirectories.single()
|
||||
|
||||
for (add in resourceAdded) {
|
||||
if (vanillaRoot.resolve(add).exists()) {
|
||||
outputRoot.resolve(add).deleteIfExists()
|
||||
}
|
||||
}
|
||||
for (del in resourceRemoved) {
|
||||
val vanilla = vanillaRoot.resolve(del)
|
||||
if (vanilla.exists()) {
|
||||
val out = outputRoot.resolve(del)
|
||||
out.parent.createDirectories()
|
||||
out.deleteIfExists()
|
||||
vanilla.copyTo(out)
|
||||
}
|
||||
}
|
||||
|
||||
for (add in srcAdded) {
|
||||
val p = add.removeSuffix(".java") + ".class"
|
||||
val vanilla = vanillaRoot.resolve(p)
|
||||
if (vanilla.exists()) {
|
||||
val outFile = outputRoot.resolve(p)
|
||||
val outDir = outFile.parent
|
||||
val paths = outDir.listDirectoryEntries("${vanilla.name.removeSuffix(".class")}$*.class").toMutableList()
|
||||
paths.add(outFile)
|
||||
paths.forEach { it.deleteIfExists() }
|
||||
}
|
||||
}
|
||||
for (del in srcRemoved) {
|
||||
val p = del.removeSuffix(".java") + ".class"
|
||||
val vanillaFile = vanillaRoot.resolve(p)
|
||||
if (vanillaFile.exists()) {
|
||||
val paths = vanillaFile.parent.listDirectoryEntries("${vanillaFile.name.removeSuffix(".class")}$*.class").toMutableList()
|
||||
paths.add(vanillaFile)
|
||||
paths.forEach {
|
||||
val out = outputRoot.resolve(it.relativeTo(vanillaRoot))
|
||||
out.parent.createDirectories()
|
||||
out.deleteIfExists()
|
||||
it.copyTo(out)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun runFull() {
|
||||
val srcFiles = collectFiles(inputSrcDir.path)
|
||||
val resourceFiles = collectFiles(inputResourcesDir.path)
|
||||
filterJar(
|
||||
vanillaJar.path,
|
||||
outputJar.path,
|
||||
listOf()
|
||||
) {
|
||||
if (!it.isRegularFile()) {
|
||||
false
|
||||
} else if (it.nameCount > 1) {
|
||||
val path = it.subpath(0, it.nameCount - 1).resolve(it.fileName.toString().split("$")[0].removeSuffix(".class")).toString()
|
||||
!srcFiles.contains("$path.java") && !resourceFiles.contains(path)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun collectFiles(dir: Path): Set<String> {
|
||||
return Files.walk(dir).use { stream ->
|
||||
stream.filter { it.isRegularFile() }
|
||||
.map { it.relativeTo(dir).invariantSeparatorsPathString }
|
||||
.collect(Collectors.toUnmodifiableSet())
|
||||
}
|
||||
}
|
||||
|
||||
private fun InputChanges.added(baseDir: DirectoryProperty): Set<String> {
|
||||
return getFileChanges(baseDir).filter { it.changeType == ChangeType.ADDED }
|
||||
.map { it.file.toPath().relativeTo(baseDir.path).invariantSeparatorsPathString }
|
||||
.toSet()
|
||||
}
|
||||
|
||||
private fun InputChanges.removed(baseDir: DirectoryProperty): Set<String> {
|
||||
return getFileChanges(baseDir).filter { it.changeType == ChangeType.REMOVED }
|
||||
.map { it.file.toPath().relativeTo(baseDir.path).invariantSeparatorsPathString }
|
||||
.toSet()
|
||||
}
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
* paperweight is a Gradle plugin for the PaperMC project.
|
||||
*
|
||||
* Copyright (c) 2023 Kyle Wood (DenWav)
|
||||
* Contributors
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 only, no later versions.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
|
||||
* USA
|
||||
*/
|
||||
|
||||
package io.papermc.paperweight.tasks
|
||||
|
||||
import io.papermc.paperweight.util.*
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.stream.Collectors
|
||||
import kotlin.io.path.*
|
||||
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.OutputFile
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
||||
abstract class FilterProjectDir : BaseTask() {
|
||||
|
||||
@get:InputDirectory
|
||||
abstract val inputSrcDir: DirectoryProperty
|
||||
|
||||
@get:InputDirectory
|
||||
abstract val inputResourcesDir: DirectoryProperty
|
||||
|
||||
@get:InputFile
|
||||
abstract val vanillaJar: RegularFileProperty
|
||||
|
||||
@get:OutputFile
|
||||
abstract val outputJar: RegularFileProperty
|
||||
|
||||
override fun init() {
|
||||
outputJar.convention(defaultOutput())
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun run() {
|
||||
val output = outputJar.path
|
||||
val target = output.resolveSibling("${output.name}.dir")
|
||||
target.createDirectories()
|
||||
|
||||
vanillaJar.path.openZip().use { zip ->
|
||||
val srcFiles = collectFiles(inputSrcDir.path)
|
||||
val resourceFiles = collectFiles(inputResourcesDir.path)
|
||||
|
||||
zip.walk().use { stream ->
|
||||
stream
|
||||
.filter { it.isRegularFile() }
|
||||
.filter {
|
||||
if (it.nameCount > 1) {
|
||||
val path = it.subpath(0, it.nameCount - 1).resolve(it.fileName.toString().split("$")[0].removeSuffix(".class")).toString()
|
||||
!srcFiles.contains("$path.java") && !resourceFiles.contains(path)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
}.forEach { f ->
|
||||
val targetFile = target.resolve(f.invariantSeparatorsPathString.substring(1))
|
||||
targetFile.parent.createDirectories()
|
||||
f.copyTo(targetFile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zip(target, output)
|
||||
target.deleteRecursive()
|
||||
}
|
||||
|
||||
private fun collectFiles(dir: Path): Set<String> {
|
||||
return Files.walk(dir).use { stream ->
|
||||
stream.filter { it.isRegularFile() }
|
||||
.map { it.relativeTo(dir).invariantSeparatorsPathString }
|
||||
.collect(Collectors.toUnmodifiableSet())
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,7 +61,7 @@ fun Project.setupServerProject(
|
|||
exportRuntimeClasspathTo(parent)
|
||||
|
||||
@Suppress("UNUSED_VARIABLE", "KotlinRedundantDiagnosticSuppress")
|
||||
val filterProjectDir by tasks.registering<FilterProjectDir> {
|
||||
val filterPatchedFiles by tasks.registering<FilterPatchedFiles> {
|
||||
inputSrcDir.set(file("src/main/java"))
|
||||
inputResourcesDir.set(file("src/main/resources"))
|
||||
vanillaJar.set(
|
||||
|
@ -82,7 +82,7 @@ fun Project.setupServerProject(
|
|||
layout.projectDirectory.path
|
||||
)
|
||||
|
||||
add(create(parent.files(remappedJar)))
|
||||
add(create(parent.files(filterPatchedFiles.flatMap { it.outputJar })))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue