Compare commits
5 commits
main
...
softspoon-
Author | SHA1 | Date | |
---|---|---|---|
|
aa75f2bbcf | ||
|
005e051b3c | ||
|
d569f38cef | ||
|
4564fe8a2d | ||
|
2d425efdef |
100 changed files with 3346 additions and 76 deletions
|
@ -83,3 +83,9 @@ ij_kotlin_field_annotation_wrap = split_into_lines
|
||||||
ij_kotlin_finally_on_new_line = false
|
ij_kotlin_finally_on_new_line = false
|
||||||
ij_kotlin_if_rparen_on_new_line = true
|
ij_kotlin_if_rparen_on_new_line = true
|
||||||
ij_kotlin_import_nested_classes = false
|
ij_kotlin_import_nested_classes = false
|
||||||
|
|
||||||
|
[*.patch]
|
||||||
|
trim_trailing_whitespace=false
|
||||||
|
|
||||||
|
[*.patch]
|
||||||
|
trim_trailing_whitespace=false
|
||||||
|
|
4
.github/workflows/deploy-snapshot.yml
vendored
4
.github/workflows/deploy-snapshot.yml
vendored
|
@ -1,7 +1,7 @@
|
||||||
name: Deploy Snapshot
|
name: Deploy Snapshot
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches: [ 'main' ]
|
branches: [ 'main', 'softspoon-v2' ]
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- 'license/*'
|
- 'license/*'
|
||||||
- 'readme.md'
|
- 'readme.md'
|
||||||
|
@ -29,7 +29,7 @@ jobs:
|
||||||
echo version=$project_version >> $GITHUB_OUTPUT
|
echo version=$project_version >> $GITHUB_OUTPUT
|
||||||
- name: Deploy snapshot version
|
- name: Deploy snapshot version
|
||||||
if: endsWith(steps.get_version.outputs.version, '-SNAPSHOT')
|
if: endsWith(steps.get_version.outputs.version, '-SNAPSHOT')
|
||||||
run: ./gradlew -Dorg.gradle.parallel=true publish --no-daemon --stacktrace
|
run: ./gradlew -Dorg.gradle.parallel=true publish --no-daemon --stacktrace -Dorg.gradle.internal.http.socketTimeout=90000 -Dorg.gradle.internal.http.connectionTimeout=90000
|
||||||
env:
|
env:
|
||||||
ORG_GRADLE_PROJECT_paperUsername: ${{ secrets.DEPLOY_USER }}
|
ORG_GRADLE_PROJECT_paperUsername: ${{ secrets.DEPLOY_USER }}
|
||||||
ORG_GRADLE_PROJECT_paperPassword: ${{ secrets.DEPLOY_PASS }}
|
ORG_GRADLE_PROJECT_paperPassword: ${{ secrets.DEPLOY_PASS }}
|
||||||
|
|
12
.github/workflows/test.yml
vendored
12
.github/workflows/test.yml
vendored
|
@ -19,4 +19,14 @@ jobs:
|
||||||
- name: Setup Gradle
|
- name: Setup Gradle
|
||||||
uses: gradle/gradle-build-action@v2
|
uses: gradle/gradle-build-action@v2
|
||||||
- name: Execute Gradle build
|
- name: Execute Gradle build
|
||||||
run: ./gradlew build --no-daemon --stacktrace
|
run: |
|
||||||
|
git config --global user.email "no-reply@github.com"
|
||||||
|
git config --global user.name "GitHub Actions"
|
||||||
|
./gradlew build --no-daemon --stacktrace
|
||||||
|
- name: Publish Test Report
|
||||||
|
uses: mikepenz/action-junit-report@v4
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
report_paths: '**/build/test-results/test/TEST-*.xml'
|
||||||
|
detailed_summary: true
|
||||||
|
annotate_notice: true
|
||||||
|
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -43,3 +43,8 @@ ehthumbs_vista.db
|
||||||
|
|
||||||
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
|
||||||
!gradle-wrapper.ja
|
!gradle-wrapper.ja
|
||||||
|
|
||||||
|
/test/
|
||||||
|
/testpaper/
|
||||||
|
/testfork/
|
||||||
|
/testhistory/
|
||||||
|
|
|
@ -11,7 +11,7 @@ java {
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType(JavaCompile::class).configureEach {
|
tasks.withType(JavaCompile::class).configureEach {
|
||||||
options.release = 11
|
options.release = 17
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
@ -21,14 +21,15 @@ kotlin {
|
||||||
target {
|
target {
|
||||||
compilations.configureEach {
|
compilations.configureEach {
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = "11"
|
jvmTarget = "17"
|
||||||
freeCompilerArgs = listOf("-Xjvm-default=all", "-Xjdk-release=11")
|
freeCompilerArgs = listOf("-Xjvm-default=all", "-Xjdk-release=17", "-opt-in=kotlin.io.path.ExperimentalPathApi")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
mavenLocal() // TODO remove again
|
||||||
maven("https://repo.papermc.io/repository/maven-snapshots/") {
|
maven("https://repo.papermc.io/repository/maven-snapshots/") {
|
||||||
mavenContent {
|
mavenContent {
|
||||||
includeModule("org.cadixdev", "mercury")
|
includeModule("org.cadixdev", "mercury")
|
||||||
|
@ -38,6 +39,28 @@ repositories {
|
||||||
mavenContent {
|
mavenContent {
|
||||||
includeGroup("codechicken")
|
includeGroup("codechicken")
|
||||||
includeGroup("net.fabricmc")
|
includeGroup("net.fabricmc")
|
||||||
|
includeGroupAndSubgroups("io.papermc")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maven("https://maven.parchmentmc.org") {
|
||||||
|
name = "ParchmentMC"
|
||||||
|
mavenContent {
|
||||||
|
releasesOnly()
|
||||||
|
includeGroupAndSubgroups("org.parchmentmc")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maven("https://maven.neoforged.net/releases") {
|
||||||
|
name = "NeoForged"
|
||||||
|
mavenContent {
|
||||||
|
releasesOnly()
|
||||||
|
includeGroupAndSubgroups("net.neoforged")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maven("https://maven.fabricmc.net") {
|
||||||
|
name = "FabricMC"
|
||||||
|
mavenContent {
|
||||||
|
releasesOnly()
|
||||||
|
includeGroupAndSubgroups("net.fabricmc")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
@ -55,6 +78,7 @@ testing {
|
||||||
useKotlinTest(embeddedKotlinVersion)
|
useKotlinTest(embeddedKotlinVersion)
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.junit.jupiter:junit-jupiter-engine:5.10.1")
|
implementation("org.junit.jupiter:junit-jupiter-engine:5.10.1")
|
||||||
|
implementation("org.junit.platform:junit-platform-launcher:1.10.1")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
group = io.papermc.paperweight
|
group = io.papermc.paperweight
|
||||||
version = 1.7.2-SNAPSHOT
|
version = 2.0.0-SNAPSHOT
|
||||||
|
|
||||||
org.gradle.caching = true
|
org.gradle.caching = true
|
||||||
org.gradle.parallel = true
|
org.gradle.parallel = true
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
[versions]
|
[versions]
|
||||||
asm = "9.7"
|
asm = "9.7"
|
||||||
lorenz = "0.5.8"
|
lorenz = "0.5.8"
|
||||||
hypo = "1.2.4"
|
hypo = "2.3.0"
|
||||||
|
serialize = "1.5.1"
|
||||||
|
feather = "1.1.0"
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
asm-core = { module = "org.ow2.asm:asm", version.ref = "asm" }
|
asm-core = { module = "org.ow2.asm:asm", version.ref = "asm" }
|
||||||
|
@ -9,6 +11,8 @@ asm-tree = { module = "org.ow2.asm:asm-tree", version.ref = "asm" }
|
||||||
|
|
||||||
httpclient = "org.apache.httpcomponents:httpclient:4.5.14"
|
httpclient = "org.apache.httpcomponents:httpclient:4.5.14"
|
||||||
kotson = "com.github.salomonbrys.kotson:kotson:2.5.0"
|
kotson = "com.github.salomonbrys.kotson:kotson:2.5.0"
|
||||||
|
coroutines = "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.2"
|
||||||
|
jgit = "org.eclipse.jgit:org.eclipse.jgit:6.6.0.202305301015-r"
|
||||||
gson = "com.google.code.gson:gson:2.10.1"
|
gson = "com.google.code.gson:gson:2.10.1"
|
||||||
|
|
||||||
cadix-lorenz-core = { module = "org.cadixdev:lorenz", version.ref = "lorenz" }
|
cadix-lorenz-core = { module = "org.cadixdev:lorenz", version.ref = "lorenz" }
|
||||||
|
@ -16,7 +20,9 @@ cadix-lorenz-asm = { module = "org.cadixdev:lorenz-asm", version.ref = "lorenz"
|
||||||
cadix-lorenz-proguard = { module = "org.cadixdev:lorenz-io-proguard", version.ref = "lorenz" }
|
cadix-lorenz-proguard = { module = "org.cadixdev:lorenz-io-proguard", version.ref = "lorenz" }
|
||||||
cadix-atlas = "org.cadixdev:atlas:0.2.1"
|
cadix-atlas = "org.cadixdev:atlas:0.2.1"
|
||||||
cadix-at = "org.cadixdev:at:0.1.0-rc1"
|
cadix-at = "org.cadixdev:at:0.1.0-rc1"
|
||||||
|
#cadix-mercury = "org.cadixdev:mercury:0.1.2-paperweight-local-SNAPSHOT" # todo local mods for patch remapping
|
||||||
cadix-mercury = "org.cadixdev:mercury:0.1.2-paperweight-SNAPSHOT"
|
cadix-mercury = "org.cadixdev:mercury:0.1.2-paperweight-SNAPSHOT"
|
||||||
|
cadix-bombe-jar = "org.cadixdev:bombe-jar:0.4.4"
|
||||||
|
|
||||||
hypo-model = { module = "dev.denwav.hypo:hypo-model", version.ref = "hypo" }
|
hypo-model = { module = "dev.denwav.hypo:hypo-model", version.ref = "hypo" }
|
||||||
hypo-core = { module = "dev.denwav.hypo:hypo-core", version.ref = "hypo" }
|
hypo-core = { module = "dev.denwav.hypo:hypo-core", version.ref = "hypo" }
|
||||||
|
@ -29,7 +35,18 @@ slf4j-jdk14 = "org.slf4j:slf4j-jdk14:1.7.32"
|
||||||
lorenzTiny = "net.fabricmc:lorenz-tiny:3.0.0"
|
lorenzTiny = "net.fabricmc:lorenz-tiny:3.0.0"
|
||||||
jbsdiff = "io.sigpipe:jbsdiff:1.0"
|
jbsdiff = "io.sigpipe:jbsdiff:1.0"
|
||||||
|
|
||||||
diffpatch = "codechicken:DiffPatch:1.5.0.29"
|
feather-core = { module = "org.parchmentmc:feather", version.ref = "feather" }
|
||||||
|
feather-gson = { module = "org.parchmentmc.feather:io-gson", version.ref = "feather" }
|
||||||
|
|
||||||
|
diffpatch = "codechicken:DiffPatch:1.5.0.30"
|
||||||
|
|
||||||
|
serialize-core = { module = "org.jetbrains.kotlinx:kotlinx-serialization-core", version.ref = "serialize" }
|
||||||
|
serialize-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialize" }
|
||||||
|
|
||||||
|
restamp = "io.papermc.restamp:restamp:1.1.1-SNAPSHOT"
|
||||||
|
|
||||||
|
# test
|
||||||
|
mockk = "io.mockk:mockk:1.13.8"
|
||||||
|
|
||||||
# Gradle
|
# Gradle
|
||||||
gradle-licenser = "net.kyori:indra-licenser-spotless:3.1.3"
|
gradle-licenser = "net.kyori:indra-licenser-spotless:3.1.3"
|
||||||
|
@ -41,6 +58,6 @@ gradle-plugin-publish = "com.gradle.publish:plugin-publish-plugin:1.2.1"
|
||||||
|
|
||||||
[bundles]
|
[bundles]
|
||||||
asm = ["asm-core", "asm-tree"]
|
asm = ["asm-core", "asm-tree"]
|
||||||
cadix = ["cadix-lorenz-core", "cadix-lorenz-asm", "cadix-lorenz-proguard", "cadix-atlas", "cadix-at", "cadix-mercury"]
|
cadix = ["cadix-lorenz-core", "cadix-lorenz-asm", "cadix-lorenz-proguard", "cadix-atlas", "cadix-at", "cadix-mercury", "cadix-bombe-jar"]
|
||||||
hypo = ["hypo-model", "hypo-core", "hypo-hydrate", "hypo-asm-core", "hypo-asm-hydrate", "hypo-mappings"]
|
hypo = ["hypo-model", "hypo-core", "hypo-hydrate", "hypo-asm-core", "hypo-asm-hydrate", "hypo-mappings"]
|
||||||
kotson = ["kotson", "gson"]
|
kotson = ["kotson", "gson"]
|
||||||
|
|
|
@ -7,6 +7,7 @@ dependencies {
|
||||||
shade(projects.paperweightLib)
|
shade(projects.paperweightLib)
|
||||||
|
|
||||||
implementation(libs.bundles.kotson)
|
implementation(libs.bundles.kotson)
|
||||||
|
implementation(libs.coroutines)
|
||||||
}
|
}
|
||||||
|
|
||||||
gradlePlugin {
|
gradlePlugin {
|
||||||
|
|
|
@ -25,6 +25,7 @@ package io.papermc.paperweight.core
|
||||||
import io.papermc.paperweight.DownloadService
|
import io.papermc.paperweight.DownloadService
|
||||||
import io.papermc.paperweight.core.extension.PaperweightCoreExtension
|
import io.papermc.paperweight.core.extension.PaperweightCoreExtension
|
||||||
import io.papermc.paperweight.core.taskcontainers.AllTasks
|
import io.papermc.paperweight.core.taskcontainers.AllTasks
|
||||||
|
import io.papermc.paperweight.core.taskcontainers.SoftSpoonTasks
|
||||||
import io.papermc.paperweight.core.tasks.PaperweightCorePrepareForDownstream
|
import io.papermc.paperweight.core.tasks.PaperweightCorePrepareForDownstream
|
||||||
import io.papermc.paperweight.taskcontainers.BundlerJarTasks
|
import io.papermc.paperweight.taskcontainers.BundlerJarTasks
|
||||||
import io.papermc.paperweight.taskcontainers.DevBundleTasks
|
import io.papermc.paperweight.taskcontainers.DevBundleTasks
|
||||||
|
@ -53,7 +54,9 @@ class PaperweightCore : Plugin<Project> {
|
||||||
|
|
||||||
val ext = target.extensions.create(PAPERWEIGHT_EXTENSION, PaperweightCoreExtension::class, target)
|
val ext = target.extensions.create(PAPERWEIGHT_EXTENSION, PaperweightCoreExtension::class, target)
|
||||||
|
|
||||||
target.gradle.sharedServices.registerIfAbsent(DOWNLOAD_SERVICE_NAME, DownloadService::class) {}
|
target.gradle.sharedServices.registerIfAbsent(DOWNLOAD_SERVICE_NAME, DownloadService::class) {
|
||||||
|
parameters.projectPath.set(target.projectDir)
|
||||||
|
}
|
||||||
|
|
||||||
target.tasks.register<Delete>("cleanCache") {
|
target.tasks.register<Delete>("cleanCache") {
|
||||||
group = "paper"
|
group = "paper"
|
||||||
|
@ -69,6 +72,7 @@ class PaperweightCore : Plugin<Project> {
|
||||||
target.configurations.create(REMAPPER_CONFIG)
|
target.configurations.create(REMAPPER_CONFIG)
|
||||||
target.configurations.create(DECOMPILER_CONFIG)
|
target.configurations.create(DECOMPILER_CONFIG)
|
||||||
target.configurations.create(PAPERCLIP_CONFIG)
|
target.configurations.create(PAPERCLIP_CONFIG)
|
||||||
|
target.configurations.create(MACHE_CONFIG)
|
||||||
|
|
||||||
if (target.providers.gradleProperty("paperweight.dev").orNull == "true") {
|
if (target.providers.gradleProperty("paperweight.dev").orNull == "true") {
|
||||||
target.tasks.register<CreateDiffOutput>("diff") {
|
target.tasks.register<CreateDiffOutput>("diff") {
|
||||||
|
@ -90,10 +94,12 @@ class PaperweightCore : Plugin<Project> {
|
||||||
ext.mainClass
|
ext.mainClass
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val softSpoonTasks = SoftSpoonTasks(target, tasks)
|
||||||
|
|
||||||
target.createPatchRemapTask(tasks)
|
target.createPatchRemapTask(tasks)
|
||||||
|
|
||||||
target.tasks.register<PaperweightCorePrepareForDownstream>(PAPERWEIGHT_PREPARE_DOWNSTREAM) {
|
target.tasks.register<PaperweightCorePrepareForDownstream>(PAPERWEIGHT_PREPARE_DOWNSTREAM) {
|
||||||
dependsOn(tasks.applyPatches)
|
dependsOn(tasks.applyPatchesLegacy)
|
||||||
vanillaJar.set(tasks.downloadServerJar.flatMap { it.outputJar })
|
vanillaJar.set(tasks.downloadServerJar.flatMap { it.outputJar })
|
||||||
remappedJar.set(tasks.lineMapJar.flatMap { it.outputJar })
|
remappedJar.set(tasks.lineMapJar.flatMap { it.outputJar })
|
||||||
decompiledJar.set(tasks.decompileJar.flatMap { it.outputJar })
|
decompiledJar.set(tasks.decompileJar.flatMap { it.outputJar })
|
||||||
|
@ -124,21 +130,35 @@ class PaperweightCore : Plugin<Project> {
|
||||||
}
|
}
|
||||||
|
|
||||||
target.afterEvaluate {
|
target.afterEvaluate {
|
||||||
|
println("SoftSpoon: ${ext.softSpoon.get()}")
|
||||||
|
|
||||||
target.repositories {
|
target.repositories {
|
||||||
maven(ext.paramMappingsRepo) {
|
if (!ext.softSpoon.get()) {
|
||||||
name = PARAM_MAPPINGS_REPO_NAME
|
maven(ext.paramMappingsRepo) {
|
||||||
content { onlyForConfigurations(PARAM_MAPPINGS_CONFIG) }
|
name = PARAM_MAPPINGS_REPO_NAME
|
||||||
}
|
content { onlyForConfigurations(PARAM_MAPPINGS_CONFIG) }
|
||||||
maven(ext.remapRepo) {
|
}
|
||||||
name = REMAPPER_REPO_NAME
|
maven(ext.remapRepo) {
|
||||||
content { onlyForConfigurations(REMAPPER_CONFIG) }
|
name = REMAPPER_REPO_NAME
|
||||||
}
|
content { onlyForConfigurations(REMAPPER_CONFIG) }
|
||||||
maven(ext.decompileRepo) {
|
}
|
||||||
name = DECOMPILER_REPO_NAME
|
maven(ext.decompileRepo) {
|
||||||
content { onlyForConfigurations(DECOMPILER_CONFIG) }
|
name = DECOMPILER_REPO_NAME
|
||||||
|
content { onlyForConfigurations(DECOMPILER_CONFIG) }
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
maven(ext.macheRepo) {
|
||||||
|
name = MACHE_REPO_NAME
|
||||||
|
content { onlyForConfigurations(MACHE_CONFIG) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ext.softSpoon.get()) {
|
||||||
|
softSpoonTasks.afterEvaluate()
|
||||||
|
return@afterEvaluate
|
||||||
|
}
|
||||||
|
|
||||||
// Setup the server jar
|
// Setup the server jar
|
||||||
val cache = target.layout.cache
|
val cache = target.layout.cache
|
||||||
|
|
||||||
|
|
|
@ -38,8 +38,11 @@ open class PaperExtension(objects: ObjectFactory, layout: ProjectLayout) {
|
||||||
val spigotServerPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "patches/server")
|
val spigotServerPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "patches/server")
|
||||||
val remappedSpigotServerPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "patches/server-remapped")
|
val remappedSpigotServerPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "patches/server-remapped")
|
||||||
val unmappedSpigotServerPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "patches/server-unmapped")
|
val unmappedSpigotServerPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "patches/server-unmapped")
|
||||||
val paperApiDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "Paper-API")
|
val paperApiDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "paper-api")
|
||||||
val paperServerDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "Paper-Server")
|
val paperServerDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "paper-server")
|
||||||
|
val sourcePatchDir: DirectoryProperty = objects.dirFrom(paperServerDir, "patches/sources")
|
||||||
|
val resourcePatchDir: DirectoryProperty = objects.dirFrom(paperServerDir, "patches/resources")
|
||||||
|
val featurePatchDir: DirectoryProperty = objects.dirFrom(paperServerDir, "patches/feature")
|
||||||
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
val buildDataDir: DirectoryProperty = objects.dirWithDefault(layout, "build-data")
|
val buildDataDir: DirectoryProperty = objects.dirWithDefault(layout, "build-data")
|
||||||
|
|
|
@ -36,10 +36,13 @@ import org.gradle.kotlin.dsl.*
|
||||||
|
|
||||||
open class PaperweightCoreExtension(project: Project, objects: ObjectFactory, layout: ProjectLayout) {
|
open class PaperweightCoreExtension(project: Project, objects: ObjectFactory, layout: ProjectLayout) {
|
||||||
|
|
||||||
|
val softSpoon: Property<Boolean> = objects.property<Boolean>().convention(false)
|
||||||
|
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
val workDir: DirectoryProperty = objects.dirWithDefault(layout, "work")
|
val workDir: DirectoryProperty = objects.dirWithDefault(layout, "work")
|
||||||
|
|
||||||
val minecraftVersion: Property<String> = objects.property()
|
val minecraftVersion: Property<String> = objects.property()
|
||||||
|
val minecraftManifestUrl: Property<String> = objects.property<String>().convention(MC_MANIFEST_URL)
|
||||||
val serverProject: Property<Project> = objects.property()
|
val serverProject: Property<Project> = objects.property()
|
||||||
|
|
||||||
val mainClass: Property<String> = objects.property<String>().convention("org.bukkit.craftbukkit.Main")
|
val mainClass: Property<String> = objects.property<String>().convention("org.bukkit.craftbukkit.Main")
|
||||||
|
@ -50,6 +53,7 @@ open class PaperweightCoreExtension(project: Project, objects: ObjectFactory, la
|
||||||
val paramMappingsRepo: Property<String> = objects.property()
|
val paramMappingsRepo: Property<String> = objects.property()
|
||||||
val decompileRepo: Property<String> = objects.property()
|
val decompileRepo: Property<String> = objects.property()
|
||||||
val remapRepo: Property<String> = objects.property()
|
val remapRepo: Property<String> = objects.property()
|
||||||
|
val macheRepo: Property<String> = objects.property<String>().convention("https://repo.papermc.io/repository/maven-public/")
|
||||||
|
|
||||||
val vanillaJarIncludes: ListProperty<String> = objects.listProperty<String>().convention(
|
val vanillaJarIncludes: ListProperty<String> = objects.listProperty<String>().convention(
|
||||||
listOf("/*.class", "/net/minecraft/**", "/com/mojang/math/**")
|
listOf("/*.class", "/net/minecraft/**", "/com/mojang/math/**")
|
||||||
|
|
|
@ -101,6 +101,23 @@ open class AllTasks(
|
||||||
downloader.set(downloadService)
|
downloader.set(downloadService)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val downloadPaperLibrariesSources by tasks.registering<DownloadPaperLibraries> {
|
||||||
|
paperDependencies.set(
|
||||||
|
project.ext.serverProject.map { p ->
|
||||||
|
val configuration = p.configurations["implementation"]
|
||||||
|
configuration.isCanBeResolved = true
|
||||||
|
configuration.resolvedConfiguration.resolvedArtifacts.map {
|
||||||
|
"${it.moduleVersion.id.group}:${it.moduleVersion.id.name}:${it.moduleVersion.id.version}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
repositories.set(listOf(MAVEN_CENTRAL_URL, PAPER_MAVEN_REPO_URL))
|
||||||
|
outputDir.set(cache.resolve(PAPER_SOURCES_JARS_PATH))
|
||||||
|
sources.set(true)
|
||||||
|
|
||||||
|
downloader.set(downloadService)
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("DuplicatedCode")
|
@Suppress("DuplicatedCode")
|
||||||
val applyServerPatches by tasks.registering<ApplyPaperPatches> {
|
val applyServerPatches by tasks.registering<ApplyPaperPatches> {
|
||||||
group = "paper"
|
group = "paper"
|
||||||
|
@ -126,7 +143,7 @@ open class AllTasks(
|
||||||
mcDevSources.set(extension.mcDevSourceDir)
|
mcDevSources.set(extension.mcDevSourceDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
val applyPatches by tasks.registering<Task> {
|
val applyPatchesLegacy by tasks.registering<Task> {
|
||||||
group = "paper"
|
group = "paper"
|
||||||
description = "Set up the Paper development environment"
|
description = "Set up the Paper development environment"
|
||||||
dependsOn(applyApiPatches, applyServerPatches)
|
dependsOn(applyApiPatches, applyServerPatches)
|
||||||
|
@ -151,7 +168,7 @@ open class AllTasks(
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
val rebuildPatches by tasks.registering<Task> {
|
val rebuildPatchesLegacy by tasks.registering<Task> {
|
||||||
group = "paper"
|
group = "paper"
|
||||||
description = "Rebuilds patches to api and server"
|
description = "Rebuilds patches to api and server"
|
||||||
dependsOn(rebuildApiPatches, rebuildServerPatches)
|
dependsOn(rebuildApiPatches, rebuildServerPatches)
|
||||||
|
|
|
@ -45,7 +45,7 @@ open class InitialTasks(
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val downloadMcManifest by tasks.registering<DownloadTask> {
|
val downloadMcManifest by tasks.registering<DownloadTask> {
|
||||||
url.set(MC_MANIFEST_URL)
|
url.set(project.ext.minecraftManifestUrl)
|
||||||
outputFile.set(cache.resolve(MC_MANIFEST))
|
outputFile.set(cache.resolve(MC_MANIFEST))
|
||||||
|
|
||||||
doNotTrackState("The Minecraft manifest is a changing resource")
|
doNotTrackState("The Minecraft manifest is a changing resource")
|
||||||
|
@ -54,7 +54,7 @@ open class InitialTasks(
|
||||||
}
|
}
|
||||||
private val mcManifest = downloadMcManifest.flatMap { it.outputFile }.map { gson.fromJson<MinecraftManifest>(it) }
|
private val mcManifest = downloadMcManifest.flatMap { it.outputFile }.map { gson.fromJson<MinecraftManifest>(it) }
|
||||||
|
|
||||||
val downloadMcVersionManifest by tasks.registering<DownloadTask> {
|
val downloadMcVersionManifest by tasks.registering<CacheableDownloadTask> {
|
||||||
url.set(
|
url.set(
|
||||||
mcManifest.zip(extension.minecraftVersion) { manifest, version ->
|
mcManifest.zip(extension.minecraftVersion) { manifest, version ->
|
||||||
manifest.versions.first { it.id == version }.url
|
manifest.versions.first { it.id == version }.url
|
||||||
|
@ -71,7 +71,7 @@ open class InitialTasks(
|
||||||
}
|
}
|
||||||
private val versionManifest = downloadMcVersionManifest.flatMap { it.outputFile }.map { gson.fromJson<MinecraftVersionManifest>(it) }
|
private val versionManifest = downloadMcVersionManifest.flatMap { it.outputFile }.map { gson.fromJson<MinecraftVersionManifest>(it) }
|
||||||
|
|
||||||
val downloadMappings by tasks.registering<DownloadTask> {
|
val downloadMappings by tasks.registering<CacheableDownloadTask> {
|
||||||
url.set(versionManifest.map { version -> version.serverMappingsDownload().url })
|
url.set(versionManifest.map { version -> version.serverMappingsDownload().url })
|
||||||
expectedHash.set(versionManifest.map { version -> version.serverMappingsDownload().hash() })
|
expectedHash.set(versionManifest.map { version -> version.serverMappingsDownload().hash() })
|
||||||
outputFile.set(cache.resolve(SERVER_MAPPINGS))
|
outputFile.set(cache.resolve(SERVER_MAPPINGS))
|
||||||
|
@ -94,5 +94,6 @@ open class InitialTasks(
|
||||||
serverLibrariesList.set(cache.resolve(SERVER_LIBRARIES_LIST))
|
serverLibrariesList.set(cache.resolve(SERVER_LIBRARIES_LIST))
|
||||||
serverVersionsList.set(cache.resolve(SERVER_VERSIONS_LIST))
|
serverVersionsList.set(cache.resolve(SERVER_VERSIONS_LIST))
|
||||||
serverLibraryJars.set(cache.resolve(MINECRAFT_JARS_PATH))
|
serverLibraryJars.set(cache.resolve(MINECRAFT_JARS_PATH))
|
||||||
|
serverJar.set(cache.resolve(SERVER_JAR))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,344 @@
|
||||||
|
/*
|
||||||
|
* 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.core.taskcontainers
|
||||||
|
|
||||||
|
import io.papermc.paperweight.core.ext
|
||||||
|
import io.papermc.paperweight.tasks.*
|
||||||
|
import io.papermc.paperweight.tasks.mache.*
|
||||||
|
import io.papermc.paperweight.tasks.mache.RemapJar
|
||||||
|
import io.papermc.paperweight.tasks.softspoon.ApplyFeaturePatches
|
||||||
|
import io.papermc.paperweight.tasks.softspoon.ApplyFilePatches
|
||||||
|
import io.papermc.paperweight.tasks.softspoon.ApplyFilePatchesFuzzy
|
||||||
|
import io.papermc.paperweight.tasks.softspoon.RebuildFilePatches
|
||||||
|
import io.papermc.paperweight.util.*
|
||||||
|
import io.papermc.paperweight.util.constants.*
|
||||||
|
import io.papermc.paperweight.util.data.mache.*
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.*
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.Task
|
||||||
|
import org.gradle.api.plugins.JavaPlugin
|
||||||
|
import org.gradle.api.plugins.JavaPluginExtension
|
||||||
|
import org.gradle.api.tasks.SourceSet
|
||||||
|
import org.gradle.api.tasks.TaskContainer
|
||||||
|
import org.gradle.kotlin.dsl.*
|
||||||
|
|
||||||
|
open class SoftSpoonTasks(
|
||||||
|
val project: Project,
|
||||||
|
val allTasks: AllTasks,
|
||||||
|
tasks: TaskContainer = project.tasks
|
||||||
|
) {
|
||||||
|
|
||||||
|
lateinit var mache: MacheMeta
|
||||||
|
|
||||||
|
val macheCodebook by project.configurations.registering {
|
||||||
|
isTransitive = false
|
||||||
|
}
|
||||||
|
val macheRemapper by project.configurations.registering {
|
||||||
|
isTransitive = false
|
||||||
|
}
|
||||||
|
val macheDecompiler by project.configurations.registering {
|
||||||
|
isTransitive = false
|
||||||
|
}
|
||||||
|
val macheParamMappings by project.configurations.registering {
|
||||||
|
isTransitive = false
|
||||||
|
}
|
||||||
|
val macheConstants by project.configurations.registering {
|
||||||
|
isTransitive = false
|
||||||
|
}
|
||||||
|
val macheMinecraft by project.configurations.registering
|
||||||
|
val macheMinecraftExtended by project.configurations.registering
|
||||||
|
|
||||||
|
val macheRemapJar by tasks.registering(RemapJar::class) {
|
||||||
|
group = "mache"
|
||||||
|
serverJar.set(allTasks.extractFromBundler.flatMap { it.serverJar })
|
||||||
|
serverMappings.set(allTasks.downloadMappings.flatMap { it.outputFile })
|
||||||
|
|
||||||
|
remapperArgs.set(mache.remapperArgs)
|
||||||
|
codebookClasspath.from(macheCodebook)
|
||||||
|
minecraftClasspath.from(macheMinecraft)
|
||||||
|
remapperClasspath.from(macheRemapper)
|
||||||
|
paramMappings.from(macheParamMappings)
|
||||||
|
constants.from(macheConstants)
|
||||||
|
|
||||||
|
outputJar.set(layout.cache.resolve(FINAL_REMAPPED_CODEBOOK_JAR))
|
||||||
|
}
|
||||||
|
|
||||||
|
val macheDecompileJar by tasks.registering(DecompileJar::class) {
|
||||||
|
group = "mache"
|
||||||
|
inputJar.set(macheRemapJar.flatMap { it.outputJar })
|
||||||
|
decompilerArgs.set(mache.decompilerArgs)
|
||||||
|
|
||||||
|
minecraftClasspath.from(macheMinecraft)
|
||||||
|
decompiler.from(macheDecompiler)
|
||||||
|
|
||||||
|
outputJar.set(layout.cache.resolve(FINAL_DECOMPILE_JAR))
|
||||||
|
}
|
||||||
|
|
||||||
|
val collectAccessTransform by tasks.registering(CollectATsFromPatches::class) {
|
||||||
|
group = "mache"
|
||||||
|
|
||||||
|
patchDir.set(project.ext.paper.featurePatchDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
val mergeCollectedAts by tasks.registering<MergeAccessTransforms> {
|
||||||
|
firstFile.set(project.ext.paper.additionalAts.fileExists(project))
|
||||||
|
secondFile.set(collectAccessTransform.flatMap { it.outputFile })
|
||||||
|
}
|
||||||
|
|
||||||
|
val setupMacheSources by tasks.registering(SetupVanilla::class) {
|
||||||
|
group = "mache"
|
||||||
|
description = "Setup vanilla source dir (applying mache patches and paper ATs)."
|
||||||
|
|
||||||
|
mache.from(project.configurations.named(MACHE_CONFIG))
|
||||||
|
machePatches.set(layout.cache.resolve(PATCHES_FOLDER))
|
||||||
|
ats.set(mergeCollectedAts.flatMap { it.outputFile })
|
||||||
|
minecraftClasspath.from(macheMinecraft)
|
||||||
|
|
||||||
|
libraries.from(allTasks.downloadPaperLibrariesSources.flatMap { it.outputDir }, allTasks.downloadMcLibrariesSources.flatMap { it.outputDir })
|
||||||
|
paperPatches.from(project.ext.paper.sourcePatchDir, project.ext.paper.featurePatchDir)
|
||||||
|
devImports.set(project.ext.paper.devImports.fileExists(project))
|
||||||
|
|
||||||
|
inputFile.set(macheDecompileJar.flatMap { it.outputJar })
|
||||||
|
predicate.set { Files.isRegularFile(it) && it.toString().endsWith(".java") }
|
||||||
|
outputDir.set(layout.cache.resolve(BASE_PROJECT).resolve("sources"))
|
||||||
|
}
|
||||||
|
|
||||||
|
val setupMacheResources by tasks.registering(SetupVanilla::class) {
|
||||||
|
group = "mache"
|
||||||
|
description = "Setup vanilla resources dir"
|
||||||
|
|
||||||
|
inputFile.set(allTasks.extractFromBundler.flatMap { it.serverJar })
|
||||||
|
predicate.set { Files.isRegularFile(it) && !it.toString().endsWith(".class") }
|
||||||
|
outputDir.set(layout.cache.resolve(BASE_PROJECT).resolve("resources"))
|
||||||
|
}
|
||||||
|
|
||||||
|
val applySourcePatches by tasks.registering(ApplyFilePatches::class) {
|
||||||
|
group = "softspoon"
|
||||||
|
description = "Applies patches to the vanilla sources"
|
||||||
|
|
||||||
|
input.set(setupMacheSources.flatMap { it.outputDir })
|
||||||
|
output.set(project.ext.serverProject.map { it.layout.projectDirectory.dir("src/vanilla/java") })
|
||||||
|
patches.set(project.ext.paper.sourcePatchDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
val applySourcePatchesFuzzy by tasks.registering(ApplyFilePatchesFuzzy::class) {
|
||||||
|
group = "softspoon"
|
||||||
|
description = "Applies patches to the vanilla sources"
|
||||||
|
|
||||||
|
input.set(setupMacheSources.flatMap { it.outputDir })
|
||||||
|
output.set(project.ext.serverProject.map { it.layout.projectDirectory.dir("src/vanilla/java") })
|
||||||
|
patches.set(project.ext.paper.sourcePatchDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
val applyResourcePatches by tasks.registering(ApplyFilePatches::class) {
|
||||||
|
group = "softspoon"
|
||||||
|
description = "Applies patches to the vanilla resources"
|
||||||
|
|
||||||
|
input.set(setupMacheResources.flatMap { it.outputDir })
|
||||||
|
output.set(project.ext.serverProject.map { it.layout.projectDirectory.dir("src/vanilla/resources") })
|
||||||
|
patches.set(project.ext.paper.resourcePatchDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
val applyFilePatches by tasks.registering(Task::class) {
|
||||||
|
group = "softspoon"
|
||||||
|
description = "Applies all file patches"
|
||||||
|
dependsOn(applySourcePatches, applyResourcePatches)
|
||||||
|
}
|
||||||
|
|
||||||
|
val applyFeaturePatches by tasks.registering(ApplyFeaturePatches::class) {
|
||||||
|
group = "softspoon"
|
||||||
|
description = "Applies all feature patches"
|
||||||
|
dependsOn(applyFilePatches)
|
||||||
|
|
||||||
|
repo.set(project.ext.serverProject.map { it.layout.projectDirectory.dir("src/vanilla/java") })
|
||||||
|
patches.set(project.ext.paper.featurePatchDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
val applyPatches by tasks.registering(Task::class) {
|
||||||
|
group = "softspoon"
|
||||||
|
description = "Applies all patches"
|
||||||
|
dependsOn(applyFilePatches, applyFeaturePatches)
|
||||||
|
}
|
||||||
|
|
||||||
|
val rebuildSourcePatches by tasks.registering(RebuildFilePatches::class) {
|
||||||
|
group = "softspoon"
|
||||||
|
description = "Rebuilds patches to the vanilla sources"
|
||||||
|
|
||||||
|
minecraftClasspath.from(macheMinecraftExtended)
|
||||||
|
atFile.set(project.ext.paper.additionalAts.fileExists(project))
|
||||||
|
atFileOut.set(project.ext.paper.additionalAts.fileExists(project))
|
||||||
|
|
||||||
|
base.set(layout.cache.resolve(BASE_PROJECT).resolve("sources"))
|
||||||
|
input.set(project.ext.serverProject.map { it.layout.projectDirectory.dir("src/vanilla/java") })
|
||||||
|
patches.set(project.ext.paper.sourcePatchDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
val rebuildResourcePatches by tasks.registering(RebuildFilePatches::class) {
|
||||||
|
group = "softspoon"
|
||||||
|
description = "Rebuilds patches to the vanilla resources"
|
||||||
|
|
||||||
|
base.set(layout.cache.resolve(BASE_PROJECT).resolve("resources"))
|
||||||
|
input.set(project.ext.serverProject.map { it.layout.projectDirectory.dir("src/vanilla/resources") })
|
||||||
|
patches.set(project.ext.paper.resourcePatchDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
val rebuildFilePatches by tasks.registering(Task::class) {
|
||||||
|
group = "softspoon"
|
||||||
|
description = "Rebuilds all file patches"
|
||||||
|
dependsOn(rebuildSourcePatches, rebuildResourcePatches)
|
||||||
|
}
|
||||||
|
|
||||||
|
val rebuildFeaturePatches by tasks.registering(RebuildGitPatches::class) {
|
||||||
|
group = "softspoon"
|
||||||
|
description = "Rebuilds all feature patches"
|
||||||
|
dependsOn(rebuildFilePatches)
|
||||||
|
|
||||||
|
inputDir.set(project.ext.serverProject.map { it.layout.projectDirectory.dir("src/vanilla/java") })
|
||||||
|
patchDir.set(project.ext.paper.featurePatchDir)
|
||||||
|
baseRef.set("file")
|
||||||
|
}
|
||||||
|
|
||||||
|
val rebuildPatches by tasks.registering(Task::class) {
|
||||||
|
group = "softspoon"
|
||||||
|
description = "Rebuilds all file patches"
|
||||||
|
dependsOn(rebuildFilePatches, rebuildFeaturePatches)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun afterEvaluate() {
|
||||||
|
// load mache
|
||||||
|
mache = this.project.configurations.named(MACHE_CONFIG).get().singleFile.toPath().openZip().use { zip ->
|
||||||
|
return@use gson.fromJson<MacheMeta>(zip.getPath("/mache.json").readLines().joinToString("\n"))
|
||||||
|
}
|
||||||
|
println("Loaded mache ${mache.macheVersion} for minecraft ${mache.minecraftVersion}")
|
||||||
|
|
||||||
|
// setup repos
|
||||||
|
this.project.repositories {
|
||||||
|
println("setup repos for ${project.name}")
|
||||||
|
for (repository in mache.repositories) {
|
||||||
|
maven(repository.url) {
|
||||||
|
name = repository.name
|
||||||
|
mavenContent {
|
||||||
|
for (group in repository.groups ?: listOf()) {
|
||||||
|
includeGroupByRegex(group + ".*")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
maven(MC_LIBRARY_URL) {
|
||||||
|
name = "Minecraft"
|
||||||
|
}
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
val libsFile = project.layout.cache.resolve(SERVER_LIBRARIES_TXT)
|
||||||
|
|
||||||
|
// setup mc deps
|
||||||
|
macheMinecraft {
|
||||||
|
withDependencies {
|
||||||
|
project.dependencies {
|
||||||
|
val libs = libsFile.convertToPathOrNull()
|
||||||
|
if (libs != null && libs.exists()) {
|
||||||
|
libs.forEachLine { line ->
|
||||||
|
add(create(line))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
macheMinecraftExtended {
|
||||||
|
extendsFrom(macheMinecraft.get())
|
||||||
|
withDependencies {
|
||||||
|
project.dependencies {
|
||||||
|
add(create(project.files(project.layout.cache.resolve(FINAL_REMAPPED_CODEBOOK_JAR))))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup mache deps
|
||||||
|
this.project.dependencies {
|
||||||
|
mache.dependencies.codebook.forEach {
|
||||||
|
"macheCodebook"(it.toMavenString())
|
||||||
|
}
|
||||||
|
mache.dependencies.paramMappings.forEach {
|
||||||
|
"macheParamMappings"(it.toMavenString())
|
||||||
|
}
|
||||||
|
mache.dependencies.constants.forEach {
|
||||||
|
"macheConstants"(it.toMavenString())
|
||||||
|
}
|
||||||
|
mache.dependencies.remapper.forEach {
|
||||||
|
"macheRemapper"(it.toMavenString())
|
||||||
|
}
|
||||||
|
mache.dependencies.decompiler.forEach {
|
||||||
|
"macheDecompiler"(it.toMavenString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.project.ext.serverProject.get().setupServerProject(libsFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Project.setupServerProject(libsFile: Path) {
|
||||||
|
if (!projectDir.exists()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// minecraft deps
|
||||||
|
val macheMinecraft by configurations.creating {
|
||||||
|
withDependencies {
|
||||||
|
dependencies {
|
||||||
|
// setup mc deps
|
||||||
|
val libs = libsFile.convertToPathOrNull()
|
||||||
|
if (libs != null && libs.exists()) {
|
||||||
|
libs.forEachLine { line ->
|
||||||
|
add(create(line))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// impl extends minecraft
|
||||||
|
configurations.named(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME) {
|
||||||
|
extendsFrom(macheMinecraft)
|
||||||
|
}
|
||||||
|
|
||||||
|
// repos
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
maven(PAPER_MAVEN_REPO_URL)
|
||||||
|
maven(MC_LIBRARY_URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add vanilla source set
|
||||||
|
the<JavaPluginExtension>().sourceSets.named(SourceSet.MAIN_SOURCE_SET_NAME) {
|
||||||
|
java {
|
||||||
|
srcDirs(projectDir.resolve("src/vanilla/java"))
|
||||||
|
}
|
||||||
|
resources {
|
||||||
|
srcDirs(projectDir.resolve("src/vanilla/resources"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,7 +53,9 @@ open class SpigotTasks(
|
||||||
val generateSpigotMappings by tasks.registering<GenerateSpigotMappings> {
|
val generateSpigotMappings by tasks.registering<GenerateSpigotMappings> {
|
||||||
classMappings.set(addAdditionalSpigotMappings.flatMap { it.outputClassSrg })
|
classMappings.set(addAdditionalSpigotMappings.flatMap { it.outputClassSrg })
|
||||||
|
|
||||||
sourceMappings.set(generateMappings.flatMap { it.outputMappings })
|
// todo hypo update breaks generate mappings, hardcode for now
|
||||||
|
// sourceMappings.set(generateMappings.flatMap { it.outputMappings })
|
||||||
|
sourceMappings.set(Path.of("D:\\IntellijProjects\\PaperClean\\.gradle\\caches\\paperweight\\mappings\\official-mojang+yarn.tiny"))
|
||||||
|
|
||||||
outputMappings.set(cache.resolve(SPIGOT_MOJANG_YARN_MAPPINGS))
|
outputMappings.set(cache.resolve(SPIGOT_MOJANG_YARN_MAPPINGS))
|
||||||
notchToSpigotMappings.set(cache.resolve(OBF_SPIGOT_MAPPINGS))
|
notchToSpigotMappings.set(cache.resolve(OBF_SPIGOT_MAPPINGS))
|
||||||
|
|
|
@ -49,7 +49,8 @@ open class VanillaTasks(
|
||||||
|
|
||||||
val remapJar by tasks.registering<RemapJar> {
|
val remapJar by tasks.registering<RemapJar> {
|
||||||
inputJar.set(filterVanillaJar.flatMap { it.outputJar })
|
inputJar.set(filterVanillaJar.flatMap { it.outputJar })
|
||||||
mappingsFile.set(generateMappings.flatMap { it.outputMappings })
|
// mappingsFile.set(generateMappings.flatMap { it.outputMappings })
|
||||||
|
mappingsFile.set(Path.of("D:\\IntellijProjects\\PaperClean\\.gradle\\caches\\paperweight\\mappings\\official-mojang+yarn.tiny"))
|
||||||
fromNamespace.set(OBF_NAMESPACE)
|
fromNamespace.set(OBF_NAMESPACE)
|
||||||
toNamespace.set(DEOBF_NAMESPACE)
|
toNamespace.set(DEOBF_NAMESPACE)
|
||||||
remapper.from(project.configurations.named(REMAPPER_CONFIG))
|
remapper.from(project.configurations.named(REMAPPER_CONFIG))
|
||||||
|
|
|
@ -0,0 +1,179 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import io.papermc.paperweight.util.*
|
||||||
|
import java.net.URL
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.Paths
|
||||||
|
import kotlin.io.path.*
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import org.gradle.testkit.runner.TaskOutcome
|
||||||
|
import org.junit.jupiter.api.Disabled
|
||||||
|
import org.junit.jupiter.api.io.CleanupMode
|
||||||
|
import org.junit.jupiter.api.io.TempDir
|
||||||
|
|
||||||
|
class FunctionalTest {
|
||||||
|
|
||||||
|
val debug = false
|
||||||
|
|
||||||
|
@Disabled
|
||||||
|
@Test
|
||||||
|
fun setupCleanTestRepo() {
|
||||||
|
val projectDir = Path.of("F:\\Projects\\paperweight\\test").ensureClean().createDirectories()
|
||||||
|
|
||||||
|
setupMache("fake_mache", projectDir.resolve("mache.zip"))
|
||||||
|
setupMojang("fake_mojang", projectDir.resolve("fake_mojang"))
|
||||||
|
projectDir.copyProject("functional_test")
|
||||||
|
|
||||||
|
val settings = projectDir.resolve("settings.gradle")
|
||||||
|
val text = settings.readText()
|
||||||
|
settings.writeText(text.replace("// includeBuild '..'", "includeBuild '..'").replace("functional_test", "test"))
|
||||||
|
|
||||||
|
projectDir.resolve("patches").deleteRecursively()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test simple test project`(@TempDir(cleanup = CleanupMode.ON_SUCCESS) tempDir: Path) {
|
||||||
|
println("running in $tempDir")
|
||||||
|
val testResource = Paths.get("src/test/resources/functional_test")
|
||||||
|
|
||||||
|
setupMache("fake_mache", tempDir.resolve("mache.zip"))
|
||||||
|
setupMojang("fake_mojang", tempDir.resolve("fake_mojang"))
|
||||||
|
|
||||||
|
val gradleRunner = tempDir.copyProject("functional_test").gradleRunner()
|
||||||
|
|
||||||
|
println("\nrunning extractFromBundler\n")
|
||||||
|
val extractFromBundler = gradleRunner
|
||||||
|
.withArguments("extractFromBundler", "--stacktrace", "-Dfake=true")
|
||||||
|
.withDebug(debug)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
assertEquals(extractFromBundler.task(":extractFromBundler")?.outcome, TaskOutcome.SUCCESS)
|
||||||
|
|
||||||
|
// appP -> works
|
||||||
|
println("\nrunning applyPatches dependencies\n")
|
||||||
|
val appP = gradleRunner
|
||||||
|
.withArguments("applyPatches", "dependencies", ":test-server:dependencies", "--stacktrace", "-Dfake=true")
|
||||||
|
.withDebug(debug)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
assertEquals(appP.task(":applyPatches")?.outcome, TaskOutcome.SUCCESS)
|
||||||
|
|
||||||
|
// clean rebuild rebP -> changes nothing
|
||||||
|
println("\nrunning rebuildPatches\n")
|
||||||
|
val rebP = gradleRunner
|
||||||
|
.withArguments("rebuildPatches", "--stacktrace", "-Dfake=true")
|
||||||
|
.withDebug(debug)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
assertEquals(rebP.task(":rebuildPatches")?.outcome, TaskOutcome.SUCCESS)
|
||||||
|
assertEquals(
|
||||||
|
testResource.resolve("fake-patches/sources/Test.java.patch").readText(),
|
||||||
|
tempDir.resolve("fake-patches/sources/Test.java.patch").readText()
|
||||||
|
)
|
||||||
|
|
||||||
|
// add AT to source -> patch and AT file is updated
|
||||||
|
val sourceFile = tempDir.resolve("test-server/src/vanilla/java/Test.java")
|
||||||
|
val replacedContent = sourceFile.readText().replace(
|
||||||
|
"\"2\";",
|
||||||
|
"\"2\"; // Woo"
|
||||||
|
).replace("public String getTest2() {", "private final String getTest2() {// Paper-AT: private+f getTest2()Ljava/lang/String;")
|
||||||
|
sourceFile.writeText(replacedContent)
|
||||||
|
|
||||||
|
Git(tempDir.resolve("test-server/src/vanilla/java")).let { git ->
|
||||||
|
git("add", ".").executeSilently()
|
||||||
|
git("commit", "--amend", "--no-edit").executeSilently()
|
||||||
|
}
|
||||||
|
|
||||||
|
println("\nrunning rebuildPatches again\n")
|
||||||
|
val rebP2 = gradleRunner
|
||||||
|
.withArguments("rebuildPatches", "--stacktrace", "-Dfake=true")
|
||||||
|
.withDebug(debug)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
assertEquals(rebP2.task(":rebuildPatches")?.outcome, TaskOutcome.SUCCESS)
|
||||||
|
assertEquals(
|
||||||
|
testResource.resolve("fake-patches/expected/Test.java.patch").readText(),
|
||||||
|
tempDir.resolve("fake-patches/sources/Test.java.patch").readText()
|
||||||
|
)
|
||||||
|
assertEquals(testResource.resolve("build-data/expected.at").readText(), tempDir.resolve("build-data/fake.at").readText())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test full vanilla project`(@TempDir(cleanup = CleanupMode.ON_SUCCESS) tempDir: Path) {
|
||||||
|
println("running in $tempDir")
|
||||||
|
val gradleRunner = tempDir.copyProject("functional_test").gradleRunner()
|
||||||
|
|
||||||
|
val extractFromBundler = gradleRunner
|
||||||
|
.withArguments("extractFromBundler", "--stacktrace", "-Dfake=false")
|
||||||
|
.withDebug(debug)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
assertEquals(extractFromBundler.task(":extractFromBundler")?.outcome, TaskOutcome.SUCCESS)
|
||||||
|
|
||||||
|
val result = gradleRunner
|
||||||
|
.withArguments("applyPatches", "-Dfake=false")
|
||||||
|
.withDebug(debug)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
assertEquals(result.task(":applyPatches")?.outcome, TaskOutcome.SUCCESS)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setupMache(macheName: String, target: Path) {
|
||||||
|
val macheDir = Paths.get("src/test/resources/$macheName")
|
||||||
|
zip(macheDir, target)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setupMojang(mojangName: String, target: Path) {
|
||||||
|
val mojangDir = Paths.get("src/test/resources/$mojangName")
|
||||||
|
mojangDir.copyRecursivelyTo(target)
|
||||||
|
|
||||||
|
val serverFolder = target.resolve("server")
|
||||||
|
ProcessBuilder()
|
||||||
|
.directory(serverFolder)
|
||||||
|
.command("javac", serverFolder.resolve("Test.java").toString())
|
||||||
|
.redirectErrorStream(true)
|
||||||
|
.start()
|
||||||
|
.waitFor()
|
||||||
|
|
||||||
|
ProcessBuilder()
|
||||||
|
.directory(serverFolder)
|
||||||
|
.command("jar", "-cf", "server.jar", "Test.class", "test.json")
|
||||||
|
.redirectErrorStream(true)
|
||||||
|
.start()
|
||||||
|
.waitFor()
|
||||||
|
|
||||||
|
val versionFolder = target.resolve("bundle/META-INF/versions/fake/")
|
||||||
|
versionFolder.createDirectories()
|
||||||
|
serverFolder.resolve("server.jar").copyTo(versionFolder.resolve("server.jar"))
|
||||||
|
|
||||||
|
val oshiFolder = target.resolve("bundle/META-INF/libraries/com/github/oshi/oshi-core/6.4.5/")
|
||||||
|
oshiFolder.createDirectories()
|
||||||
|
oshiFolder.resolve(
|
||||||
|
"oshi-core-6.4.5.jar"
|
||||||
|
).writeBytes(URL("https://libraries.minecraft.net/com/github/oshi/oshi-core/6.4.5/oshi-core-6.4.5.jar").readBytes())
|
||||||
|
zip(target.resolve("bundle"), target.resolve("bundle.jar"))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import io.papermc.paperweight.util.*
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.nio.file.Paths
|
||||||
|
import kotlin.io.path.*
|
||||||
|
import org.gradle.testkit.runner.GradleRunner
|
||||||
|
|
||||||
|
fun Path.copyProject(resourcesProjectName: String): ProjectFiles {
|
||||||
|
Paths.get("src/test/resources/$resourcesProjectName")
|
||||||
|
.copyToRecursively(this, followLinks = false)
|
||||||
|
Git(this)("init").executeSilently()
|
||||||
|
return ProjectFiles(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ProjectFiles(val projectDir: Path) {
|
||||||
|
val gradleProperties: Path = resolve("gradle.properties")
|
||||||
|
val buildGradle: Path = resolve("build.gradle")
|
||||||
|
val buildGradleKts: Path = resolve("build.gradle.kts")
|
||||||
|
val settingsGradle: Path = resolve("settings.gradle")
|
||||||
|
val settingsGradleKts: Path = resolve("settings.gradle.kts")
|
||||||
|
|
||||||
|
fun resolve(path: String): Path = projectDir.resolve(path)
|
||||||
|
|
||||||
|
fun gradleRunner(): GradleRunner = GradleRunner.create()
|
||||||
|
.forwardOutput()
|
||||||
|
.withPluginClasspath()
|
||||||
|
.withProjectDir(projectDir.toFile())
|
||||||
|
}
|
108
paperweight-core/src/test/resources/fake_mache/mache.json
Normal file
108
paperweight-core/src/test/resources/fake_mache/mache.json
Normal file
|
@ -0,0 +1,108 @@
|
||||||
|
{
|
||||||
|
"minecraftVersion": "fake",
|
||||||
|
"macheVersion": "fake",
|
||||||
|
"dependencies": {
|
||||||
|
"codebook": [
|
||||||
|
{
|
||||||
|
"group": "io.papermc.codebook",
|
||||||
|
"name": "codebook-cli",
|
||||||
|
"version": "1.0.10",
|
||||||
|
"classifier": "all"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"paramMappings": [
|
||||||
|
{
|
||||||
|
"group": "org.parchmentmc.data",
|
||||||
|
"name": "parchment-1.20.4",
|
||||||
|
"version": "2024.02.25",
|
||||||
|
"extension": "zip"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"constants": [
|
||||||
|
],
|
||||||
|
"remapper": [
|
||||||
|
{
|
||||||
|
"group": "net.neoforged",
|
||||||
|
"name": "AutoRenamingTool",
|
||||||
|
"version": "1.0.14",
|
||||||
|
"classifier": "all"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"decompiler": [
|
||||||
|
{
|
||||||
|
"group": "org.vineflower",
|
||||||
|
"name": "vineflower",
|
||||||
|
"version": "1.10.0-20240212.003104-88"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"url": "https://maven.fabricmc.net/",
|
||||||
|
"name": "FabricMC",
|
||||||
|
"groups": [
|
||||||
|
"net.fabricmc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://maven.neoforged.net/releases/",
|
||||||
|
"name": "NeoForged",
|
||||||
|
"groups": [
|
||||||
|
"net.neoforged",
|
||||||
|
"net.minecraftforge"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://repo.papermc.io/repository/maven-public/",
|
||||||
|
"name": "PaperMC",
|
||||||
|
"groups": [
|
||||||
|
"io.papermc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://maven.parchmentmc.org/",
|
||||||
|
"name": "ParchmentMC",
|
||||||
|
"groups": [
|
||||||
|
"org.parchmentmc"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"url": "https://s01.oss.sonatype.org/content/repositories/snapshots/",
|
||||||
|
"name": "sonatype snapshots",
|
||||||
|
"groups": [
|
||||||
|
"org.vineflower"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"decompilerArgs": [
|
||||||
|
"-nns=true",
|
||||||
|
"-tcs=true",
|
||||||
|
"-ovr=false",
|
||||||
|
"-vvm=true",
|
||||||
|
"-iec=true",
|
||||||
|
"-jrt=current",
|
||||||
|
"-ind= ",
|
||||||
|
"-jvn=false",
|
||||||
|
"-dcc=true",
|
||||||
|
"-sef=true",
|
||||||
|
"-nls=1"
|
||||||
|
],
|
||||||
|
"remapperArgs": [
|
||||||
|
"--temp-dir={tempDir}",
|
||||||
|
"--remapper-file={remapperFile}",
|
||||||
|
"--mappings-file={mappingsFile}",
|
||||||
|
"--params-file={paramsFile}",
|
||||||
|
"--output={output}",
|
||||||
|
"--input={input}",
|
||||||
|
"--input-classpath={inputClasspath}"
|
||||||
|
],
|
||||||
|
"additionalCompileDependencies": {
|
||||||
|
"compileOnly": [
|
||||||
|
{
|
||||||
|
"group": "org.jetbrains",
|
||||||
|
"name": "annotations",
|
||||||
|
"version": "24.0.1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
--- a/Test.java
|
||||||
|
+++ b/Test.java
|
||||||
|
@@ -1,5 +_,5 @@
|
||||||
|
public class Test {
|
||||||
|
- public int dum;
|
||||||
|
+ public int dum2;
|
||||||
|
private final String test;
|
||||||
|
|
||||||
|
public Test(String var1) {
|
|
@ -0,0 +1 @@
|
||||||
|
- com.github.oshi:oshi-core:6.4.5 com/github/oshi/oshi-core/6.4.5/oshi-core-6.4.5.jar
|
|
@ -0,0 +1 @@
|
||||||
|
- fake fake/server.jar
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"id": "fake"
|
||||||
|
}
|
19
paperweight-core/src/test/resources/fake_mojang/mappings.txt
Normal file
19
paperweight-core/src/test/resources/fake_mojang/mappings.txt
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
com.mojang.math.Axis -> a:
|
||||||
|
# {"fileName":"Axis.java","id":"sourceFile"}
|
||||||
|
com.mojang.math.Axis XN -> a
|
||||||
|
com.mojang.math.Axis XP -> b
|
||||||
|
com.mojang.math.Axis YN -> c
|
||||||
|
com.mojang.math.Axis YP -> d
|
||||||
|
com.mojang.math.Axis ZN -> e
|
||||||
|
com.mojang.math.Axis ZP -> f
|
||||||
|
17:17:com.mojang.math.Axis of(org.joml.Vector3f) -> of
|
||||||
|
org.joml.Quaternionf rotation(float) -> rotation
|
||||||
|
23:23:org.joml.Quaternionf rotationDegrees(float) -> rotationDegrees
|
||||||
|
17:17:org.joml.Quaternionf lambda$of$6(org.joml.Vector3f,float) -> a
|
||||||
|
14:14:org.joml.Quaternionf lambda$static$5(float) -> a
|
||||||
|
13:13:org.joml.Quaternionf lambda$static$4(float) -> b
|
||||||
|
12:12:org.joml.Quaternionf lambda$static$3(float) -> c
|
||||||
|
11:11:org.joml.Quaternionf lambda$static$2(float) -> d
|
||||||
|
10:10:org.joml.Quaternionf lambda$static$1(float) -> e
|
||||||
|
9:9:org.joml.Quaternionf lambda$static$0(float) -> f
|
||||||
|
9:14:void <clinit>() -> <clinit>
|
|
@ -0,0 +1,17 @@
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public int dum;
|
||||||
|
private final String test;
|
||||||
|
|
||||||
|
public Test(String test) {
|
||||||
|
this.test = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTest() {
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTest2() {
|
||||||
|
return test + "2";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"test": "test"
|
||||||
|
}
|
12
paperweight-core/src/test/resources/fake_mojang/version.json
Normal file
12
paperweight-core/src/test/resources/fake_mojang/version.json
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"downloads": {
|
||||||
|
"server": {
|
||||||
|
"sha1": "",
|
||||||
|
"url": "file://project/fake_mojang/bundle.jar"
|
||||||
|
},
|
||||||
|
"server_mappings": {
|
||||||
|
"sha1": "",
|
||||||
|
"url": "file://project/fake_mojang/mappings.txt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"latest": {
|
||||||
|
"release": "fake",
|
||||||
|
"snapshot": "fake"
|
||||||
|
},
|
||||||
|
"versions": [
|
||||||
|
{
|
||||||
|
"id": "fake",
|
||||||
|
"type": "release",
|
||||||
|
"url": "file://project/fake_mojang/version.json",
|
||||||
|
"sha1": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
2
paperweight-core/src/test/resources/functional_test/.gitignore
vendored
Normal file
2
paperweight-core/src/test/resources/functional_test/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
.gradle
|
||||||
|
gradle
|
|
@ -0,0 +1,5 @@
|
||||||
|
# This file is auto generated, any changes may be overridden!
|
||||||
|
# See CONTRIBUTING.md on how to add access transformers.
|
||||||
|
private+f Test getTest2()Ljava/lang/String;
|
||||||
|
public+f Test dum2
|
||||||
|
public+f Test getTest()Ljava/lang/String;
|
|
@ -0,0 +1,4 @@
|
||||||
|
# This file is auto generated, any changes may be overridden!
|
||||||
|
# See CONTRIBUTING.md on how to add access transformers.
|
||||||
|
public+f Test dum2
|
||||||
|
public+f Test getTest()Ljava/lang/String;
|
|
@ -0,0 +1,3 @@
|
||||||
|
# This file is auto generated, any changes may be overridden!
|
||||||
|
# See CONTRIBUTING.md on how to add access transformers.
|
||||||
|
private+f net.minecraft.CrashReport getTitle()Ljava/lang/String;
|
|
@ -0,0 +1,52 @@
|
||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
id 'com.github.johnrengelman.shadow' version '8.1.1' apply false
|
||||||
|
id 'io.papermc.paperweight.core'
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
apply plugin: 'java'
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
def fake = Boolean.getBoolean("fake")
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
if (fake) {
|
||||||
|
mache files('mache.zip') // use fake mache for testing
|
||||||
|
} else {
|
||||||
|
mache 'io.papermc:mache:1.20.4+build.3'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
paperweight {
|
||||||
|
softSpoon = true
|
||||||
|
|
||||||
|
if (fake) {
|
||||||
|
// use fake mojang data for testing
|
||||||
|
minecraftVersion = 'fake'
|
||||||
|
minecraftManifestUrl = 'file://project/fake_mojang/version_manifest.json'
|
||||||
|
|
||||||
|
paper {
|
||||||
|
sourcePatchDir.set(file('fake-patches/sources'))
|
||||||
|
resourcePatchDir.set(file('fake-patches/resources'))
|
||||||
|
featurePatchDir.set(file('fake-patches/feature'))
|
||||||
|
|
||||||
|
additionalAts.set(file('build-data/fake.at'))
|
||||||
|
|
||||||
|
paperServerDir.set(file('test-server'))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
minecraftVersion = '1.20.4'
|
||||||
|
|
||||||
|
paper {
|
||||||
|
paperServerDir.set(file('test-server'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
serverProject = project(':test-server')
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
--- a/Test.java
|
||||||
|
+++ b/Test.java
|
||||||
|
@@ -7,10 +_,10 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String getTest() {
|
||||||
|
- return this.test;
|
||||||
|
+ return this.test; // WOOOO
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String getTest2() {
|
||||||
|
- return this.test + "2";
|
||||||
|
+ return this.test + "2"; // Woo
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
--- a/test.json
|
||||||
|
+++ b/test.json
|
||||||
|
@@ -1,3 +_,3 @@
|
||||||
|
{
|
||||||
|
- "test": "test"
|
||||||
|
+ "test": "test2"
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
--- a/Test.java
|
||||||
|
+++ b/Test.java
|
||||||
|
@@ -7,7 +_,7 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String getTest() {
|
||||||
|
- return this.test;
|
||||||
|
+ return this.test; // WOOOO
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTest2() {
|
|
@ -0,0 +1,18 @@
|
||||||
|
pluginManagement {
|
||||||
|
// includeBuild '..'
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
gradlePluginPortal()
|
||||||
|
maven {
|
||||||
|
url "https://repo.papermc.io/repository/maven-public/"
|
||||||
|
}
|
||||||
|
maven {
|
||||||
|
url "https://maven.parchmentmc.org"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rootProject.name = 'functional_test'
|
||||||
|
|
||||||
|
include 'test-api'
|
||||||
|
include 'test-server'
|
|
@ -0,0 +1,3 @@
|
||||||
|
plugins {
|
||||||
|
id "java-library"
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
plugins {
|
||||||
|
id "java"
|
||||||
|
id "com.github.johnrengelman.shadow"
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(":test-api")
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||||
|
From: MiniDigger | Martin <admin@benndorf.dev>
|
||||||
|
Date: Sun, 31 Mar 2024 17:01:32 +0200
|
||||||
|
Subject: [PATCH] Example
|
||||||
|
|
||||||
|
|
||||||
|
diff --git a/net/minecraft/server/dedicated/DedicatedServer.java b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||||
|
index 28def15b5789d34bcfc2a16a17444c9c72dc2c8f..a8f735100a8d4db72dae9be3eeeca0d417be3eee 100644
|
||||||
|
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||||
|
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||||
|
@@ -106,6 +106,7 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||||
|
thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER));
|
||||||
|
thread.start();
|
||||||
|
LOGGER.info("Starting minecraft server version {}", SharedConstants.getCurrentVersion().getName());
|
||||||
|
+ LOGGER.info("Wooooooooooooooooooo");
|
||||||
|
if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) {
|
||||||
|
LOGGER.warn("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\"");
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
--- a/version.json
|
||||||
|
+++ b/version.json
|
||||||
|
@@ -1,6 +_,6 @@
|
||||||
|
{
|
||||||
|
- "id": "1.20.4",
|
||||||
|
- "name": "1.20.4",
|
||||||
|
+ "id": "1.20.4-paper",
|
||||||
|
+ "name": "1.20.4 - Paper",
|
||||||
|
"world_version": 3700,
|
||||||
|
"series_id": "main",
|
||||||
|
"protocol_version": 765,
|
|
@ -0,0 +1,15 @@
|
||||||
|
--- a/net/minecraft/CrashReport.java
|
||||||
|
+++ b/net/minecraft/CrashReport.java
|
||||||
|
@@ -35,10 +_,11 @@
|
||||||
|
public CrashReport(String title, Throwable exception) {
|
||||||
|
this.title = title;
|
||||||
|
this.exception = exception;
|
||||||
|
+ // FIXME this.systemReport.setDetail("CraftBukkit Information", new org.bukkit.craftbukkit.CraftCrashReport()); // CraftBukkit
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String getTitle() {
|
||||||
|
- return this.title;
|
||||||
|
+ return this.title; // Test
|
||||||
|
}
|
||||||
|
|
||||||
|
public Throwable getException() {
|
|
@ -9,6 +9,8 @@ repositories {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(libs.httpclient)
|
implementation(libs.httpclient)
|
||||||
implementation(libs.bundles.kotson)
|
implementation(libs.bundles.kotson)
|
||||||
|
implementation(libs.coroutines)
|
||||||
|
implementation(libs.jgit)
|
||||||
|
|
||||||
// ASM for inspection
|
// ASM for inspection
|
||||||
implementation(libs.bundles.asm)
|
implementation(libs.bundles.asm)
|
||||||
|
@ -19,9 +21,16 @@ dependencies {
|
||||||
|
|
||||||
implementation(libs.lorenzTiny)
|
implementation(libs.lorenzTiny)
|
||||||
|
|
||||||
|
implementation(libs.feather.core)
|
||||||
|
implementation(libs.feather.gson)
|
||||||
|
|
||||||
implementation(libs.jbsdiff)
|
implementation(libs.jbsdiff)
|
||||||
|
|
||||||
|
implementation(libs.restamp)
|
||||||
|
|
||||||
implementation(variantOf(libs.diffpatch) { classifier("all") }) {
|
implementation(variantOf(libs.diffpatch) { classifier("all") }) {
|
||||||
isTransitive = false
|
isTransitive = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testImplementation(libs.mockk)
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,8 @@ import java.time.format.DateTimeFormatter
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import kotlin.io.path.*
|
import kotlin.io.path.*
|
||||||
|
import kotlinx.coroutines.async
|
||||||
|
import kotlinx.coroutines.coroutineScope
|
||||||
import org.apache.http.HttpHost
|
import org.apache.http.HttpHost
|
||||||
import org.apache.http.HttpStatus
|
import org.apache.http.HttpStatus
|
||||||
import org.apache.http.client.config.CookieSpecs
|
import org.apache.http.client.config.CookieSpecs
|
||||||
|
@ -41,12 +43,17 @@ import org.apache.http.client.methods.HttpGet
|
||||||
import org.apache.http.client.utils.DateUtils
|
import org.apache.http.client.utils.DateUtils
|
||||||
import org.apache.http.impl.client.CloseableHttpClient
|
import org.apache.http.impl.client.CloseableHttpClient
|
||||||
import org.apache.http.impl.client.HttpClientBuilder
|
import org.apache.http.impl.client.HttpClientBuilder
|
||||||
|
import org.gradle.api.file.DirectoryProperty
|
||||||
import org.gradle.api.logging.Logger
|
import org.gradle.api.logging.Logger
|
||||||
import org.gradle.api.logging.Logging
|
import org.gradle.api.logging.Logging
|
||||||
import org.gradle.api.services.BuildService
|
import org.gradle.api.services.BuildService
|
||||||
import org.gradle.api.services.BuildServiceParameters
|
import org.gradle.api.services.BuildServiceParameters
|
||||||
|
|
||||||
abstract class DownloadService : BuildService<BuildServiceParameters.None>, AutoCloseable {
|
abstract class DownloadService : BuildService<DownloadService.Params>, AutoCloseable {
|
||||||
|
|
||||||
|
interface Params : BuildServiceParameters {
|
||||||
|
val projectPath: DirectoryProperty
|
||||||
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
val LOGGER: Logger = Logging.getLogger(DownloadService::class.java)
|
val LOGGER: Logger = Logging.getLogger(DownloadService::class.java)
|
||||||
|
@ -64,13 +71,19 @@ abstract class DownloadService : BuildService<BuildServiceParameters.None>, Auto
|
||||||
download(url, file, hash)
|
download(url, file, hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun downloadAsync(source: Any, target: Any, hash: Hash? = null) = coroutineScope {
|
||||||
|
async {
|
||||||
|
download(source.convertToUrl(), target.convertToPath(), hash, false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun download(source: URL, target: Path, hash: Hash?, retry: Boolean = false) {
|
private fun download(source: URL, target: Path, hash: Hash?, retry: Boolean = false) {
|
||||||
download(source, target)
|
download(source, target)
|
||||||
if (hash == null) {
|
if (hash == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
val dlHash = target.hashFile(hash.algorithm).asHexString().lowercase(Locale.ENGLISH)
|
val dlHash = target.hashFile(hash.algorithm).asHexString().lowercase(Locale.ENGLISH)
|
||||||
if (dlHash == hash.valueLower) {
|
if (hash.value == "" || dlHash == hash.valueLower) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
LOGGER.warn(
|
LOGGER.warn(
|
||||||
|
@ -91,6 +104,15 @@ abstract class DownloadService : BuildService<BuildServiceParameters.None>, Auto
|
||||||
private fun download(source: URL, target: Path) {
|
private fun download(source: URL, target: Path) {
|
||||||
target.parent.createDirectories()
|
target.parent.createDirectories()
|
||||||
|
|
||||||
|
if (source.protocol == "file") {
|
||||||
|
var path = source.toString().replace("file://", "")
|
||||||
|
if (source.host == "project") {
|
||||||
|
path = path.replace("project", parameters.projectPath.path.absolutePathString())
|
||||||
|
}
|
||||||
|
Path.of(path).copyTo(target, overwrite = true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val etagDir = target.resolveSibling("etags")
|
val etagDir = target.resolveSibling("etags")
|
||||||
etagDir.createDirectories()
|
etagDir.createDirectories()
|
||||||
|
|
||||||
|
|
|
@ -189,16 +189,16 @@ fun Git.disableAutoGpgSigningInRepo() {
|
||||||
invoke("config", "tag.gpgSign", "false").executeSilently(silenceErr = true)
|
invoke("config", "tag.gpgSign", "false").executeSilently(silenceErr = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkoutRepoFromUpstream(git: Git, upstream: Path, upstreamBranch: String) {
|
fun checkoutRepoFromUpstream(git: Git, upstream: Path, upstreamBranch: String, upstreamName: String = "upstream", branchName: String = "master") {
|
||||||
git("init", "--quiet").executeSilently(silenceErr = true)
|
git("init", "--quiet").executeSilently(silenceErr = true)
|
||||||
git.disableAutoGpgSigningInRepo()
|
git.disableAutoGpgSigningInRepo()
|
||||||
git("remote", "remove", "upstream").runSilently(silenceErr = true)
|
git("remote", "remove", upstreamName).runSilently(silenceErr = true)
|
||||||
git("remote", "add", "upstream", upstream.toUri().toString()).executeSilently(silenceErr = true)
|
git("remote", "add", upstreamName, upstream.toUri().toString()).executeSilently(silenceErr = true)
|
||||||
git("fetch", "upstream", "--prune").executeSilently(silenceErr = true)
|
git("fetch", upstreamName, "--prune").executeSilently(silenceErr = true)
|
||||||
if (git("checkout", "master").runSilently(silenceErr = true) != 0) {
|
if (git("checkout", branchName).runSilently(silenceErr = true) != 0) {
|
||||||
git("checkout", "-b", "master").runSilently(silenceErr = true)
|
git("checkout", "-b", branchName).runSilently(silenceErr = true)
|
||||||
}
|
}
|
||||||
git("reset", "--hard", "upstream/$upstreamBranch").executeSilently(silenceErr = true)
|
git("reset", "--hard", "$upstreamName/$upstreamBranch").executeSilently(silenceErr = true)
|
||||||
git("gc").runSilently(silenceErr = true)
|
git("gc").runSilently(silenceErr = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ import org.gradle.api.file.RegularFileProperty
|
||||||
import org.gradle.api.provider.Property
|
import org.gradle.api.provider.Property
|
||||||
import org.gradle.api.tasks.*
|
import org.gradle.api.tasks.*
|
||||||
|
|
||||||
// Not cached since this is Mojang's server jar
|
@CacheableTask
|
||||||
abstract class DownloadServerJar : BaseTask() {
|
abstract class DownloadServerJar : BaseTask() {
|
||||||
|
|
||||||
@get:Input
|
@get:Input
|
||||||
|
@ -41,7 +41,6 @@ abstract class DownloadServerJar : BaseTask() {
|
||||||
abstract val downloader: Property<DownloadService>
|
abstract val downloader: Property<DownloadService>
|
||||||
|
|
||||||
@get:Nested
|
@get:Nested
|
||||||
@get:Optional
|
|
||||||
abstract val expectedHash: Property<Hash>
|
abstract val expectedHash: Property<Hash>
|
||||||
|
|
||||||
override fun init() {
|
override fun init() {
|
||||||
|
|
|
@ -59,11 +59,6 @@ abstract class ExtractFromBundler : BaseTask() {
|
||||||
@get:OutputFile
|
@get:OutputFile
|
||||||
abstract val serverVersionsList: RegularFileProperty
|
abstract val serverVersionsList: RegularFileProperty
|
||||||
|
|
||||||
override fun init() {
|
|
||||||
super.init()
|
|
||||||
serverJar.set(defaultOutput())
|
|
||||||
}
|
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun run() {
|
fun run() {
|
||||||
ServerBundler.extractFromBundler(
|
ServerBundler.extractFromBundler(
|
||||||
|
@ -99,16 +94,16 @@ object ServerBundler {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun extractServerJar(bundlerZip: Path, serverJar: Path, outputVersionJson: Path?) {
|
private fun extractServerJar(bundlerZip: Path, serverJar: Path, outputVersionJson: Path?) {
|
||||||
val serverVersionJson = bundlerZip.resolve("version.json")
|
val serverVersionJson = bundlerZip.resolve(FileEntry.VERSION_JSON)
|
||||||
outputVersionJson?.let { output ->
|
outputVersionJson?.let { output ->
|
||||||
serverVersionJson.copyTo(output, overwrite = true)
|
serverVersionJson.copyTo(output, overwrite = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
val versionId = gson.fromJson<JsonObject>(serverVersionJson)["id"].asString
|
val versionId = gson.fromJson<JsonObject>(serverVersionJson)["id"].asString
|
||||||
val versions = bundlerZip.resolve("/META-INF/versions.list").readLines()
|
val versions = bundlerZip.resolve(FileEntry.VERSIONS_LIST).readLines()
|
||||||
.map { it.split('\t') }
|
.map { it.split('\t') }
|
||||||
.associate { it[1] to it[2] }
|
.associate { it[1] to it[2] }
|
||||||
val serverJarPath = bundlerZip.resolve("/META-INF/versions/${versions[versionId]}")
|
val serverJarPath = bundlerZip.resolve("${FileEntry.VERSIONS_DIR}/${versions[versionId]}")
|
||||||
|
|
||||||
serverJar.parent.createDirectories()
|
serverJar.parent.createDirectories()
|
||||||
serverJarPath.copyTo(serverJar, overwrite = true)
|
serverJarPath.copyTo(serverJar, overwrite = true)
|
||||||
|
@ -117,7 +112,7 @@ object ServerBundler {
|
||||||
private fun extractLibraryJars(bundlerZip: Path, serverLibraryJars: Path) {
|
private fun extractLibraryJars(bundlerZip: Path, serverLibraryJars: Path) {
|
||||||
serverLibraryJars.deleteRecursive()
|
serverLibraryJars.deleteRecursive()
|
||||||
serverLibraryJars.parent.createDirectories()
|
serverLibraryJars.parent.createDirectories()
|
||||||
bundlerZip.resolve("/META-INF/libraries").copyRecursivelyTo(serverLibraryJars)
|
bundlerZip.resolve(FileEntry.LIBRARIES_DIR).copyRecursivelyTo(serverLibraryJars)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun writeLibrariesTxt(bundlerZip: Path, serverLibrariesTxt: Path) {
|
private fun writeLibrariesTxt(bundlerZip: Path, serverLibrariesTxt: Path) {
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* 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 io.papermc.paperweight.util.data.mache.*
|
||||||
|
import kotlin.io.path.*
|
||||||
|
import org.gradle.api.DefaultTask
|
||||||
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
|
import org.gradle.api.tasks.Classpath
|
||||||
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
|
||||||
|
abstract class MacheTask : DefaultTask() {
|
||||||
|
|
||||||
|
@get:Classpath
|
||||||
|
abstract val mache: ConfigurableFileCollection
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
fun run() {
|
||||||
|
val meta = getMacheMeta()
|
||||||
|
println("loaded meta: $meta")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getMacheMeta(): MacheMeta {
|
||||||
|
val metaJson = mutableListOf("")
|
||||||
|
mache.singleFile.toPath().openZip().use { zip ->
|
||||||
|
metaJson.addAll(zip.getPath("/mache.json").readLines())
|
||||||
|
}
|
||||||
|
|
||||||
|
return gson.fromJson<MacheMeta>(metaJson.joinToString("\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun extractVanillaJar() {
|
||||||
|
// val jar = downloadedJar.convertToPath()
|
||||||
|
// val out = serverJar.convertToPath().ensureClean()
|
||||||
|
//
|
||||||
|
// jar.useZip { root ->
|
||||||
|
// val metaInf = root.resolve("META-INF")
|
||||||
|
// val versionsList = metaInf.resolve("versions.list")
|
||||||
|
// if (versionsList.notExists()) {
|
||||||
|
// throw Exception("Could not find versions.list")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// val lines = versionsList.readLines()
|
||||||
|
// if (lines.size != 1) {
|
||||||
|
// throw Exception("versions.list is invalid")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// val line = lines.first()
|
||||||
|
// val parts = line.split(whitespace)
|
||||||
|
// if (parts.size != 3) {
|
||||||
|
// throw Exception("versions.list line is invalid")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// val serverJarInJar = metaInf.resolve("versions").resolve(parts[2])
|
||||||
|
// if (serverJarInJar.notExists()) {
|
||||||
|
// throw Exception("Could not find version jar")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// serverJarInJar.copyTo(out)
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,6 +34,7 @@ import org.gradle.api.tasks.OutputFile
|
||||||
import org.gradle.api.tasks.PathSensitive
|
import org.gradle.api.tasks.PathSensitive
|
||||||
import org.gradle.api.tasks.PathSensitivity
|
import org.gradle.api.tasks.PathSensitivity
|
||||||
import org.gradle.api.tasks.TaskAction
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
import writeLF
|
||||||
|
|
||||||
@CacheableTask
|
@CacheableTask
|
||||||
abstract class MergeAccessTransforms : BaseTask() {
|
abstract class MergeAccessTransforms : BaseTask() {
|
||||||
|
@ -67,6 +68,6 @@ abstract class MergeAccessTransforms : BaseTask() {
|
||||||
outputAt.merge(at)
|
outputAt.merge(at)
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessTransformFormats.FML.write(outputFile.path, outputAt)
|
AccessTransformFormats.FML.writeLF(outputFile.path, outputAt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.gradle.api.tasks.OutputFile
|
||||||
import org.gradle.api.tasks.PathSensitive
|
import org.gradle.api.tasks.PathSensitive
|
||||||
import org.gradle.api.tasks.PathSensitivity
|
import org.gradle.api.tasks.PathSensitivity
|
||||||
import org.gradle.api.tasks.TaskAction
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
import writeLF
|
||||||
|
|
||||||
@CacheableTask
|
@CacheableTask
|
||||||
abstract class RemapAccessTransform : BaseTask() {
|
abstract class RemapAccessTransform : BaseTask() {
|
||||||
|
@ -57,6 +58,6 @@ abstract class RemapAccessTransform : BaseTask() {
|
||||||
val mappingSet = MappingFormats.TINY.read(mappings.path, SPIGOT_NAMESPACE, DEOBF_NAMESPACE)
|
val mappingSet = MappingFormats.TINY.read(mappings.path, SPIGOT_NAMESPACE, DEOBF_NAMESPACE)
|
||||||
|
|
||||||
val resultAt = at.remap(mappingSet)
|
val resultAt = at.remap(mappingSet)
|
||||||
AccessTransformFormats.FML.write(outputFile.path, resultAt)
|
AccessTransformFormats.FML.writeLF(outputFile.path, resultAt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ import org.gradle.kotlin.dsl.*
|
||||||
import org.gradle.workers.WorkAction
|
import org.gradle.workers.WorkAction
|
||||||
import org.gradle.workers.WorkParameters
|
import org.gradle.workers.WorkParameters
|
||||||
import org.gradle.workers.WorkerExecutor
|
import org.gradle.workers.WorkerExecutor
|
||||||
|
import writeLF
|
||||||
|
|
||||||
@CacheableTask
|
@CacheableTask
|
||||||
abstract class RemapSources : JavaLauncherTask() {
|
abstract class RemapSources : JavaLauncherTask() {
|
||||||
|
@ -260,7 +261,7 @@ abstract class RemapSources : JavaLauncherTask() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (generatedAtOutPath != null) {
|
if (generatedAtOutPath != null) {
|
||||||
AccessTransformFormats.FML.write(generatedAtOutPath, processAt)
|
AccessTransformFormats.FML.writeLF(generatedAtOutPath, processAt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,6 +40,7 @@ import org.gradle.api.tasks.OutputFile
|
||||||
import org.gradle.api.tasks.PathSensitive
|
import org.gradle.api.tasks.PathSensitive
|
||||||
import org.gradle.api.tasks.PathSensitivity
|
import org.gradle.api.tasks.PathSensitivity
|
||||||
import org.gradle.api.tasks.TaskAction
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
import writeLF
|
||||||
|
|
||||||
@CacheableTask
|
@CacheableTask
|
||||||
abstract class RemapSpigotAt : BaseTask() {
|
abstract class RemapSpigotAt : BaseTask() {
|
||||||
|
@ -108,7 +109,7 @@ abstract class RemapSpigotAt : BaseTask() {
|
||||||
val mappings = MappingFormats.TINY.read(mapping.path, SPIGOT_NAMESPACE, DEOBF_NAMESPACE)
|
val mappings = MappingFormats.TINY.read(mapping.path, SPIGOT_NAMESPACE, DEOBF_NAMESPACE)
|
||||||
val remappedAt = outputAt.remap(mappings)
|
val remappedAt = outputAt.remap(mappings)
|
||||||
|
|
||||||
AccessTransformFormats.FML.write(outputFile.path, remappedAt)
|
AccessTransformFormats.FML.writeLF(outputFile.path, remappedAt)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseAccess(text: String): AccessTransform {
|
private fun parseAccess(text: String): AccessTransform {
|
||||||
|
|
|
@ -71,6 +71,9 @@ abstract class DownloadTask : DefaultTask() {
|
||||||
fun run() = downloader.get().download(url, outputFile, expectedHash.orNull)
|
fun run() = downloader.get().download(url, outputFile, expectedHash.orNull)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@CacheableTask
|
||||||
|
abstract class CacheableDownloadTask : DownloadTask()
|
||||||
|
|
||||||
@CacheableTask
|
@CacheableTask
|
||||||
abstract class DownloadMcLibraries : BaseTask() {
|
abstract class DownloadMcLibraries : BaseTask() {
|
||||||
|
|
||||||
|
@ -100,7 +103,7 @@ abstract class DownloadMcLibraries : BaseTask() {
|
||||||
|
|
||||||
@TaskAction
|
@TaskAction
|
||||||
fun run() {
|
fun run() {
|
||||||
downloadMinecraftLibraries(
|
downloadLibraries(
|
||||||
downloader,
|
downloader,
|
||||||
workerExecutor,
|
workerExecutor,
|
||||||
outputDir.path,
|
outputDir.path,
|
||||||
|
@ -111,20 +114,62 @@ abstract class DownloadMcLibraries : BaseTask() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun downloadMinecraftLibraries(
|
@CacheableTask
|
||||||
|
abstract class DownloadPaperLibraries : BaseTask() {
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
abstract val paperDependencies: ListProperty<String>
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
abstract val repositories: ListProperty<String>
|
||||||
|
|
||||||
|
@get:OutputDirectory
|
||||||
|
abstract val outputDir: DirectoryProperty
|
||||||
|
|
||||||
|
@get:Internal
|
||||||
|
abstract val downloader: Property<DownloadService>
|
||||||
|
|
||||||
|
@get:Inject
|
||||||
|
abstract val workerExecutor: WorkerExecutor
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
abstract val sources: Property<Boolean>
|
||||||
|
|
||||||
|
override fun init() {
|
||||||
|
super.init()
|
||||||
|
sources.convention(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
fun run() {
|
||||||
|
downloadLibraries(
|
||||||
|
downloader,
|
||||||
|
workerExecutor,
|
||||||
|
outputDir.path,
|
||||||
|
repositories.get(),
|
||||||
|
paperDependencies.get(),
|
||||||
|
sources.get()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun downloadLibraries(
|
||||||
download: Provider<DownloadService>,
|
download: Provider<DownloadService>,
|
||||||
workerExecutor: WorkerExecutor,
|
workerExecutor: WorkerExecutor,
|
||||||
targetDir: Path,
|
targetDir: Path,
|
||||||
repositories: List<String>,
|
repositories: List<String>,
|
||||||
mcLibraries: List<String>,
|
libraries: List<String>,
|
||||||
sources: Boolean
|
sources: Boolean
|
||||||
): WorkQueue {
|
): WorkQueue {
|
||||||
val excludes = listOf(targetDir.fileSystem.getPathMatcher("glob:*.etag"))
|
val excludes = listOf(targetDir.fileSystem.getPathMatcher("glob:*.etag"))
|
||||||
targetDir.deleteRecursive(excludes)
|
targetDir.deleteRecursive(excludes)
|
||||||
|
if (!targetDir.exists()) {
|
||||||
|
targetDir.createDirectories()
|
||||||
|
}
|
||||||
|
|
||||||
val queue = workerExecutor.noIsolation()
|
val queue = workerExecutor.noIsolation()
|
||||||
|
|
||||||
for (lib in mcLibraries) {
|
for (lib in libraries) {
|
||||||
if (sources) {
|
if (sources) {
|
||||||
queue.submit(DownloadSourcesToDirAction::class) {
|
queue.submit(DownloadSourcesToDirAction::class) {
|
||||||
repos.set(repositories)
|
repos.set(repositories)
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
/*
|
||||||
|
* 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.mache
|
||||||
|
|
||||||
|
import io.papermc.paperweight.util.*
|
||||||
|
import io.papermc.paperweight.util.constants.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.io.path.absolutePathString
|
||||||
|
import kotlin.io.path.deleteIfExists
|
||||||
|
import kotlin.io.path.name
|
||||||
|
import kotlin.io.path.outputStream
|
||||||
|
import kotlin.io.path.writeText
|
||||||
|
import org.gradle.api.DefaultTask
|
||||||
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
|
import org.gradle.api.file.ProjectLayout
|
||||||
|
import org.gradle.api.file.RegularFileProperty
|
||||||
|
import org.gradle.api.provider.ListProperty
|
||||||
|
import org.gradle.api.tasks.CacheableTask
|
||||||
|
import org.gradle.api.tasks.Classpath
|
||||||
|
import org.gradle.api.tasks.CompileClasspath
|
||||||
|
import org.gradle.api.tasks.Input
|
||||||
|
import org.gradle.api.tasks.InputFile
|
||||||
|
import org.gradle.api.tasks.OutputFile
|
||||||
|
import org.gradle.api.tasks.PathSensitive
|
||||||
|
import org.gradle.api.tasks.PathSensitivity
|
||||||
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
import org.gradle.process.ExecOperations
|
||||||
|
|
||||||
|
@CacheableTask
|
||||||
|
abstract class DecompileJar : DefaultTask() {
|
||||||
|
|
||||||
|
@get:PathSensitive(PathSensitivity.NONE)
|
||||||
|
@get:InputFile
|
||||||
|
abstract val inputJar: RegularFileProperty
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
abstract val decompilerArgs: ListProperty<String>
|
||||||
|
|
||||||
|
@get:CompileClasspath
|
||||||
|
abstract val minecraftClasspath: ConfigurableFileCollection
|
||||||
|
|
||||||
|
@get:Classpath
|
||||||
|
abstract val decompiler: ConfigurableFileCollection
|
||||||
|
|
||||||
|
@get:OutputFile
|
||||||
|
abstract val outputJar: RegularFileProperty
|
||||||
|
|
||||||
|
@get:Inject
|
||||||
|
abstract val exec: ExecOperations
|
||||||
|
|
||||||
|
@get:Inject
|
||||||
|
abstract val layout: ProjectLayout
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
fun run() {
|
||||||
|
val out = outputJar.convertToPath().ensureClean()
|
||||||
|
|
||||||
|
val cfgFile = layout.buildDirectory.file(DECOMP_CFG).convertToPath().ensureClean()
|
||||||
|
val cfgText = buildString {
|
||||||
|
for (file in minecraftClasspath.files) {
|
||||||
|
append("-e=")
|
||||||
|
append(file.toPath().absolutePathString())
|
||||||
|
append(System.lineSeparator())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cfgFile.writeText(cfgText)
|
||||||
|
|
||||||
|
val logs = out.resolveSibling("${out.name}.log")
|
||||||
|
|
||||||
|
logs.outputStream().buffered().use { log ->
|
||||||
|
exec.javaexec {
|
||||||
|
classpath(decompiler)
|
||||||
|
mainClass.set("org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler")
|
||||||
|
|
||||||
|
maxHeapSize = "3G"
|
||||||
|
|
||||||
|
args(decompilerArgs.get())
|
||||||
|
args("-cfg", cfgFile.absolutePathString())
|
||||||
|
|
||||||
|
args(inputJar.convertToPath().absolutePathString())
|
||||||
|
args(out.absolutePathString())
|
||||||
|
|
||||||
|
standardOutput = log
|
||||||
|
errorOutput = log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.openZip().use { root ->
|
||||||
|
root.getPath("META-INF", "MANIFEST.MF").deleteIfExists()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* 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.mache
|
||||||
|
|
||||||
|
import io.papermc.paperweight.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.io.path.*
|
||||||
|
import org.gradle.api.DefaultTask
|
||||||
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
|
import org.gradle.api.file.ProjectLayout
|
||||||
|
import org.gradle.api.file.RegularFileProperty
|
||||||
|
import org.gradle.api.provider.ListProperty
|
||||||
|
import org.gradle.api.tasks.*
|
||||||
|
import org.gradle.process.ExecOperations
|
||||||
|
|
||||||
|
@CacheableTask
|
||||||
|
abstract class RemapJar : DefaultTask() {
|
||||||
|
|
||||||
|
@get:PathSensitive(PathSensitivity.NONE)
|
||||||
|
@get:InputFile
|
||||||
|
abstract val serverJar: RegularFileProperty
|
||||||
|
|
||||||
|
@get:PathSensitive(PathSensitivity.NONE)
|
||||||
|
@get:InputFile
|
||||||
|
abstract val serverMappings: RegularFileProperty
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
abstract val remapperArgs: ListProperty<String>
|
||||||
|
|
||||||
|
@get:Classpath
|
||||||
|
abstract val codebookClasspath: ConfigurableFileCollection
|
||||||
|
|
||||||
|
@get:CompileClasspath
|
||||||
|
abstract val minecraftClasspath: ConfigurableFileCollection
|
||||||
|
|
||||||
|
@get:Classpath
|
||||||
|
abstract val remapperClasspath: ConfigurableFileCollection
|
||||||
|
|
||||||
|
@get:PathSensitive(PathSensitivity.NONE)
|
||||||
|
@get:InputFiles
|
||||||
|
abstract val paramMappings: ConfigurableFileCollection
|
||||||
|
|
||||||
|
@get:Classpath
|
||||||
|
abstract val constants: ConfigurableFileCollection
|
||||||
|
|
||||||
|
@get:OutputFile
|
||||||
|
abstract val outputJar: RegularFileProperty
|
||||||
|
|
||||||
|
@get:Inject
|
||||||
|
abstract val exec: ExecOperations
|
||||||
|
|
||||||
|
@get:Inject
|
||||||
|
abstract val layout: ProjectLayout
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
fun run() {
|
||||||
|
val out = outputJar.convertToPath().ensureClean()
|
||||||
|
|
||||||
|
val logFile = out.resolveSibling("${out.name}.log")
|
||||||
|
|
||||||
|
logFile.outputStream().buffered().use { log ->
|
||||||
|
exec.javaexec {
|
||||||
|
classpath(codebookClasspath.singleFile)
|
||||||
|
|
||||||
|
maxHeapSize = "2G"
|
||||||
|
|
||||||
|
remapperArgs.get().forEach { arg ->
|
||||||
|
args(
|
||||||
|
arg
|
||||||
|
.replace(Regex("\\{tempDir}")) { layout.buildDirectory.dir(".tmp_codebook").get().asFile.absolutePath }
|
||||||
|
.replace(Regex("\\{remapperFile}")) { remapperClasspath.singleFile.absolutePath }
|
||||||
|
.replace(Regex("\\{mappingsFile}")) { serverMappings.get().asFile.absolutePath }
|
||||||
|
.replace(Regex("\\{paramsFile}")) { paramMappings.singleFile.absolutePath }
|
||||||
|
.replace(Regex("\\{constantsFile}")) { constants.singleFile.absolutePath }
|
||||||
|
.replace(Regex("\\{output}")) { outputJar.get().asFile.absolutePath }
|
||||||
|
.replace(Regex("\\{input}")) { serverJar.get().asFile.absolutePath }
|
||||||
|
.replace(Regex("\\{inputClasspath}")) { minecraftClasspath.files.joinToString(":") { it.absolutePath } }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
standardOutput = log
|
||||||
|
errorOutput = log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,198 @@
|
||||||
|
/*
|
||||||
|
* 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.mache
|
||||||
|
|
||||||
|
import codechicken.diffpatch.cli.PatchOperation
|
||||||
|
import codechicken.diffpatch.util.LoggingOutputStream
|
||||||
|
import codechicken.diffpatch.util.archiver.ArchiveFormat
|
||||||
|
import io.papermc.paperweight.tasks.*
|
||||||
|
import io.papermc.paperweight.util.*
|
||||||
|
import io.papermc.restamp.Restamp
|
||||||
|
import io.papermc.restamp.RestampContextConfiguration
|
||||||
|
import io.papermc.restamp.RestampInput
|
||||||
|
import java.nio.file.Path
|
||||||
|
import java.util.function.Predicate
|
||||||
|
import kotlin.io.path.*
|
||||||
|
import org.cadixdev.at.io.AccessTransformFormats
|
||||||
|
import org.eclipse.jgit.api.Git
|
||||||
|
import org.eclipse.jgit.api.ResetCommand
|
||||||
|
import org.eclipse.jgit.lib.PersonIdent
|
||||||
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
|
import org.gradle.api.file.DirectoryProperty
|
||||||
|
import org.gradle.api.file.RegularFileProperty
|
||||||
|
import org.gradle.api.logging.LogLevel
|
||||||
|
import org.gradle.api.provider.Property
|
||||||
|
import org.gradle.api.tasks.*
|
||||||
|
import org.openrewrite.InMemoryExecutionContext
|
||||||
|
|
||||||
|
abstract class SetupVanilla : BaseTask() {
|
||||||
|
|
||||||
|
@get:PathSensitive(PathSensitivity.NONE)
|
||||||
|
@get:InputFile
|
||||||
|
abstract val inputFile: RegularFileProperty
|
||||||
|
|
||||||
|
@get:Internal
|
||||||
|
abstract val predicate: Property<Predicate<Path>>
|
||||||
|
|
||||||
|
@get:OutputDirectory
|
||||||
|
abstract val outputDir: DirectoryProperty
|
||||||
|
|
||||||
|
@get:Internal
|
||||||
|
abstract val machePatches: DirectoryProperty
|
||||||
|
|
||||||
|
@get:Optional
|
||||||
|
@get:InputFile
|
||||||
|
@get:PathSensitive(PathSensitivity.NONE)
|
||||||
|
abstract val ats: RegularFileProperty
|
||||||
|
|
||||||
|
@get:Optional
|
||||||
|
@get:InputFiles
|
||||||
|
abstract val libraries: ConfigurableFileCollection
|
||||||
|
|
||||||
|
@get:Optional
|
||||||
|
@get:InputFiles
|
||||||
|
abstract val paperPatches: ConfigurableFileCollection
|
||||||
|
|
||||||
|
@get:Optional
|
||||||
|
@get:InputFile
|
||||||
|
abstract val devImports: RegularFileProperty
|
||||||
|
|
||||||
|
@get:Optional
|
||||||
|
@get:CompileClasspath
|
||||||
|
abstract val minecraftClasspath: ConfigurableFileCollection
|
||||||
|
|
||||||
|
@get:Optional
|
||||||
|
@get:Classpath
|
||||||
|
abstract val mache: ConfigurableFileCollection
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
fun run() {
|
||||||
|
val outputPath = outputDir.convertToPath()
|
||||||
|
|
||||||
|
val git: Git
|
||||||
|
if (outputPath.resolve(".git/HEAD").isRegularFile()) {
|
||||||
|
git = Git.open(outputPath.toFile())
|
||||||
|
git.reset().setRef("ROOT").setMode(ResetCommand.ResetType.HARD).call()
|
||||||
|
} else {
|
||||||
|
outputPath.createDirectories()
|
||||||
|
|
||||||
|
git = Git.init()
|
||||||
|
.setDirectory(outputPath.toFile())
|
||||||
|
.setInitialBranch("main")
|
||||||
|
.call()
|
||||||
|
|
||||||
|
val rootIdent = PersonIdent("ROOT", "root@automated.papermc.io")
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
println("Copy initial sources...")
|
||||||
|
inputFile.convertToPath().openZip().walk()
|
||||||
|
.filter(predicate.get())
|
||||||
|
.forEach {
|
||||||
|
val target = outputPath.resolve(it.toString().substring(1))
|
||||||
|
target.parent.createDirectories()
|
||||||
|
// make sure we have a trailing newline
|
||||||
|
var content = it.readText()
|
||||||
|
if (!content.endsWith("\n")) {
|
||||||
|
content += "\n"
|
||||||
|
}
|
||||||
|
target.writeText(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
println("Setup git repo...")
|
||||||
|
commitAndTag(git, "Vanilla")
|
||||||
|
|
||||||
|
if (machePatches.isPresent) {
|
||||||
|
println("Applying mache patches...")
|
||||||
|
|
||||||
|
val result = PatchOperation.builder()
|
||||||
|
.logTo(LoggingOutputStream(logger, LogLevel.LIFECYCLE))
|
||||||
|
.basePath(outputPath.convertToPath())
|
||||||
|
.outputPath(outputPath.convertToPath())
|
||||||
|
.patchesPath(mache.singleFile.toPath(), ArchiveFormat.ZIP)
|
||||||
|
.patchesPrefix("patches")
|
||||||
|
.level(codechicken.diffpatch.util.LogLevel.INFO)
|
||||||
|
.ignorePrefix(".git")
|
||||||
|
.build()
|
||||||
|
.operate()
|
||||||
|
|
||||||
|
commitAndTag(git, "Mache")
|
||||||
|
|
||||||
|
if (result.exit != 0) {
|
||||||
|
throw Exception("Failed to apply ${result.summary.failedMatches} mache patches")
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.lifecycle("Applied ${result.summary.changedFiles} mache patches")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ats.isPresent) {
|
||||||
|
val classPath = minecraftClasspath.files.map { it.toPath() }.toMutableList()
|
||||||
|
classPath.add(outputPath)
|
||||||
|
|
||||||
|
println("Applying access transformers...")
|
||||||
|
val configuration = RestampContextConfiguration.builder()
|
||||||
|
.accessTransformers(ats.convertToPath(), AccessTransformFormats.FML)
|
||||||
|
.sourceRoot(outputPath)
|
||||||
|
.sourceFilesFromAccessTransformers(false)
|
||||||
|
.classpath(classPath)
|
||||||
|
.executionContext(InMemoryExecutionContext { it.printStackTrace() })
|
||||||
|
.failWithNotApplicableAccessTransformers()
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val parsedInput = RestampInput.parseFrom(configuration)
|
||||||
|
val results = Restamp.run(parsedInput).allResults
|
||||||
|
|
||||||
|
results.forEach { result ->
|
||||||
|
if (result.after != null) {
|
||||||
|
outputPath.resolve(result.after!!.sourcePath).writeText(result.after!!.printAll())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
commitAndTag(git, "ATs")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!libraries.isEmpty && !paperPatches.isEmpty) {
|
||||||
|
val patches = paperPatches.files.flatMap { it.toPath().walk().filter { path -> path.toString().endsWith(".patch") }.toList() }
|
||||||
|
McDev.importMcDev(patches, null, devImports.pathOrNull, outputPath, null, libraries.files.map { it.toPath() }, true, "")
|
||||||
|
|
||||||
|
commitAndTag(git, "Imports")
|
||||||
|
}
|
||||||
|
|
||||||
|
git.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun commitAndTag(git: Git, name: String) {
|
||||||
|
val vanillaIdent = PersonIdent(name, "${name.lowercase()}@automated.papermc.io")
|
||||||
|
|
||||||
|
git.add().addFilepattern(".").call()
|
||||||
|
git.commit()
|
||||||
|
.setMessage(name)
|
||||||
|
.setAuthor(vanillaIdent)
|
||||||
|
.setSign(false)
|
||||||
|
.call()
|
||||||
|
git.tagDelete().setTags(name).call()
|
||||||
|
git.tag().setName(name).setTagger(vanillaIdent).setSigned(false).call()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/*
|
||||||
|
* 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.softspoon
|
||||||
|
|
||||||
|
import io.papermc.paperweight.tasks.*
|
||||||
|
import io.papermc.paperweight.util.*
|
||||||
|
import javax.inject.Inject
|
||||||
|
import org.gradle.api.file.DirectoryProperty
|
||||||
|
import org.gradle.api.provider.Property
|
||||||
|
import org.gradle.api.provider.ProviderFactory
|
||||||
|
import org.gradle.api.tasks.Input
|
||||||
|
import org.gradle.api.tasks.InputDirectory
|
||||||
|
import org.gradle.api.tasks.PathSensitive
|
||||||
|
import org.gradle.api.tasks.PathSensitivity
|
||||||
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
import org.gradle.api.tasks.UntrackedTask
|
||||||
|
|
||||||
|
@UntrackedTask(because = "Always apply patches")
|
||||||
|
abstract class ApplyFeaturePatches : ControllableOutputTask() {
|
||||||
|
|
||||||
|
@get:PathSensitive(PathSensitivity.NONE)
|
||||||
|
@get:InputDirectory
|
||||||
|
abstract val repo: DirectoryProperty
|
||||||
|
|
||||||
|
@get:PathSensitive(PathSensitivity.NONE)
|
||||||
|
@get:InputDirectory
|
||||||
|
abstract val patches: DirectoryProperty
|
||||||
|
|
||||||
|
@get:Inject
|
||||||
|
abstract val providers: ProviderFactory
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
abstract val verbose: Property<Boolean>
|
||||||
|
|
||||||
|
override fun init() {
|
||||||
|
printOutput.convention(false).finalizeValueOnRead()
|
||||||
|
verbose.convention(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
fun run() {
|
||||||
|
Git.checkForGit()
|
||||||
|
|
||||||
|
val repoPath = repo.convertToPath()
|
||||||
|
|
||||||
|
val git = Git(repoPath)
|
||||||
|
|
||||||
|
if (git("checkout", "main").runSilently(silenceErr = true) != 0) {
|
||||||
|
git("checkout", "-b", "main").runSilently(silenceErr = true)
|
||||||
|
}
|
||||||
|
git("reset", "--hard", "file").executeSilently(silenceErr = true)
|
||||||
|
git("gc").runSilently(silenceErr = true)
|
||||||
|
|
||||||
|
applyGitPatches(git, "server repo", repoPath, patches.convertToPath(), printOutput.get(), verbose.get())
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
* 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.softspoon
|
||||||
|
|
||||||
|
import codechicken.diffpatch.cli.PatchOperation
|
||||||
|
import codechicken.diffpatch.match.FuzzyLineMatcher
|
||||||
|
import codechicken.diffpatch.util.LoggingOutputStream
|
||||||
|
import codechicken.diffpatch.util.PatchMode
|
||||||
|
import io.papermc.paperweight.tasks.*
|
||||||
|
import io.papermc.paperweight.util.*
|
||||||
|
import java.io.PrintStream
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.*
|
||||||
|
import org.eclipse.jgit.api.Git
|
||||||
|
import org.eclipse.jgit.lib.PersonIdent
|
||||||
|
import org.gradle.api.file.DirectoryProperty
|
||||||
|
import org.gradle.api.logging.LogLevel
|
||||||
|
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.PathSensitive
|
||||||
|
import org.gradle.api.tasks.PathSensitivity
|
||||||
|
import org.gradle.api.tasks.TaskAction
|
||||||
|
import org.gradle.api.tasks.UntrackedTask
|
||||||
|
import org.gradle.api.tasks.options.Option
|
||||||
|
|
||||||
|
@UntrackedTask(because = "Always apply patches")
|
||||||
|
abstract class ApplyFilePatches : BaseTask() {
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
@get:Option(
|
||||||
|
option = "verbose",
|
||||||
|
description = "Prints out more info about the patching process",
|
||||||
|
)
|
||||||
|
abstract val verbose: Property<Boolean>
|
||||||
|
|
||||||
|
@get:PathSensitive(PathSensitivity.NONE)
|
||||||
|
@get:InputDirectory
|
||||||
|
abstract val input: DirectoryProperty
|
||||||
|
|
||||||
|
@get:OutputDirectory
|
||||||
|
abstract val output: DirectoryProperty
|
||||||
|
|
||||||
|
@get:PathSensitive(PathSensitivity.NONE)
|
||||||
|
@get:InputDirectory
|
||||||
|
abstract val patches: DirectoryProperty
|
||||||
|
|
||||||
|
init {
|
||||||
|
run {
|
||||||
|
verbose.convention(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
open fun run() {
|
||||||
|
io.papermc.paperweight.util.Git.checkForGit()
|
||||||
|
|
||||||
|
val outputPath = output.convertToPath()
|
||||||
|
recreateCloneDirectory(outputPath)
|
||||||
|
|
||||||
|
checkoutRepoFromUpstream(Git(outputPath), input.convertToPath(), "main", "mache", "main")
|
||||||
|
|
||||||
|
setupGitHook(outputPath)
|
||||||
|
|
||||||
|
val printStream = PrintStream(LoggingOutputStream(logger, LogLevel.LIFECYCLE))
|
||||||
|
val result = PatchOperation.builder()
|
||||||
|
.logTo(printStream)
|
||||||
|
.basePath(output.convertToPath())
|
||||||
|
.patchesPath(patches.convertToPath())
|
||||||
|
.outputPath(output.convertToPath())
|
||||||
|
.level(if (verbose.get()) codechicken.diffpatch.util.LogLevel.ALL else codechicken.diffpatch.util.LogLevel.INFO)
|
||||||
|
.mode(mode())
|
||||||
|
.minFuzz(minFuzz())
|
||||||
|
.summary(verbose.get())
|
||||||
|
.lineEnding("\n")
|
||||||
|
.ignorePrefix(".git")
|
||||||
|
.build()
|
||||||
|
.operate()
|
||||||
|
|
||||||
|
commit()
|
||||||
|
|
||||||
|
if (result.exit != 0) {
|
||||||
|
val total = result.summary.failedMatches + result.summary.exactMatches +
|
||||||
|
result.summary.accessMatches + result.summary.offsetMatches + result.summary.fuzzyMatches
|
||||||
|
throw Exception("Failed to apply ${result.summary.failedMatches}/$total hunks")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!verbose.get()) {
|
||||||
|
logger.lifecycle("Applied ${result.summary.changedFiles} patches")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupGitHook(outputPath: Path) {
|
||||||
|
val hook = outputPath.resolve(".git/hooks/post-rewrite")
|
||||||
|
hook.parent.createDirectories()
|
||||||
|
hook.writeText(javaClass.getResource("/post-rewrite.sh")!!.readText())
|
||||||
|
hook.toFile().setExecutable(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun commit() {
|
||||||
|
val ident = PersonIdent("File", "filepatches@automated.papermc.io")
|
||||||
|
val git = Git.open(output.convertToPath().toFile())
|
||||||
|
git.add().addFilepattern(".").call()
|
||||||
|
git.commit()
|
||||||
|
.setMessage("File Patches")
|
||||||
|
.setAuthor(ident)
|
||||||
|
.setSign(false)
|
||||||
|
.call()
|
||||||
|
git.tagDelete().setTags("file").call()
|
||||||
|
git.tag().setName("file").setTagger(ident).setSigned(false).call()
|
||||||
|
git.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
internal open fun mode(): PatchMode {
|
||||||
|
return PatchMode.OFFSET
|
||||||
|
}
|
||||||
|
|
||||||
|
internal open fun minFuzz(): Float {
|
||||||
|
return FuzzyLineMatcher.DEFAULT_MIN_MATCH_SCORE
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* 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.softspoon
|
||||||
|
import codechicken.diffpatch.util.PatchMode
|
||||||
|
import org.gradle.api.provider.Property
|
||||||
|
import org.gradle.api.tasks.Input
|
||||||
|
import org.gradle.api.tasks.UntrackedTask
|
||||||
|
import org.gradle.api.tasks.options.Option
|
||||||
|
|
||||||
|
@UntrackedTask(because = "Always apply patches")
|
||||||
|
abstract class ApplyFilePatchesFuzzy : ApplyFilePatches() {
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
@get:Option(
|
||||||
|
option = "min-fuzz",
|
||||||
|
description = "Min fuzz. The minimum quality needed for a patch to be applied. Default is 0.5.",
|
||||||
|
)
|
||||||
|
abstract val minFuzz: Property<String>
|
||||||
|
|
||||||
|
init {
|
||||||
|
run {
|
||||||
|
minFuzz.convention("0.5")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mode(): PatchMode {
|
||||||
|
return PatchMode.FUZZY
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun minFuzz(): Float {
|
||||||
|
return minFuzz.get().toFloat()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* 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.softspoon
|
||||||
|
|
||||||
|
import io.papermc.paperweight.tasks.*
|
||||||
|
import io.papermc.paperweight.util.*
|
||||||
|
import io.papermc.restamp.Restamp
|
||||||
|
import io.papermc.restamp.RestampContextConfiguration
|
||||||
|
import io.papermc.restamp.RestampInput
|
||||||
|
import java.nio.file.Files
|
||||||
|
import javax.inject.Inject
|
||||||
|
import kotlin.io.path.*
|
||||||
|
import org.cadixdev.at.io.AccessTransformFormats
|
||||||
|
import org.gradle.api.file.ConfigurableFileCollection
|
||||||
|
import org.gradle.api.file.RegularFileProperty
|
||||||
|
import org.gradle.api.tasks.*
|
||||||
|
import org.gradle.kotlin.dsl.*
|
||||||
|
import org.gradle.workers.WorkAction
|
||||||
|
import org.gradle.workers.WorkParameters
|
||||||
|
import org.gradle.workers.WorkerExecutor
|
||||||
|
import org.openrewrite.InMemoryExecutionContext
|
||||||
|
|
||||||
|
@CacheableTask
|
||||||
|
abstract class ApplySourceAT : BaseTask() {
|
||||||
|
|
||||||
|
@get:Classpath
|
||||||
|
abstract val inputJar: RegularFileProperty
|
||||||
|
|
||||||
|
@get:OutputFile
|
||||||
|
abstract val outputJar: RegularFileProperty
|
||||||
|
|
||||||
|
@get:Optional
|
||||||
|
@get:InputFile
|
||||||
|
@get:PathSensitive(PathSensitivity.NONE)
|
||||||
|
abstract val atFile: RegularFileProperty
|
||||||
|
|
||||||
|
@get:Optional
|
||||||
|
@get:CompileClasspath
|
||||||
|
abstract val minecraftClasspath: ConfigurableFileCollection
|
||||||
|
|
||||||
|
@get:Inject
|
||||||
|
abstract val worker: WorkerExecutor
|
||||||
|
|
||||||
|
override fun init() {
|
||||||
|
outputJar.convention(defaultOutput())
|
||||||
|
}
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
fun run() {
|
||||||
|
val queue = worker.processIsolation {
|
||||||
|
forkOptions {
|
||||||
|
maxHeapSize = "2G"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val classPath = minecraftClasspath.files.map { it.toPath() }.toMutableList()
|
||||||
|
classPath.add(inputJar.convertToPath())
|
||||||
|
|
||||||
|
queue.submit(RestampWorker::class) {
|
||||||
|
minecraftClasspath.from(minecraftClasspath)
|
||||||
|
atFile.set(atFile)
|
||||||
|
inputJar.set(inputJar)
|
||||||
|
outputJar.set(outputJar)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class RestampWorker : WorkAction<RestampWorker.Params> {
|
||||||
|
interface Params : WorkParameters {
|
||||||
|
val minecraftClasspath: ConfigurableFileCollection
|
||||||
|
val atFile: RegularFileProperty
|
||||||
|
val inputJar: RegularFileProperty
|
||||||
|
val outputJar: RegularFileProperty
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun execute() {
|
||||||
|
val inputZip = parameters.inputJar.convertToPath().openZip()
|
||||||
|
|
||||||
|
val classPath = parameters.minecraftClasspath.files.map { it.toPath() }.toMutableList()
|
||||||
|
classPath.add(parameters.inputJar.convertToPath())
|
||||||
|
|
||||||
|
val configuration = RestampContextConfiguration.builder()
|
||||||
|
.accessTransformers(parameters.atFile.convertToPath(), AccessTransformFormats.FML)
|
||||||
|
.sourceRoot(inputZip.getPath("/"))
|
||||||
|
.sourceFilesFromAccessTransformers()
|
||||||
|
.classpath(classPath)
|
||||||
|
.executionContext(InMemoryExecutionContext { it.printStackTrace() })
|
||||||
|
.failWithNotApplicableAccessTransformers()
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val parsedInput = RestampInput.parseFrom(configuration)
|
||||||
|
val results = Restamp.run(parsedInput).allResults
|
||||||
|
|
||||||
|
parameters.outputJar.convertToPath().writeZip().use { zip ->
|
||||||
|
val alreadyWritten = mutableSetOf<String>()
|
||||||
|
results.forEach { result ->
|
||||||
|
if (result.after == null) {
|
||||||
|
println("Ignoring ${result.before?.sourcePath} because result.after is null?")
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
result.after?.let { after ->
|
||||||
|
zip.getPath(after.sourcePath.toString()).writeText(after.printAll())
|
||||||
|
alreadyWritten.add("/" + after.sourcePath.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inputZip.walk().filter { Files.isRegularFile(it) }.filter { !alreadyWritten.contains(it.toString()) }.forEach { file ->
|
||||||
|
zip.getPath(file.toString()).writeText(file.readText())
|
||||||
|
}
|
||||||
|
|
||||||
|
zip.close()
|
||||||
|
}
|
||||||
|
inputZip.close()
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,210 @@
|
||||||
|
/*
|
||||||
|
* 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.softspoon
|
||||||
|
|
||||||
|
import atFromString
|
||||||
|
import codechicken.diffpatch.cli.DiffOperation
|
||||||
|
import codechicken.diffpatch.util.LogLevel
|
||||||
|
import codechicken.diffpatch.util.LoggingOutputStream
|
||||||
|
import io.papermc.paperweight.tasks.*
|
||||||
|
import io.papermc.paperweight.util.*
|
||||||
|
import io.papermc.restamp.Restamp
|
||||||
|
import io.papermc.restamp.RestampContextConfiguration
|
||||||
|
import io.papermc.restamp.RestampInput
|
||||||
|
import java.io.PrintStream
|
||||||
|
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.gradle.api.file.ConfigurableFileCollection
|
||||||
|
import org.gradle.api.file.DirectoryProperty
|
||||||
|
import org.gradle.api.file.RegularFileProperty
|
||||||
|
import org.gradle.api.provider.Property
|
||||||
|
import org.gradle.api.tasks.*
|
||||||
|
import org.gradle.api.tasks.options.Option
|
||||||
|
import org.openrewrite.InMemoryExecutionContext
|
||||||
|
import writeLF
|
||||||
|
|
||||||
|
@UntrackedTask(because = "Always rebuild patches")
|
||||||
|
abstract class RebuildFilePatches : BaseTask() {
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
@get:Option(
|
||||||
|
option = "verbose",
|
||||||
|
description = "Prints out more info about the patching process",
|
||||||
|
)
|
||||||
|
abstract val verbose: Property<Boolean>
|
||||||
|
|
||||||
|
@get:InputDirectory
|
||||||
|
abstract val input: DirectoryProperty
|
||||||
|
|
||||||
|
@get:InputDirectory
|
||||||
|
abstract val base: DirectoryProperty
|
||||||
|
|
||||||
|
@get:OutputDirectory
|
||||||
|
abstract val patches: DirectoryProperty
|
||||||
|
|
||||||
|
@get:Optional
|
||||||
|
@get:InputFile
|
||||||
|
abstract val atFile: RegularFileProperty
|
||||||
|
|
||||||
|
@get:Optional
|
||||||
|
@get:OutputFile
|
||||||
|
abstract val atFileOut: RegularFileProperty
|
||||||
|
|
||||||
|
@get:Optional
|
||||||
|
@get:CompileClasspath
|
||||||
|
abstract val minecraftClasspath: ConfigurableFileCollection
|
||||||
|
|
||||||
|
@get:Input
|
||||||
|
abstract val contextLines: Property<Int>
|
||||||
|
|
||||||
|
override fun init() {
|
||||||
|
contextLines.convention(3)
|
||||||
|
verbose.convention(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
fun run() {
|
||||||
|
val patchDir = patches.convertToPath().ensureClean()
|
||||||
|
patchDir.createDirectory()
|
||||||
|
val inputDir = input.convertToPath()
|
||||||
|
val baseDir = base.convertToPath()
|
||||||
|
|
||||||
|
val oldAts = if (atFile.isPresent) AccessTransformFormats.FML.read(atFile.convertToPath()) else AccessTransformSet.create()
|
||||||
|
|
||||||
|
val git = Git(inputDir)
|
||||||
|
git("stash", "push").executeSilently(silenceErr = true)
|
||||||
|
git("checkout", "file").executeSilently(silenceErr = true)
|
||||||
|
|
||||||
|
// handle AT
|
||||||
|
baseDir.walk()
|
||||||
|
.map { it.relativeTo(baseDir).toString().replace("\\", "/") }
|
||||||
|
.filter {
|
||||||
|
!it.startsWith(".git") && !it.endsWith(".nbt") && !it.endsWith(".mcassetsroot")
|
||||||
|
}
|
||||||
|
.forEach {
|
||||||
|
val ats = AccessTransformSet.create()
|
||||||
|
val source = inputDir.resolve(it)
|
||||||
|
val decomp = baseDir.resolve(it)
|
||||||
|
val className = it.replace(".java", "")
|
||||||
|
handleATInSource(source, ats, className)
|
||||||
|
handleATInBase(decomp, ats, baseDir)
|
||||||
|
oldAts.merge(ats)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (atFileOut.isPresent) {
|
||||||
|
AccessTransformFormats.FML.writeLF(
|
||||||
|
atFileOut.convertToPath(),
|
||||||
|
oldAts,
|
||||||
|
"# This file is auto generated, any changes may be overridden!\n# See CONTRIBUTING.md on how to add access transformers.\n"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// rebuild patches
|
||||||
|
val printStream = PrintStream(LoggingOutputStream(logger, org.gradle.api.logging.LogLevel.LIFECYCLE))
|
||||||
|
val result = DiffOperation.builder()
|
||||||
|
.logTo(printStream)
|
||||||
|
.aPath(baseDir)
|
||||||
|
.bPath(inputDir)
|
||||||
|
.outputPath(patchDir)
|
||||||
|
.autoHeader(true)
|
||||||
|
.level(if (verbose.get()) LogLevel.ALL else LogLevel.INFO)
|
||||||
|
.lineEnding("\n")
|
||||||
|
.ignorePrefix(".git")
|
||||||
|
.ignorePrefix("data/minecraft/structures")
|
||||||
|
.ignorePrefix("data/.mc")
|
||||||
|
.ignorePrefix("assets/.mc")
|
||||||
|
.context(contextLines.get())
|
||||||
|
.summary(verbose.get())
|
||||||
|
.build()
|
||||||
|
.operate()
|
||||||
|
|
||||||
|
git("switch", "-").executeSilently(silenceErr = true)
|
||||||
|
git("stash", "pop").runSilently(silenceErr = true)
|
||||||
|
|
||||||
|
logger.lifecycle("Rebuilt ${result.summary.changedFiles} patches")
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleATInBase(decomp: Path, newAts: AccessTransformSet, decompRoot: Path) {
|
||||||
|
if (newAts.classes.isEmpty()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val configuration = RestampContextConfiguration.builder()
|
||||||
|
.accessTransformSet(newAts)
|
||||||
|
.sourceRoot(decompRoot)
|
||||||
|
.sourceFiles(listOf(decomp))
|
||||||
|
.classpath(minecraftClasspath.files.map { it.toPath() })
|
||||||
|
.executionContext(InMemoryExecutionContext { it.printStackTrace() })
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val parsedInput = RestampInput.parseFrom(configuration)
|
||||||
|
val results = Restamp.run(parsedInput).allResults
|
||||||
|
|
||||||
|
if (results.size != 1) {
|
||||||
|
logger.lifecycle("Failed to apply AT to ${decomp.fileName} (doesn't it already exist?): $results")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val result = results[0].after?.printAll()
|
||||||
|
if (result != null) {
|
||||||
|
decomp.writeText(result, Charsets.UTF_8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleATInSource(source: Path, newAts: AccessTransformSet, className: String) {
|
||||||
|
val sourceLines = source.readLines()
|
||||||
|
val fixedLines = ArrayList<String>(sourceLines.size)
|
||||||
|
var requiresWrite = false
|
||||||
|
sourceLines.forEach { line ->
|
||||||
|
if (!line.contains("// Paper-AT: ")) {
|
||||||
|
fixedLines.add(line)
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
|
||||||
|
requiresWrite = true
|
||||||
|
|
||||||
|
val split = line.split("// Paper-AT: ")
|
||||||
|
val at = split[1]
|
||||||
|
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")
|
||||||
|
|
||||||
|
fixedLines.add(split[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requiresWrite) {
|
||||||
|
source.writeText(fixedLines.joinToString("\n", postfix = "\n"), Charsets.UTF_8)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,16 +35,17 @@ object McDev {
|
||||||
|
|
||||||
fun importMcDev(
|
fun importMcDev(
|
||||||
patches: Iterable<Path>,
|
patches: Iterable<Path>,
|
||||||
decompJar: Path,
|
decompJar: Path?,
|
||||||
importsFile: Path?,
|
importsFile: Path?,
|
||||||
targetDir: Path,
|
targetDir: Path,
|
||||||
dataTargetDir: Path? = null,
|
dataTargetDir: Path? = null,
|
||||||
librariesDirs: List<Path> = listOf(),
|
librariesDirs: List<Path> = listOf(),
|
||||||
printOutput: Boolean = true
|
printOutput: Boolean = true,
|
||||||
|
javaSourceSet: String = "/src/main/java"
|
||||||
) {
|
) {
|
||||||
val (javaPatchLines, dataPatchLines) = readPatchLines(patches)
|
val (javaPatchLines, dataPatchLines) = readPatchLines(patches, javaSourceSet)
|
||||||
|
|
||||||
decompJar.openZip().use { zipFile ->
|
decompJar?.openZip()?.use { zipFile ->
|
||||||
val decompSourceFiles = mutableSetOf<String>()
|
val decompSourceFiles = mutableSetOf<String>()
|
||||||
val decompDataFiles = mutableSetOf<String>()
|
val decompDataFiles = mutableSetOf<String>()
|
||||||
|
|
||||||
|
@ -127,7 +128,7 @@ object McDev {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Import library classes
|
// Import library classes
|
||||||
val imports = findLibraries(importsFile, libFiles, javaPatchLines)
|
val imports = findLibraries(importsFile, libFiles, javaPatchLines, javaSourceSet)
|
||||||
logger.log(if (printOutput) LogLevel.LIFECYCLE else LogLevel.DEBUG, "Importing {} classes from library sources...", imports.size)
|
logger.log(if (printOutput) LogLevel.LIFECYCLE else LogLevel.DEBUG, "Importing {} classes from library sources...", imports.size)
|
||||||
|
|
||||||
for ((libraryFileName, importFilePath) in imports) {
|
for ((libraryFileName, importFilePath) in imports) {
|
||||||
|
@ -170,11 +171,11 @@ object McDev {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readPatchLines(patches: Iterable<Path>): Pair<Set<String>, Set<String>> {
|
private fun readPatchLines(patches: Iterable<Path>, javaSourceSet: String): Pair<Set<String>, Set<String>> {
|
||||||
val srcResult = hashSetOf<String>()
|
val srcResult = hashSetOf<String>()
|
||||||
val dataResult = hashSetOf<String>()
|
val dataResult = hashSetOf<String>()
|
||||||
|
|
||||||
val javaPrefix = "+++ b/src/main/java/"
|
val javaPrefix = "+++ b$javaSourceSet/"
|
||||||
val dataPrefix = "+++ b/src/main/resources/data/minecraft/"
|
val dataPrefix = "+++ b/src/main/resources/data/minecraft/"
|
||||||
|
|
||||||
for (patch in patches) {
|
for (patch in patches) {
|
||||||
|
@ -216,7 +217,7 @@ object McDev {
|
||||||
return Pair(srcResult, dataResult)
|
return Pair(srcResult, dataResult)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findLibraries(libraryImports: Path?, libFiles: List<Path>, patchLines: Set<String>): Set<LibraryImport> {
|
private fun findLibraries(libraryImports: Path?, libFiles: List<Path>, patchLines: Set<String>, javaSourceSet: String): Set<LibraryImport> {
|
||||||
val result = hashSetOf<LibraryImport>()
|
val result = hashSetOf<LibraryImport>()
|
||||||
|
|
||||||
// Imports from library-imports.txt
|
// Imports from library-imports.txt
|
||||||
|
@ -233,15 +234,15 @@ object McDev {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan patches for necessary imports
|
// Scan patches for necessary imports
|
||||||
result += findNeededLibraryImports(patchLines, libFiles)
|
result += findNeededLibraryImports(patchLines, libFiles, javaSourceSet)
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findNeededLibraryImports(patchLines: Set<String>, libFiles: List<Path>): Set<LibraryImport> {
|
private fun findNeededLibraryImports(patchLines: Set<String>, libFiles: List<Path>, javaSourceSet: String): Set<LibraryImport> {
|
||||||
val knownImportMap = findPossibleLibraryImports(libFiles)
|
val knownImportMap = findPossibleLibraryImports(libFiles)
|
||||||
.associateBy { it.importFilePath }
|
.associateBy { it.importFilePath }
|
||||||
val prefix = "+++ b/src/main/java/"
|
val prefix = "+++ b$javaSourceSet/"
|
||||||
return patchLines.map { it.substringAfter(prefix) }
|
return patchLines.map { it.substringAfter(prefix) }
|
||||||
.mapNotNull { knownImportMap[it] }
|
.mapNotNull { knownImportMap[it] }
|
||||||
.toSet()
|
.toSet()
|
||||||
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.BufferedWriter
|
||||||
|
import java.io.StringWriter
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.*
|
||||||
|
import org.cadixdev.at.AccessChange
|
||||||
|
import org.cadixdev.at.AccessTransform
|
||||||
|
import org.cadixdev.at.AccessTransformSet
|
||||||
|
import org.cadixdev.at.ModifierChange
|
||||||
|
import org.cadixdev.at.io.AccessTransformFormat
|
||||||
|
import org.cadixdev.at.io.AccessTransformFormats
|
||||||
|
|
||||||
|
fun atFromString(input: String): AccessTransform {
|
||||||
|
var last = input.length - 1
|
||||||
|
|
||||||
|
val final = if (input[last] == 'f') {
|
||||||
|
if (input[--last] == '-') ModifierChange.REMOVE else ModifierChange.ADD
|
||||||
|
} else {
|
||||||
|
ModifierChange.NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
val access = when (input.split("+", "-").first()) {
|
||||||
|
"public" -> AccessChange.PUBLIC
|
||||||
|
"protected" -> AccessChange.PROTECTED
|
||||||
|
"private" -> AccessChange.PRIVATE
|
||||||
|
else -> AccessChange.NONE
|
||||||
|
}
|
||||||
|
|
||||||
|
return AccessTransform.of(access, final)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun atToString(at: AccessTransform): String {
|
||||||
|
val access = when (at.access) {
|
||||||
|
AccessChange.PRIVATE -> "private"
|
||||||
|
AccessChange.PROTECTED -> "protected"
|
||||||
|
AccessChange.PUBLIC -> "public"
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
val final = when (at.final) {
|
||||||
|
ModifierChange.REMOVE -> "-f"
|
||||||
|
ModifierChange.ADD -> "+f"
|
||||||
|
else -> ""
|
||||||
|
}
|
||||||
|
return access + final
|
||||||
|
}
|
||||||
|
|
||||||
|
fun AccessTransformFormat.writeLF(path: Path, at: AccessTransformSet, header: String = "") {
|
||||||
|
val stringWriter = StringWriter()
|
||||||
|
val writer = BufferedWriter(stringWriter)
|
||||||
|
AccessTransformFormats.FML.write(writer, at)
|
||||||
|
writer.close()
|
||||||
|
// unify line endings
|
||||||
|
val lines = stringWriter.toString().replace("\r\n", "\n").split("\n")
|
||||||
|
// remove last empty line, the sort, then add it back
|
||||||
|
path.writeText(lines.subList(0, lines.size - 1).sorted().joinToString("\n", header, "\n"), Charsets.UTF_8)
|
||||||
|
}
|
|
@ -44,6 +44,7 @@ const val REMAPPER_CONFIG = "remapper"
|
||||||
const val PLUGIN_REMAPPER_CONFIG = "pluginRemapper"
|
const val PLUGIN_REMAPPER_CONFIG = "pluginRemapper"
|
||||||
const val DECOMPILER_CONFIG = "decompiler"
|
const val DECOMPILER_CONFIG = "decompiler"
|
||||||
const val PAPERCLIP_CONFIG = "paperclip"
|
const val PAPERCLIP_CONFIG = "paperclip"
|
||||||
|
const val MACHE_CONFIG = "mache"
|
||||||
const val DEV_BUNDLE_CONFIG = "paperweightDevelopmentBundle"
|
const val DEV_BUNDLE_CONFIG = "paperweightDevelopmentBundle"
|
||||||
const val MOJANG_MAPPED_SERVER_CONFIG = "mojangMappedServer"
|
const val MOJANG_MAPPED_SERVER_CONFIG = "mojangMappedServer"
|
||||||
const val MOJANG_MAPPED_SERVER_RUNTIME_CONFIG = "mojangMappedServerRuntime"
|
const val MOJANG_MAPPED_SERVER_RUNTIME_CONFIG = "mojangMappedServerRuntime"
|
||||||
|
@ -54,6 +55,7 @@ const val SERVER_RUNTIME_CLASSPATH = "serverRuntimeClasspath"
|
||||||
const val PARAM_MAPPINGS_REPO_NAME = "paperweightParamMappingsRepository"
|
const val PARAM_MAPPINGS_REPO_NAME = "paperweightParamMappingsRepository"
|
||||||
const val DECOMPILER_REPO_NAME = "paperweightDecompilerRepository"
|
const val DECOMPILER_REPO_NAME = "paperweightDecompilerRepository"
|
||||||
const val REMAPPER_REPO_NAME = "paperweightRemapperRepository"
|
const val REMAPPER_REPO_NAME = "paperweightRemapperRepository"
|
||||||
|
const val MACHE_REPO_NAME = "paperweightMacheRepository"
|
||||||
|
|
||||||
const val CACHE_PATH = "caches"
|
const val CACHE_PATH = "caches"
|
||||||
private const val PAPER_PATH = "paperweight"
|
private const val PAPER_PATH = "paperweight"
|
||||||
|
@ -77,6 +79,9 @@ const val MINECRAFT_SOURCES_PATH = "$JARS_PATH/minecraft-sources"
|
||||||
const val SPIGOT_JARS_PATH = "$JARS_PATH/spigot"
|
const val SPIGOT_JARS_PATH = "$JARS_PATH/spigot"
|
||||||
const val SPIGOT_SOURCES_JARS_PATH = "$JARS_PATH/spigot-sources"
|
const val SPIGOT_SOURCES_JARS_PATH = "$JARS_PATH/spigot-sources"
|
||||||
|
|
||||||
|
const val PAPER_JARS_PATH = "$JARS_PATH/paper"
|
||||||
|
const val PAPER_SOURCES_JARS_PATH = "$JARS_PATH/paper-sources"
|
||||||
|
|
||||||
private const val MAPPINGS_DIR = "$PAPER_PATH/mappings"
|
private const val MAPPINGS_DIR = "$PAPER_PATH/mappings"
|
||||||
const val SERVER_MAPPINGS = "$MAPPINGS_DIR/server_mappings.txt"
|
const val SERVER_MAPPINGS = "$MAPPINGS_DIR/server_mappings.txt"
|
||||||
const val MOJANG_YARN_MAPPINGS = "$MAPPINGS_DIR/official-mojang+yarn.tiny"
|
const val MOJANG_YARN_MAPPINGS = "$MAPPINGS_DIR/official-mojang+yarn.tiny"
|
||||||
|
@ -90,10 +95,12 @@ const val PATCHED_SPIGOT_MOJANG_YARN_SOURCE_MAPPINGS = "$MAPPINGS_DIR/spigot-moj
|
||||||
const val REOBF_MOJANG_SPIGOT_MAPPINGS = "$MAPPINGS_DIR/mojang+yarn-spigot-reobf.tiny"
|
const val REOBF_MOJANG_SPIGOT_MAPPINGS = "$MAPPINGS_DIR/mojang+yarn-spigot-reobf.tiny"
|
||||||
const val PATCHED_REOBF_MOJANG_SPIGOT_MAPPINGS = "$MAPPINGS_DIR/mojang+yarn-spigot-reobf-patched.tiny"
|
const val PATCHED_REOBF_MOJANG_SPIGOT_MAPPINGS = "$MAPPINGS_DIR/mojang+yarn-spigot-reobf-patched.tiny"
|
||||||
const val RELOCATED_PATCHED_REOBF_MOJANG_SPIGOT_MAPPINGS = "$MAPPINGS_DIR/mojang+yarn-spigot-reobf-patched-relocated.tiny"
|
const val RELOCATED_PATCHED_REOBF_MOJANG_SPIGOT_MAPPINGS = "$MAPPINGS_DIR/mojang+yarn-spigot-reobf-patched-relocated.tiny"
|
||||||
|
const val SPIGOT_MOJANG_PARCHMENT_MAPPINGS = "$MAPPINGS_DIR/spigot-mojang+parchment.tiny"
|
||||||
|
|
||||||
const val OBF_NAMESPACE = "official"
|
const val OBF_NAMESPACE = "official"
|
||||||
const val SPIGOT_NAMESPACE = "spigot"
|
const val SPIGOT_NAMESPACE = "spigot"
|
||||||
const val DEOBF_NAMESPACE = "mojang+yarn"
|
const val DEOBF_NAMESPACE = "mojang+yarn"
|
||||||
|
const val NEW_DEOBF_NAMESPACE = "mojang+parchment"
|
||||||
const val MAPPINGS_NAMESPACE_MANIFEST_KEY = "paperweight-mappings-namespace"
|
const val MAPPINGS_NAMESPACE_MANIFEST_KEY = "paperweight-mappings-namespace"
|
||||||
|
|
||||||
private const val DATA_PATH = "$PAPER_PATH/data"
|
private const val DATA_PATH = "$PAPER_PATH/data"
|
||||||
|
@ -105,13 +112,17 @@ const val SERVER_VERSION_JSON = "$BUNDLER_PATH/version.json"
|
||||||
const val SERVER_LIBRARIES_TXT = "$BUNDLER_PATH/ServerLibraries.txt"
|
const val SERVER_LIBRARIES_TXT = "$BUNDLER_PATH/ServerLibraries.txt"
|
||||||
const val SERVER_LIBRARIES_LIST = "$BUNDLER_PATH/libraries.list"
|
const val SERVER_LIBRARIES_LIST = "$BUNDLER_PATH/libraries.list"
|
||||||
const val SERVER_VERSIONS_LIST = "$BUNDLER_PATH/versions.list"
|
const val SERVER_VERSIONS_LIST = "$BUNDLER_PATH/versions.list"
|
||||||
|
const val SERVER_JAR = "$BUNDLER_PATH/server.jar"
|
||||||
|
|
||||||
private const val SETUP_CACHE = "$PAPER_PATH/setupCache"
|
private const val SETUP_CACHE = "$PAPER_PATH/setupCache"
|
||||||
private const val TASK_CACHE = "$PAPER_PATH/taskCache"
|
private const val TASK_CACHE = "$PAPER_PATH/taskCache"
|
||||||
|
|
||||||
const val FINAL_REMAPPED_JAR = "$TASK_CACHE/minecraft.jar"
|
const val FINAL_REMAPPED_JAR = "$TASK_CACHE/minecraft.jar"
|
||||||
|
const val FINAL_REMAPPED_CODEBOOK_JAR = "$TASK_CACHE/codebook-minecraft.jar"
|
||||||
const val FINAL_FILTERED_REMAPPED_JAR = "$TASK_CACHE/filteredMinecraft.jar"
|
const val FINAL_FILTERED_REMAPPED_JAR = "$TASK_CACHE/filteredMinecraft.jar"
|
||||||
const val FINAL_DECOMPILE_JAR = "$TASK_CACHE/decompileJar.jar"
|
const val FINAL_DECOMPILE_JAR = "$TASK_CACHE/decompileJar.jar"
|
||||||
|
const val SPIGOT_MACHE_DECOMPILE_JAR = "$TASK_CACHE/macheSpigotDecompileJar.jar"
|
||||||
|
const val DECOMP_CFG = "$TASK_CACHE/decomp_cfg.txt"
|
||||||
|
|
||||||
const val MC_DEV_SOURCES_DIR = "$PAPER_PATH/mc-dev-sources"
|
const val MC_DEV_SOURCES_DIR = "$PAPER_PATH/mc-dev-sources"
|
||||||
|
|
||||||
|
@ -119,6 +130,13 @@ const val IVY_REPOSITORY = "$PAPER_PATH/ivyRepository"
|
||||||
|
|
||||||
const val DOWNLOAD_SERVICE_NAME = "paperweightDownloadService"
|
const val DOWNLOAD_SERVICE_NAME = "paperweightDownloadService"
|
||||||
|
|
||||||
|
private const val MACHE_PATH = "$PAPER_PATH/mache"
|
||||||
|
const val PATCHED_JAR = "$MACHE_PATH/patched.jar"
|
||||||
|
const val FAILED_PATCH_JAR = "$MACHE_PATH/failed.jar"
|
||||||
|
const val PATCHES_FOLDER = "$MACHE_PATH/patches"
|
||||||
|
const val BASE_PROJECT = "$MACHE_PATH/base"
|
||||||
|
const val REMAPPED_CB = "$MACHE_PATH/remapped-cb"
|
||||||
|
|
||||||
fun paperSetupOutput(name: String, ext: String) = "$SETUP_CACHE/$name.$ext"
|
fun paperSetupOutput(name: String, ext: String) = "$SETUP_CACHE/$name.$ext"
|
||||||
fun Task.paperTaskOutput(ext: String) = paperTaskOutput(name, ext)
|
fun Task.paperTaskOutput(ext: String) = paperTaskOutput(name, ext)
|
||||||
fun paperTaskOutput(name: String, ext: String) = "$TASK_CACHE/$name.$ext"
|
fun paperTaskOutput(name: String, ext: String) = "$TASK_CACHE/$name.$ext"
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* 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.util.data.mache
|
||||||
|
|
||||||
|
data class MacheAdditionalDependencies(
|
||||||
|
val compileOnly: List<MavenArtifact>? = null,
|
||||||
|
val implementation: List<MavenArtifact>? = null,
|
||||||
|
)
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* 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.util.data.mache
|
||||||
|
|
||||||
|
data class MacheDependencies(
|
||||||
|
val codebook: List<MavenArtifact>,
|
||||||
|
val paramMappings: List<MavenArtifact>,
|
||||||
|
val constants: List<MavenArtifact>,
|
||||||
|
val remapper: List<MavenArtifact>,
|
||||||
|
val decompiler: List<MavenArtifact>,
|
||||||
|
)
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* 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.util.data.mache
|
||||||
|
|
||||||
|
data class MacheMeta(
|
||||||
|
val minecraftVersion: String,
|
||||||
|
val macheVersion: String,
|
||||||
|
val dependencies: MacheDependencies,
|
||||||
|
val repositories: List<MacheRepository>,
|
||||||
|
val decompilerArgs: List<String>,
|
||||||
|
val remapperArgs: List<String>,
|
||||||
|
val additionalCompileDependencies: MacheAdditionalDependencies? = null,
|
||||||
|
)
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* 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.util.data.mache
|
||||||
|
|
||||||
|
data class MacheRepository(
|
||||||
|
val url: String,
|
||||||
|
val name: String,
|
||||||
|
val groups: List<String>? = null,
|
||||||
|
)
|
|
@ -0,0 +1,35 @@
|
||||||
|
/*
|
||||||
|
* 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.util.data.mache
|
||||||
|
|
||||||
|
data class MavenArtifact(
|
||||||
|
val group: String,
|
||||||
|
val name: String,
|
||||||
|
val version: String,
|
||||||
|
val classifier: String? = null,
|
||||||
|
val extension: String? = null,
|
||||||
|
) {
|
||||||
|
fun toMavenString(): String {
|
||||||
|
return "$group:$name:$version" + (classifier?.let { ":$it" } ?: "") + (extension?.let { "@$it" } ?: "")
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ import io.papermc.paperweight.PaperweightException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.net.URI
|
import java.net.URI
|
||||||
import java.nio.file.FileSystem
|
import java.nio.file.FileSystem
|
||||||
|
import java.nio.file.FileSystemNotFoundException
|
||||||
import java.nio.file.FileSystems
|
import java.nio.file.FileSystems
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
@ -35,6 +36,9 @@ import java.util.Arrays
|
||||||
import java.util.stream.Collectors
|
import java.util.stream.Collectors
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
import java.util.stream.StreamSupport
|
import java.util.stream.StreamSupport
|
||||||
|
import java.util.zip.ZipEntry
|
||||||
|
import java.util.zip.ZipInputStream
|
||||||
|
import java.util.zip.ZipOutputStream
|
||||||
import kotlin.io.path.*
|
import kotlin.io.path.*
|
||||||
import kotlin.streams.asSequence
|
import kotlin.streams.asSequence
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
|
@ -142,13 +146,41 @@ private fun Path.jarUri(): URI {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Path.openZip(): FileSystem {
|
fun Path.openZip(): FileSystem {
|
||||||
return FileSystems.newFileSystem(jarUri(), emptyMap<String, Any>())
|
return try {
|
||||||
|
FileSystems.getFileSystem(jarUri())
|
||||||
|
} catch (e: FileSystemNotFoundException) {
|
||||||
|
FileSystems.newFileSystem(jarUri(), emptyMap<String, Any>())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Path.writeZip(): FileSystem {
|
fun Path.writeZip(): FileSystem {
|
||||||
return FileSystems.newFileSystem(jarUri(), mapOf("create" to "true"))
|
return FileSystems.newFileSystem(jarUri(), mapOf("create" to "true"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fun Path.writeZipStream(func: (ZipOutputStream) -> Unit) {
|
||||||
|
ZipOutputStream(this.outputStream().buffered()).use(func)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun Path.readZipStream(func: (ZipInputStream, ZipEntry) -> Unit) {
|
||||||
|
ZipInputStream(this.inputStream().buffered()).use { zis ->
|
||||||
|
var entry = zis.nextEntry
|
||||||
|
while (entry != null) {
|
||||||
|
func(zis, entry)
|
||||||
|
entry = zis.nextEntry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun copyEntry(input: InputStream, output: ZipOutputStream, entry: ZipEntry) {
|
||||||
|
val newEntry = ZipEntry(entry)
|
||||||
|
output.putNextEntry(newEntry)
|
||||||
|
try {
|
||||||
|
input.copyTo(output)
|
||||||
|
} finally {
|
||||||
|
output.closeEntry()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun FileSystem.walk(): Stream<Path> {
|
fun FileSystem.walk(): Stream<Path> {
|
||||||
return StreamSupport.stream(rootDirectories.spliterator(), false)
|
return StreamSupport.stream(rootDirectories.spliterator(), false)
|
||||||
.flatMap { Files.walk(it) }
|
.flatMap { Files.walk(it) }
|
||||||
|
|
|
@ -102,6 +102,17 @@ class Git(private val repo: Path, private val env: Map<String, String> = emptyMa
|
||||||
|
|
||||||
throw PaperweightException("You must have git installed and available on your PATH in order to use paperweight.")
|
throw PaperweightException("You must have git installed and available on your PATH in order to use paperweight.")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun checkForGitRepo(directory: Path): Boolean {
|
||||||
|
try {
|
||||||
|
val proc = ProcessBuilder("git", "status").redirectErrorStream(true).directory(directory).start()
|
||||||
|
proc.inputStream.copyTo(UselessOutputStream)
|
||||||
|
if (proc.waitFor() == 0) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} catch (_: Exception) {}
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,8 @@ import org.gradle.jvm.toolchain.JavaLauncher
|
||||||
import org.gradle.jvm.toolchain.JavaToolchainService
|
import org.gradle.jvm.toolchain.JavaToolchainService
|
||||||
import org.gradle.kotlin.dsl.*
|
import org.gradle.kotlin.dsl.*
|
||||||
|
|
||||||
|
val whitespace = Regex("\\s+")
|
||||||
|
|
||||||
val gson: Gson = GsonBuilder().disableHtmlEscaping().setPrettyPrinting().registerTypeHierarchyAdapter(Path::class.java, PathJsonConverter()).create()
|
val gson: Gson = GsonBuilder().disableHtmlEscaping().setPrettyPrinting().registerTypeHierarchyAdapter(Path::class.java, PathJsonConverter()).create()
|
||||||
|
|
||||||
class PathJsonConverter : JsonDeserializer<Path?>, JsonSerializer<Path?> {
|
class PathJsonConverter : JsonDeserializer<Path?>, JsonSerializer<Path?> {
|
||||||
|
@ -107,7 +109,9 @@ fun ProjectLayout.maybeInitSubmodules(offline: Boolean, logger: Logger) {
|
||||||
|
|
||||||
fun ProjectLayout.initSubmodules() {
|
fun ProjectLayout.initSubmodules() {
|
||||||
Git.checkForGit()
|
Git.checkForGit()
|
||||||
Git(projectDirectory.path)("submodule", "update", "--init").executeOut()
|
if (Git.checkForGitRepo(projectDirectory.path)) {
|
||||||
|
Git(projectDirectory.path)("submodule", "update", "--init").executeOut()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Project.offlineMode(): Boolean = gradle.startParameter.isOffline
|
fun Project.offlineMode(): Boolean = gradle.startParameter.isOffline
|
||||||
|
@ -201,6 +205,18 @@ fun Any.convertToPath(): Path {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Path.ensureClean(): Path {
|
||||||
|
try {
|
||||||
|
deleteRecursively()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
println("Failed to delete $this: ${e.javaClass.name}: ${e.message}")
|
||||||
|
e.suppressedExceptions.forEach { println("Suppressed exception: $it") }
|
||||||
|
throw PaperweightException("Failed to delete $this", e)
|
||||||
|
}
|
||||||
|
parent.createDirectories()
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
fun Any.convertToFileProvider(layout: ProjectLayout, providers: ProviderFactory): Provider<RegularFile> {
|
fun Any.convertToFileProvider(layout: ProjectLayout, providers: ProviderFactory): Provider<RegularFile> {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is Path -> layout.file(providers.provider { toFile() })
|
is Path -> layout.file(providers.provider { toFile() })
|
||||||
|
|
11
paperweight-lib/src/main/resources/post-rewrite.sh
Normal file
11
paperweight-lib/src/main/resources/post-rewrite.sh
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
#!/bin/sh
|
||||||
|
input=$(cat) # <old-object> SP <new-object> [SP <extra-info>] LF
|
||||||
|
fileCommit=$(git rev-list -n 1 file) # current commit tagged as "file"
|
||||||
|
oldObject=$(echo $input | cut -d' ' -f1) # <old-object>
|
||||||
|
newObject=$(echo $input | cut -d' ' -f2) # <new-object>
|
||||||
|
|
||||||
|
if [ $oldObject = $fileCommit ]; then
|
||||||
|
git tag -d file > /dev/null # delete old tag (silent)
|
||||||
|
git tag file "$newObject" --no-sign
|
||||||
|
echo "Updated tag 'file' from $oldObject to $newObject"
|
||||||
|
fi
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* 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.mockk.every
|
||||||
|
import io.mockk.mockk
|
||||||
|
import io.mockk.mockkObject
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.test.BeforeTest
|
||||||
|
import kotlin.test.Test
|
||||||
|
import org.gradle.kotlin.dsl.*
|
||||||
|
import org.gradle.workers.WorkQueue
|
||||||
|
import org.gradle.workers.WorkerExecutor
|
||||||
|
import org.junit.jupiter.api.io.TempDir
|
||||||
|
|
||||||
|
class ApplyAccessTransformTest : TaskTest() {
|
||||||
|
private lateinit var task: ApplyAccessTransform
|
||||||
|
|
||||||
|
private val workerExecutor: WorkerExecutor = mockk()
|
||||||
|
private val workQueue: WorkQueue = mockk()
|
||||||
|
|
||||||
|
@BeforeTest
|
||||||
|
fun setup() {
|
||||||
|
val project = setupProject()
|
||||||
|
project.apply(plugin = "java")
|
||||||
|
task = project.tasks.register("applyAccessTransform", ApplyAccessTransform::class).get()
|
||||||
|
mockkObject(task)
|
||||||
|
|
||||||
|
every { task.workerExecutor } returns workerExecutor
|
||||||
|
every { workerExecutor.processIsolation(any()) } returns workQueue
|
||||||
|
every { workQueue.submit(ApplyAccessTransform.AtlasAction::class, any()) } answers {
|
||||||
|
val action = object : ApplyAccessTransform.AtlasAction() {
|
||||||
|
override fun getParameters(): ApplyAccessTransform.AtlasParameters {
|
||||||
|
return mockk<ApplyAccessTransform.AtlasParameters>().also {
|
||||||
|
every { it.inputJar.get() } returns task.inputJar.get()
|
||||||
|
every { it.atFile.get() } returns task.atFile.get()
|
||||||
|
every { it.outputJar.get() } returns task.outputJar.get()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
action.execute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should apply access transform`(@TempDir tempDir: Path) {
|
||||||
|
val testResource = Path.of("src/test/resources/apply_access_transform")
|
||||||
|
val testInput = testResource.resolve("input")
|
||||||
|
|
||||||
|
val input = createJar(tempDir, testInput, "Test").toFile()
|
||||||
|
val output = tempDir.resolve("output.jar").toFile()
|
||||||
|
val atFile = testInput.resolve("ats.at").toFile()
|
||||||
|
|
||||||
|
task.inputJar.set(input)
|
||||||
|
task.outputJar.set(output)
|
||||||
|
task.atFile.set(atFile)
|
||||||
|
|
||||||
|
task.run()
|
||||||
|
|
||||||
|
val testOutput = testResource.resolve("output")
|
||||||
|
compareJar(tempDir, testOutput, "output", "Test")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,186 @@
|
||||||
|
/*
|
||||||
|
* 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.io.File
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.*
|
||||||
|
import org.eclipse.jgit.api.Git
|
||||||
|
import org.gradle.testfixtures.ProjectBuilder
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
import org.junit.jupiter.api.Assertions.assertTrue
|
||||||
|
|
||||||
|
open class TaskTest {
|
||||||
|
|
||||||
|
fun setupProject() = ProjectBuilder.builder()
|
||||||
|
.withGradleUserHomeDir(File("build"))
|
||||||
|
.withProjectDir(File(""))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
fun setupDir(tempDir: Path, testResource: Path, name: String): Path {
|
||||||
|
val temp = tempDir.resolve(name).toFile()
|
||||||
|
temp.mkdir()
|
||||||
|
testResource.resolve(name).copyRecursivelyTo(temp.convertToPath())
|
||||||
|
return temp.convertToPath()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setupFile(tempDir: Path, testResource: Path, name: String): Path {
|
||||||
|
val temp = tempDir.resolve(name)
|
||||||
|
testResource.resolve(name).copyTo(temp)
|
||||||
|
return temp
|
||||||
|
}
|
||||||
|
|
||||||
|
fun compareDir(tempDir: Path, testResource: Path, name: String) {
|
||||||
|
val actualOutput = tempDir.resolve(name)
|
||||||
|
val expectedOutput = testResource.resolve(name)
|
||||||
|
|
||||||
|
val expectedFiles = expectedOutput.walk().filter { Files.isRegularFile(it) }.filter { !it.toString().contains(".git") }.toList()
|
||||||
|
val actualFiles = actualOutput.walk().filter { Files.isRegularFile(it) }.filter { !it.toString().contains(".git") }.toList()
|
||||||
|
|
||||||
|
assertEquals(expectedFiles.size, actualFiles.size, "Expected $expectedFiles files, got $actualFiles")
|
||||||
|
|
||||||
|
expectedFiles.forEach { expectedFile ->
|
||||||
|
val actualFile = actualOutput.resolve(expectedOutput.relativize(expectedFile))
|
||||||
|
|
||||||
|
compareFile(actualFile, expectedFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun compareZip(tempDir: Path, testResource: Path, name: String) {
|
||||||
|
val actualOutput = tempDir.resolve(name)
|
||||||
|
val expectedOutput = testResource.resolve(name)
|
||||||
|
|
||||||
|
compareZip(actualOutput, expectedOutput)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun compareZip(actualOutput: Path, expectedOutput: Path) {
|
||||||
|
val actualZip = actualOutput.openZip()
|
||||||
|
val actualFiles = actualZip.walk().filter { Files.isRegularFile(it) }.toList()
|
||||||
|
val expectedZip = expectedOutput.openZip()
|
||||||
|
val expectedFiles = expectedZip.walk().filter { Files.isRegularFile(it) }.toList()
|
||||||
|
|
||||||
|
assertEquals(expectedFiles.size, actualFiles.size, "Expected $expectedFiles files, got $actualFiles")
|
||||||
|
|
||||||
|
expectedFiles.forEach { expectedFile ->
|
||||||
|
val actualFile = actualZip.getPath(expectedFile.toString())
|
||||||
|
|
||||||
|
compareFile(actualFile, expectedFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun compareFile(tempDir: Path, testResource: Path, name: String) {
|
||||||
|
val actualOutput = tempDir.resolve(name)
|
||||||
|
val expectedOutput = testResource.resolve(name)
|
||||||
|
|
||||||
|
compareFile(actualOutput, expectedOutput)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun compareFile(actual: Path, expected: Path) {
|
||||||
|
assertTrue(actual.exists(), "Expected file $actual doesn't exist")
|
||||||
|
assertEquals(expected.readText(), actual.readText(), "File $actual doesn't match expected")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setupGitRepo(directory: File, mainBranch: String, tag: String? = null) {
|
||||||
|
val git = Git.init().setDirectory(directory).setInitialBranch(mainBranch).call()
|
||||||
|
|
||||||
|
git.add().addFilepattern(".").call()
|
||||||
|
git.commit().setMessage("Test").call()
|
||||||
|
if (tag != null) {
|
||||||
|
git.tag().setName(tag).call()
|
||||||
|
}
|
||||||
|
|
||||||
|
git.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createZip(tempDir: Path, testResource: Path, zipName: String, vararg fileNames: String,): Path {
|
||||||
|
val targetZip = tempDir.resolve(zipName)
|
||||||
|
|
||||||
|
targetZip.writeZip().use { zip ->
|
||||||
|
fileNames.forEach { fileName ->
|
||||||
|
val sourceFile = testResource.resolve(fileName)
|
||||||
|
zip.getPath(fileName).writeText(sourceFile.readText())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return targetZip
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createJar(tempDir: Path, testResource: Path, name: String): Path {
|
||||||
|
val sourceFile = tempDir.resolve("$name.java")
|
||||||
|
testResource.resolve("$name.java").copyTo(sourceFile)
|
||||||
|
|
||||||
|
// run javac on the file
|
||||||
|
ProcessBuilder()
|
||||||
|
.directory(tempDir.toFile())
|
||||||
|
.command("javac", sourceFile.toString())
|
||||||
|
.redirectErrorStream(true)
|
||||||
|
.start()
|
||||||
|
.waitFor()
|
||||||
|
|
||||||
|
// create jar
|
||||||
|
ProcessBuilder()
|
||||||
|
.directory(tempDir.toFile())
|
||||||
|
.command("jar", "-cf", "$name.jar", "$name.class")
|
||||||
|
.redirectErrorStream(true)
|
||||||
|
.start()
|
||||||
|
.waitFor()
|
||||||
|
|
||||||
|
return tempDir.resolve("$name.jar")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun compareJar(tempDir: Path, testResource: Path, fileName: String, className: String) {
|
||||||
|
val outputJar = tempDir.resolve("$fileName.jar")
|
||||||
|
val expectedOutputFile = testResource.resolve("$fileName.javap")
|
||||||
|
|
||||||
|
// unpack jar
|
||||||
|
ProcessBuilder()
|
||||||
|
.directory(tempDir.toFile())
|
||||||
|
.command("jar", "-xf", outputJar.toString())
|
||||||
|
.redirectErrorStream(true)
|
||||||
|
.start()
|
||||||
|
.waitFor()
|
||||||
|
|
||||||
|
// disassemble class
|
||||||
|
val process = ProcessBuilder()
|
||||||
|
.directory(tempDir.toFile())
|
||||||
|
.command("javap", "-p", "-c", "$className.class")
|
||||||
|
.redirectErrorStream(true)
|
||||||
|
.start()
|
||||||
|
|
||||||
|
var actualOutput = process.inputStream.bufferedReader().readText()
|
||||||
|
val expectedOutput = expectedOutputFile.readText()
|
||||||
|
|
||||||
|
// cleanup output
|
||||||
|
val lines = actualOutput.split("\n")
|
||||||
|
if (lines[0].startsWith("Picked up JAVA_TOOL_OPTIONS")) {
|
||||||
|
actualOutput = actualOutput.replace(lines[0] + "\n", "")
|
||||||
|
}
|
||||||
|
actualOutput = actualOutput.replace("\r\n", "\n")
|
||||||
|
|
||||||
|
process.waitFor()
|
||||||
|
|
||||||
|
assertEquals(expectedOutput, actualOutput, "Output doesn't match expected")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* 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.softspoon
|
||||||
|
|
||||||
|
import io.papermc.paperweight.tasks.*
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.test.BeforeTest
|
||||||
|
import kotlin.test.Test
|
||||||
|
import org.gradle.kotlin.dsl.*
|
||||||
|
import org.junit.jupiter.api.io.TempDir
|
||||||
|
|
||||||
|
class ApplyFilePatchesTest : TaskTest() {
|
||||||
|
private lateinit var task: ApplyFilePatches
|
||||||
|
|
||||||
|
@BeforeTest
|
||||||
|
fun setup() {
|
||||||
|
val project = setupProject()
|
||||||
|
task = project.tasks.register("applyPatches", ApplyFilePatches::class).get()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should apply patches`(@TempDir tempDir: Path) {
|
||||||
|
val testResource = Path.of("src/test/resources/apply_patches")
|
||||||
|
val testInput = testResource.resolve("input")
|
||||||
|
|
||||||
|
val input = setupDir(tempDir, testInput, "base").toFile()
|
||||||
|
val output = tempDir.resolve("source").toFile()
|
||||||
|
val patches = testInput.resolve("patches").toFile()
|
||||||
|
|
||||||
|
setupGitRepo(input, "main")
|
||||||
|
|
||||||
|
task.input.set(input)
|
||||||
|
task.output.set(output)
|
||||||
|
task.patches.set(patches)
|
||||||
|
task.verbose.set(true)
|
||||||
|
|
||||||
|
task.run()
|
||||||
|
|
||||||
|
val testOutput = testResource.resolve("output")
|
||||||
|
compareDir(tempDir, testOutput, "source")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
/*
|
||||||
|
* 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.softspoon
|
||||||
|
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.mockk
|
||||||
|
import io.mockk.mockkObject
|
||||||
|
import io.papermc.paperweight.tasks.*
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.test.BeforeTest
|
||||||
|
import kotlin.test.Test
|
||||||
|
import org.gradle.kotlin.dsl.*
|
||||||
|
import org.gradle.workers.WorkQueue
|
||||||
|
import org.gradle.workers.WorkerExecutor
|
||||||
|
import org.junit.jupiter.api.io.TempDir
|
||||||
|
|
||||||
|
class ApplySourceATTest : TaskTest() {
|
||||||
|
private lateinit var task: ApplySourceAT
|
||||||
|
|
||||||
|
private val workerExecutor: WorkerExecutor = mockk()
|
||||||
|
private val workQueue: WorkQueue = mockk()
|
||||||
|
|
||||||
|
@BeforeTest
|
||||||
|
fun setup() {
|
||||||
|
val project = setupProject()
|
||||||
|
task = project.tasks.register("applySourceAT", ApplySourceAT::class).get()
|
||||||
|
mockkObject(task)
|
||||||
|
|
||||||
|
every { task.worker } returns workerExecutor
|
||||||
|
every { workerExecutor.processIsolation(any()) } returns workQueue
|
||||||
|
every { workQueue.submit(RestampWorker::class, any()) } answers {
|
||||||
|
val action = object : RestampWorker() {
|
||||||
|
override fun getParameters(): Params {
|
||||||
|
return mockk<Params>().also {
|
||||||
|
every { it.inputJar.get() } returns task.inputJar.get()
|
||||||
|
every { it.atFile.get() } returns task.atFile.get()
|
||||||
|
every { it.outputJar.get() } returns task.outputJar.get()
|
||||||
|
every { it.minecraftClasspath } returns task.minecraftClasspath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
action.execute()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should apply source access transformers`(@TempDir tempDir: Path) {
|
||||||
|
val testResource = Path.of("src/test/resources/apply_source_at")
|
||||||
|
val testInput = testResource.resolve("input")
|
||||||
|
|
||||||
|
val inputJar = createZip(tempDir, testInput, "Test.jar", "Test.java", "Unrelated.java")
|
||||||
|
val atFile = testInput.resolve("ats.at").toFile()
|
||||||
|
val outputJar = tempDir.resolve("output.jar")
|
||||||
|
|
||||||
|
task.inputJar.set(inputJar.toFile())
|
||||||
|
task.atFile.set(atFile)
|
||||||
|
task.outputJar.set(outputJar.toFile())
|
||||||
|
|
||||||
|
task.run()
|
||||||
|
|
||||||
|
val testOutput = testResource.resolve("output")
|
||||||
|
val expectedJar = createZip(tempDir, testOutput, "expected.jar", "Test.java", "Unrelated.java")
|
||||||
|
compareZip(outputJar, expectedJar)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* 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.softspoon
|
||||||
|
|
||||||
|
import io.papermc.paperweight.tasks.*
|
||||||
|
import java.nio.file.Path
|
||||||
|
import kotlin.test.BeforeTest
|
||||||
|
import kotlin.test.Test
|
||||||
|
import org.gradle.kotlin.dsl.*
|
||||||
|
import org.junit.jupiter.api.io.TempDir
|
||||||
|
|
||||||
|
class RebuildFilePatchesTest : TaskTest() {
|
||||||
|
private lateinit var task: RebuildFilePatches
|
||||||
|
|
||||||
|
@BeforeTest
|
||||||
|
fun setup() {
|
||||||
|
val project = setupProject()
|
||||||
|
task = project.tasks.register("rebuildPatches", RebuildFilePatches::class).get()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `should rebuild patches`(@TempDir tempDir: Path) {
|
||||||
|
val testResource = Path.of("src/test/resources/rebuild_patches")
|
||||||
|
val testInput = testResource.resolve("input")
|
||||||
|
|
||||||
|
val source = setupDir(tempDir, testInput, "source").toFile()
|
||||||
|
setupGitRepo(source, "main", "file")
|
||||||
|
val base = setupDir(tempDir, testInput, "base").toFile()
|
||||||
|
val patches = tempDir.resolve("patches").toFile()
|
||||||
|
val atFile = testInput.resolve("ats.at").toFile()
|
||||||
|
val atFileOut = tempDir.resolve("ats.at").toFile()
|
||||||
|
|
||||||
|
task.input.set(source)
|
||||||
|
task.base.set(base)
|
||||||
|
task.patches.set(patches)
|
||||||
|
task.atFile.set(atFile)
|
||||||
|
task.atFileOut.set(atFileOut)
|
||||||
|
task.verbose.set(true)
|
||||||
|
|
||||||
|
task.run()
|
||||||
|
|
||||||
|
val testOutput = testResource.resolve("output")
|
||||||
|
compareDir(tempDir, testOutput, "base")
|
||||||
|
compareDir(tempDir, testOutput, "source")
|
||||||
|
compareDir(tempDir, testOutput, "patches")
|
||||||
|
compareFile(tempDir, testOutput, "ats.at")
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* 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.util
|
||||||
|
|
||||||
|
import atFromString
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import org.cadixdev.at.AccessChange
|
||||||
|
import org.cadixdev.at.AccessTransform
|
||||||
|
import org.cadixdev.at.ModifierChange
|
||||||
|
|
||||||
|
class ATTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testATFromString() {
|
||||||
|
assertEquals(AccessTransform.of(AccessChange.PUBLIC, ModifierChange.REMOVE), atFromString("public-f"))
|
||||||
|
assertEquals(AccessTransform.of(AccessChange.PUBLIC, ModifierChange.NONE), atFromString("public"))
|
||||||
|
assertEquals(AccessTransform.of(AccessChange.PUBLIC, ModifierChange.ADD), atFromString("public+f"))
|
||||||
|
|
||||||
|
assertEquals(AccessTransform.of(AccessChange.PRIVATE, ModifierChange.REMOVE), atFromString("private-f"))
|
||||||
|
assertEquals(AccessTransform.of(AccessChange.PRIVATE, ModifierChange.NONE), atFromString("private"))
|
||||||
|
assertEquals(AccessTransform.of(AccessChange.PRIVATE, ModifierChange.ADD), atFromString("private+f"))
|
||||||
|
|
||||||
|
assertEquals(AccessTransform.of(AccessChange.NONE, ModifierChange.REMOVE), atFromString("-f"))
|
||||||
|
assertEquals(AccessTransform.of(AccessChange.NONE, ModifierChange.ADD), atFromString("+f"))
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public int dum;
|
||||||
|
private final String test;
|
||||||
|
|
||||||
|
public Test(String test) {
|
||||||
|
this.test = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTest() {
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
# This file is auto generated, any changes may be overridden!
|
||||||
|
# See CONTRIBUTING.md on how to add access transformers.
|
||||||
|
public-f Test test
|
||||||
|
public+f Test dum
|
||||||
|
private+f Test getTest()Ljava/lang/String;
|
|
@ -0,0 +1,21 @@
|
||||||
|
Compiled from "Test.java"
|
||||||
|
public class Test {
|
||||||
|
public final int dum;
|
||||||
|
|
||||||
|
public java.lang.String test;
|
||||||
|
|
||||||
|
public Test(java.lang.String);
|
||||||
|
Code:
|
||||||
|
0: aload_0
|
||||||
|
1: invokespecial #1 // Method java/lang/Object."<init>":()V
|
||||||
|
4: aload_0
|
||||||
|
5: aload_1
|
||||||
|
6: putfield #7 // Field test:Ljava/lang/String;
|
||||||
|
9: return
|
||||||
|
|
||||||
|
private final java.lang.String getTest();
|
||||||
|
Code:
|
||||||
|
0: aload_0
|
||||||
|
1: getfield #7 // Field test:Ljava/lang/String;
|
||||||
|
4: areturn
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public int dum;
|
||||||
|
private final String test;
|
||||||
|
|
||||||
|
public Test(String test) {
|
||||||
|
this.test = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTest() {
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
--- a/Test.java
|
||||||
|
+++ b/Test.java
|
||||||
|
@@ -8,6 +_,6 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTest() {
|
||||||
|
- return test;
|
||||||
|
+ return test + "Test"; // Test
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public int dum;
|
||||||
|
private final String test;
|
||||||
|
|
||||||
|
public Test(String test) {
|
||||||
|
this.test = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTest() {
|
||||||
|
return test + "Test"; // Test
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public int dum;
|
||||||
|
private final String test;
|
||||||
|
|
||||||
|
public Test(String test) {
|
||||||
|
this.test = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTest() {
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
class Unrealted {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
# This file is auto generated, any changes may be overridden!
|
||||||
|
# See CONTRIBUTING.md on how to add access transformers.
|
||||||
|
public-f Test test
|
||||||
|
public+f Test dum
|
||||||
|
private+f Test getTest()Ljava/lang/String;
|
|
@ -0,0 +1,13 @@
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public final int dum;
|
||||||
|
public String test;
|
||||||
|
|
||||||
|
public Test(String test) {
|
||||||
|
this.test = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String getTest() {
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
class Unrealted {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
# This file is auto generated, any changes may be overridden!
|
||||||
|
# See CONTRIBUTING.md on how to add access transformers.
|
||||||
|
public Test dum
|
|
@ -0,0 +1,13 @@
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public int dum;
|
||||||
|
private final String test;
|
||||||
|
|
||||||
|
public Test(String test) {
|
||||||
|
this.test = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTest() {
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public int dum;
|
||||||
|
public String test;// Paper-AT: public-f test
|
||||||
|
|
||||||
|
public Test(String test) {
|
||||||
|
this.test = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String getTest() {// Paper-AT: private+f getTest()Ljava/lang/String;
|
||||||
|
return test + "Test"; // Test
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
# This file is auto generated, any changes may be overridden!
|
||||||
|
# See CONTRIBUTING.md on how to add access transformers.
|
||||||
|
private+f Test getTest()Ljava/lang/String;
|
||||||
|
public Test dum
|
||||||
|
public-f Test test
|
|
@ -0,0 +1,13 @@
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public int dum;
|
||||||
|
public String test;
|
||||||
|
|
||||||
|
public Test(String test) {
|
||||||
|
this.test = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String getTest() {
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
--- a/Test.java
|
||||||
|
+++ b/Test.java
|
||||||
|
@@ -8,6 +_,6 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String getTest() {
|
||||||
|
- return test;
|
||||||
|
+ return test + "Test"; // Test
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public int dum;
|
||||||
|
public String test;
|
||||||
|
|
||||||
|
public Test(String test) {
|
||||||
|
this.test = test;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String getTest() {
|
||||||
|
return test + "Test"; // Test
|
||||||
|
}
|
||||||
|
}
|
|
@ -67,7 +67,9 @@ abstract class PaperweightUser : Plugin<Project> {
|
||||||
|
|
||||||
val sharedCacheRoot = target.gradle.gradleUserHomeDir.toPath().resolve("caches/paperweight-userdev")
|
val sharedCacheRoot = target.gradle.gradleUserHomeDir.toPath().resolve("caches/paperweight-userdev")
|
||||||
|
|
||||||
target.gradle.sharedServices.registerIfAbsent(DOWNLOAD_SERVICE_NAME, DownloadService::class) {}
|
target.gradle.sharedServices.registerIfAbsent(DOWNLOAD_SERVICE_NAME, DownloadService::class) {
|
||||||
|
parameters.projectPath.set(target.projectDir)
|
||||||
|
}
|
||||||
|
|
||||||
val cleanAll = target.tasks.register<Delete>("cleanAllPaperweightUserdevCaches") {
|
val cleanAll = target.tasks.register<Delete>("cleanAllPaperweightUserdevCaches") {
|
||||||
group = "paperweight"
|
group = "paperweight"
|
||||||
|
|
|
@ -70,12 +70,12 @@ class SetupHandlerImplV2(
|
||||||
override val hashFile: Path = cache.resolve(paperSetupOutput("minecraftLibraries", "hashes"))
|
override val hashFile: Path = cache.resolve(paperSetupOutput("minecraftLibraries", "hashes"))
|
||||||
|
|
||||||
override fun run(context: SetupHandler.Context) {
|
override fun run(context: SetupHandler.Context) {
|
||||||
downloadMinecraftLibraries(
|
downloadLibraries(
|
||||||
download = parameters.downloadService,
|
download = parameters.downloadService,
|
||||||
workerExecutor = context.workerExecutor,
|
workerExecutor = context.workerExecutor,
|
||||||
targetDir = minecraftLibraryJars,
|
targetDir = minecraftLibraryJars,
|
||||||
repositories = listOf(MC_LIBRARY_URL, MAVEN_CENTRAL_URL),
|
repositories = listOf(MC_LIBRARY_URL, MAVEN_CENTRAL_URL),
|
||||||
mcLibraries = bundle.config.buildData.vanillaServerLibraries,
|
libraries = bundle.config.buildData.vanillaServerLibraries,
|
||||||
sources = false
|
sources = false
|
||||||
).await()
|
).await()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue