From 0f2bab79ab266fb1bc43095d55fb65832c223842 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Sun, 27 Oct 2024 07:56:54 +0100 Subject: [PATCH 01/38] paperweight v2 --- .editorconfig | 3 + .github/workflows/deploy-snapshot.yml | 4 +- .github/workflows/test.yml | 12 +- .gitignore | 4 + .../src/main/kotlin/config-kotlin.gradle.kts | 40 +- gradle.properties | 2 +- gradle/libs.versions.toml | 26 +- gradle/wrapper/gradle-wrapper.properties | 2 +- paperweight-core/build.gradle.kts | 1 + .../paperweight/core/PaperweightCore.kt | 54 ++- .../core/extension/PaperExtension.kt | 8 +- .../extension/PaperweightCoreExtension.kt | 7 + .../core/taskcontainers/AllTasks.kt | 21 +- .../core/taskcontainers/InitialTasks.kt | 7 +- .../core/taskcontainers/SoftSpoonTasks.kt | 373 ++++++++++++++++++ .../core/taskcontainers/SpigotTasks.kt | 4 +- .../core/taskcontainers/VanillaTasks.kt | 4 +- paperweight-lib/build.gradle.kts | 9 + .../io/papermc/paperweight/DownloadService.kt | 26 +- .../tasks/ApplyCraftBukkitPatches.kt | 4 +- .../paperweight/tasks/ApplyGitPatches.kt | 16 +- .../paperweight/tasks/ApplyPaperPatches.kt | 2 +- .../paperweight/tasks/DownloadServerJar.kt | 3 +- .../paperweight/tasks/ExtractFromBundler.kt | 13 +- .../io/papermc/paperweight/tasks/MacheTask.kt | 83 ++++ .../tasks/MergeAccessTransforms.kt | 3 +- .../paperweight/tasks/RemapAccessTransform.kt | 3 +- .../papermc/paperweight/tasks/RemapSources.kt | 3 +- .../paperweight/tasks/RemapSpigotAt.kt | 3 +- .../paperweight/tasks/download-task.kt | 53 ++- .../paperweight/tasks/mache/DecompileJar.kt | 112 ++++++ .../paperweight/tasks/mache/RemapJar.kt | 115 ++++++ .../paperweight/tasks/mache/SetupVanilla.kt | 216 ++++++++++ .../tasks/patchremap/PatchApplier.kt | 4 +- .../tasks/softspoon/ApplyFeaturePatches.kt | 76 ++++ .../tasks/softspoon/ApplyFilePatches.kt | 172 ++++++++ .../tasks/softspoon/ApplyFilePatchesFuzzy.kt | 53 +++ .../tasks/softspoon/ApplySourceAT.kt | 135 +++++++ .../tasks/softspoon/FixupFilePatches.kt | 45 +++ .../tasks/softspoon/RebuildFilePatches.kt | 298 ++++++++++++++ .../tasks/softspoon/SetupPaperScript.kt | 230 +++++++++++ .../io/papermc/paperweight/util/McDev.kt | 23 +- .../kotlin/io/papermc/paperweight/util/at.kt | 77 ++++ .../paperweight/util/constants/constants.kt | 18 + .../data/mache/MacheAdditionalDependencies.kt | 28 ++ .../util/data/mache/MacheDependencies.kt | 31 ++ .../paperweight/util/data/mache/MacheMeta.kt | 33 ++ .../util/data/mache/MacheRepository.kt | 29 ++ .../util/data/mache/MavenArtifact.kt | 35 ++ .../io/papermc/paperweight/util/file.kt | 47 ++- .../kotlin/io/papermc/paperweight/util/git.kt | 11 + .../io/papermc/paperweight/util/utils.kt | 18 +- .../src/main/resources/post-rewrite.sh | 11 + .../patcher/tasks/PatcherApplyGitPatches.kt | 4 +- .../paperweight/userdev/PaperweightUser.kt | 4 +- .../internal/setup/v2/SetupHandlerImplV2.kt | 4 +- 56 files changed, 2532 insertions(+), 90 deletions(-) create mode 100644 paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MacheTask.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFeaturePatches.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatches.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatchesFuzzy.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceAT.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/FixupFilePatches.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/SetupPaperScript.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheAdditionalDependencies.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheDependencies.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheMeta.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheRepository.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MavenArtifact.kt create mode 100644 paperweight-lib/src/main/resources/post-rewrite.sh diff --git a/.editorconfig b/.editorconfig index 340d0e17e..c2aa2e6f6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -83,3 +83,6 @@ ij_kotlin_field_annotation_wrap = split_into_lines ij_kotlin_finally_on_new_line = false ij_kotlin_if_rparen_on_new_line = true ij_kotlin_import_nested_classes = false + +[*.patch] +trim_trailing_whitespace=false diff --git a/.github/workflows/deploy-snapshot.yml b/.github/workflows/deploy-snapshot.yml index 2087f8d3b..a40c9c72e 100644 --- a/.github/workflows/deploy-snapshot.yml +++ b/.github/workflows/deploy-snapshot.yml @@ -1,7 +1,7 @@ name: Deploy Snapshot on: push: - branches: [ 'main' ] + branches: [ 'main', 'softspoon-v2' ] paths-ignore: - 'license/*' - 'readme.md' @@ -29,7 +29,7 @@ jobs: echo version=$project_version >> $GITHUB_OUTPUT - name: Deploy snapshot version 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: ORG_GRADLE_PROJECT_paperUsername: ${{ secrets.DEPLOY_USER }} ORG_GRADLE_PROJECT_paperPassword: ${{ secrets.DEPLOY_PASS }} diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 34b52e960..ecb393f09 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -19,4 +19,14 @@ jobs: - name: Setup Gradle uses: gradle/gradle-build-action@v2 - 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 diff --git a/.gitignore b/.gitignore index fd472d078..0e978bd93 100644 --- a/.gitignore +++ b/.gitignore @@ -43,3 +43,7 @@ ehthumbs_vista.db # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) !gradle-wrapper.ja + +# todo remove again +/test/ +/testfork/ diff --git a/buildSrc/src/main/kotlin/config-kotlin.gradle.kts b/buildSrc/src/main/kotlin/config-kotlin.gradle.kts index 9efe9cad7..a96128eed 100644 --- a/buildSrc/src/main/kotlin/config-kotlin.gradle.kts +++ b/buildSrc/src/main/kotlin/config-kotlin.gradle.kts @@ -1,5 +1,7 @@ import com.diffplug.gradle.spotless.SpotlessExtension import net.kyori.indra.licenser.spotless.IndraSpotlessLicenserExtension +import org.gradle.api.tasks.testing.logging.TestExceptionFormat +import org.gradle.api.tasks.testing.logging.TestLogEvent plugins { idea @@ -11,7 +13,7 @@ java { } tasks.withType(JavaCompile::class).configureEach { - options.release = 11 + options.release = 17 } kotlin { @@ -21,8 +23,8 @@ kotlin { target { compilations.configureEach { kotlinOptions { - jvmTarget = "11" - freeCompilerArgs = listOf("-Xjvm-default=all", "-Xjdk-release=11") + jvmTarget = "17" + freeCompilerArgs = listOf("-Xjvm-default=all", "-Xjdk-release=17", "-opt-in=kotlin.io.path.ExperimentalPathApi") } } } @@ -38,6 +40,28 @@ repositories { mavenContent { includeGroup("codechicken") 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() @@ -55,6 +79,16 @@ testing { useKotlinTest(embeddedKotlinVersion) dependencies { implementation("org.junit.jupiter:junit-jupiter-engine:5.10.1") + implementation("org.junit.platform:junit-platform-launcher:1.10.1") + } + + targets.configureEach { + testTask { + testLogging { + events(TestLogEvent.FAILED) + exceptionFormat = TestExceptionFormat.FULL + } + } } } } diff --git a/gradle.properties b/gradle.properties index a4e83607b..8015950f8 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ group = io.papermc.paperweight -version = 1.7.8-SNAPSHOT +version = 2.0.0-SNAPSHOT org.gradle.caching = true org.gradle.parallel = true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 829b158dd..c5ad7b8c0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,9 @@ [versions] -asm = "9.7" +asm = "9.7.1" lorenz = "0.5.8" -hypo = "1.2.4" +hypo = "2.3.0" +serialize = "1.5.1" +feather = "1.1.0" [libraries] 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" 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" cadix-lorenz-core = { module = "org.cadixdev:lorenz", version.ref = "lorenz" } @@ -17,6 +21,7 @@ cadix-lorenz-proguard = { module = "org.cadixdev:lorenz-io-proguard", version.re cadix-atlas = "org.cadixdev:atlas:0.2.1" cadix-at = "org.cadixdev:at:0.1.0-rc1" 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-core = { module = "dev.denwav.hypo:hypo-core", version.ref = "hypo" } @@ -29,18 +34,29 @@ slf4j-jdk14 = "org.slf4j:slf4j-jdk14:1.7.32" lorenzTiny = "net.fabricmc:lorenz-tiny:3.0.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-licenser = "net.kyori:indra-licenser-spotless:3.1.3" gradle-spotless = "com.diffplug.spotless:spotless-plugin-gradle:6.23.1" gradle-shadow = "com.github.johnrengelman.shadow:com.github.johnrengelman.shadow.gradle.plugin:8.1.1" -gradle-kotlin-dsl = "org.gradle.kotlin.kotlin-dsl:org.gradle.kotlin.kotlin-dsl.gradle.plugin:4.3.0" +gradle-kotlin-dsl = "org.gradle.kotlin.kotlin-dsl:org.gradle.kotlin.kotlin-dsl.gradle.plugin:4.5.0" gradle-plugin-kotlin = { module = "org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin" } gradle-plugin-publish = "com.gradle.publish:plugin-publish-plugin:1.2.1" [bundles] 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"] kotson = ["kotson", "gson"] diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e7646dead..df97d72b8 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/paperweight-core/build.gradle.kts b/paperweight-core/build.gradle.kts index 99133c9ed..5957f60d9 100644 --- a/paperweight-core/build.gradle.kts +++ b/paperweight-core/build.gradle.kts @@ -7,6 +7,7 @@ dependencies { shade(projects.paperweightLib) implementation(libs.bundles.kotson) + implementation(libs.coroutines) } gradlePlugin { diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt index 26db8adb0..98e3efd56 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt @@ -25,6 +25,7 @@ package io.papermc.paperweight.core import io.papermc.paperweight.DownloadService import io.papermc.paperweight.core.extension.PaperweightCoreExtension 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.taskcontainers.BundlerJarTasks import io.papermc.paperweight.taskcontainers.DevBundleTasks @@ -53,7 +54,9 @@ class PaperweightCore : Plugin { 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("cleanCache") { group = "paper" @@ -61,14 +64,17 @@ class PaperweightCore : Plugin { delete(target.layout.cache) } - // Make sure the submodules are initialized, since there are files there - // which are required for configuration - target.layout.maybeInitSubmodules(target.offlineMode(), logger) + if (!ext.softSpoon.get()) { + // Make sure the submodules are initialized, since there are files there + // which are required for configuration + target.layout.maybeInitSubmodules(target.offlineMode(), logger) + } target.configurations.create(PARAM_MAPPINGS_CONFIG) target.configurations.create(REMAPPER_CONFIG) target.configurations.create(DECOMPILER_CONFIG) target.configurations.create(PAPERCLIP_CONFIG) + target.configurations.create(MACHE_CONFIG) if (target.providers.gradleProperty("paperweight.dev").orNull == "true") { target.tasks.register("diff") { @@ -90,10 +96,12 @@ class PaperweightCore : Plugin { ext.mainClass ) + val softSpoonTasks = SoftSpoonTasks(target, tasks) + target.createPatchRemapTask(tasks) target.tasks.register(PAPERWEIGHT_PREPARE_DOWNSTREAM) { - dependsOn(tasks.applyPatches) + dependsOn(tasks.applyPatchesLegacy) vanillaJar.set(tasks.downloadServerJar.flatMap { it.outputJar }) remappedJar.set(tasks.lineMapJar.flatMap { it.outputJar }) decompiledJar.set(tasks.decompileJar.flatMap { it.outputJar }) @@ -124,21 +132,35 @@ class PaperweightCore : Plugin { } target.afterEvaluate { + println("SoftSpoon: ${ext.softSpoon.get()}") + target.repositories { - maven(ext.paramMappingsRepo) { - name = PARAM_MAPPINGS_REPO_NAME - content { onlyForConfigurations(PARAM_MAPPINGS_CONFIG) } - } - maven(ext.remapRepo) { - name = REMAPPER_REPO_NAME - content { onlyForConfigurations(REMAPPER_CONFIG) } - } - maven(ext.decompileRepo) { - name = DECOMPILER_REPO_NAME - content { onlyForConfigurations(DECOMPILER_CONFIG) } + if (!ext.softSpoon.get()) { + maven(ext.paramMappingsRepo) { + name = PARAM_MAPPINGS_REPO_NAME + content { onlyForConfigurations(PARAM_MAPPINGS_CONFIG) } + } + maven(ext.remapRepo) { + name = REMAPPER_REPO_NAME + content { onlyForConfigurations(REMAPPER_CONFIG) } + } + maven(ext.decompileRepo) { + 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 val cache = target.layout.cache diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperExtension.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperExtension.kt index 9d5fac379..d9184ab68 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperExtension.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperExtension.kt @@ -38,8 +38,12 @@ open class PaperExtension(objects: ObjectFactory, layout: ProjectLayout) { val spigotServerPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "patches/server") val remappedSpigotServerPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "patches/server-remapped") val unmappedSpigotServerPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "patches/server-unmapped") - val paperApiDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "Paper-API") - val paperServerDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "Paper-Server") + val paperApiDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "paper-api") + val paperServerDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "paper-server") + val rejectsDir: DirectoryProperty = objects.dirFrom(paperServerDir, "patches/rejected") + val sourcePatchDir: DirectoryProperty = objects.dirFrom(paperServerDir, "patches/sources") + val resourcePatchDir: DirectoryProperty = objects.dirFrom(paperServerDir, "patches/resources") + val featurePatchDir: DirectoryProperty = objects.dirFrom(paperServerDir, "patches/features") @Suppress("MemberVisibilityCanBePrivate") val buildDataDir: DirectoryProperty = objects.dirWithDefault(layout, "build-data") diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt index 08c2fddf2..cf41a9ded 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt @@ -36,10 +36,13 @@ import org.gradle.kotlin.dsl.* open class PaperweightCoreExtension(project: Project, objects: ObjectFactory, layout: ProjectLayout) { + val softSpoon: Property = objects.property().convention(false) + @Suppress("MemberVisibilityCanBePrivate") val workDir: DirectoryProperty = objects.dirWithDefault(layout, "work") val minecraftVersion: Property = objects.property() + val minecraftManifestUrl: Property = objects.property().convention(MC_MANIFEST_URL) val serverProject: Property = objects.property() val mainClass: Property = objects.property().convention("org.bukkit.craftbukkit.Main") @@ -50,6 +53,10 @@ open class PaperweightCoreExtension(project: Project, objects: ObjectFactory, la val paramMappingsRepo: Property = objects.property() val decompileRepo: Property = objects.property() val remapRepo: Property = objects.property() + val macheRepo: Property = objects.property().convention("https://repo.papermc.io/repository/maven-public/") + + val macheOldPath: DirectoryProperty = objects.directoryProperty() + val gitFilePatches: Property = objects.property().convention(false) val vanillaJarIncludes: ListProperty = objects.listProperty().convention( listOf("/*.class", "/net/minecraft/**", "/com/mojang/math/**") diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt index 9f9d6aea8..f6ac77d1e 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt @@ -101,6 +101,23 @@ open class AllTasks( downloader.set(downloadService) } + val downloadPaperLibrariesSources by tasks.registering { + 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") val applyServerPatches by tasks.registering { group = "paper" @@ -126,7 +143,7 @@ open class AllTasks( mcDevSources.set(extension.mcDevSourceDir) } - val applyPatches by tasks.registering { + val applyPatchesLegacy by tasks.registering { group = "paper" description = "Set up the Paper development environment" dependsOn(applyApiPatches, applyServerPatches) @@ -151,7 +168,7 @@ open class AllTasks( } @Suppress("unused") - val rebuildPatches by tasks.registering { + val rebuildPatchesLegacy by tasks.registering { group = "paper" description = "Rebuilds patches to api and server" dependsOn(rebuildApiPatches, rebuildServerPatches) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/InitialTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/InitialTasks.kt index 09af05c9f..ad8982f17 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/InitialTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/InitialTasks.kt @@ -45,7 +45,7 @@ open class InitialTasks( ) { val downloadMcManifest by tasks.registering { - url.set(MC_MANIFEST_URL) + url.set(project.ext.minecraftManifestUrl) outputFile.set(cache.resolve(MC_MANIFEST)) 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(it) } - val downloadMcVersionManifest by tasks.registering { + val downloadMcVersionManifest by tasks.registering { url.set( mcManifest.zip(extension.minecraftVersion) { manifest, version -> manifest.versions.first { it.id == version }.url @@ -71,7 +71,7 @@ open class InitialTasks( } private val versionManifest = downloadMcVersionManifest.flatMap { it.outputFile }.map { gson.fromJson(it) } - val downloadMappings by tasks.registering { + val downloadMappings by tasks.registering { url.set(versionManifest.map { version -> version.serverMappingsDownload().url }) expectedHash.set(versionManifest.map { version -> version.serverMappingsDownload().hash() }) outputFile.set(cache.resolve(SERVER_MAPPINGS)) @@ -94,5 +94,6 @@ open class InitialTasks( serverLibrariesList.set(cache.resolve(SERVER_LIBRARIES_LIST)) serverVersionsList.set(cache.resolve(SERVER_VERSIONS_LIST)) serverLibraryJars.set(cache.resolve(MINECRAFT_JARS_PATH)) + serverJar.set(cache.resolve(SERVER_JAR)) } } diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt new file mode 100644 index 000000000..1aa6d5bea --- /dev/null +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt @@ -0,0 +1,373 @@ +/* + * 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.FixupFilePatches +import io.papermc.paperweight.tasks.softspoon.RebuildFilePatches +import io.papermc.paperweight.tasks.softspoon.SetupPaperScript +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 { + 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)) + macheOld.set(project.ext.macheOldPath) + 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) + rejects.set(project.ext.paper.rejectsDir) + gitFilePatches.set(project.ext.gitFilePatches) + } + + 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) + rejects.set(project.ext.paper.rejectsDir) + gitFilePatches.set(project.ext.gitFilePatches) + } + + 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) + gitFilePatches.set(project.ext.gitFilePatches) + } + + 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) + } + + val fixupSourcePatches by tasks.registering(FixupFilePatches::class) { + group = "softspoon" + description = "Puts the currently tracked source changes into the file patches commit" + + repo.set(project.ext.serverProject.map { it.layout.projectDirectory.dir("src/vanilla/java") }) + } + + val fixupResourcePatches by tasks.registering(FixupFilePatches::class) { + group = "softspoon" + description = "Puts the currently tracked resource changes into the file patches commit" + + repo.set(project.ext.serverProject.map { it.layout.projectDirectory.dir("src/vanilla/resources") }) + } + + val setupPaperScript by tasks.registering(SetupPaperScript::class) { + group = "softspoon" + description = "Creates a util script and installs it into path" + + root.set(project.projectDir) + } + + fun afterEvaluate() { + // load mache + mache = this.project.configurations.named(MACHE_CONFIG).get().singleFile.toPath().openZip().use { zip -> + return@use gson.fromJson(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().sourceSets.named(SourceSet.MAIN_SOURCE_SET_NAME) { + java { + srcDirs(projectDir.resolve("src/vanilla/java")) + } + resources { + srcDirs(projectDir.resolve("src/vanilla/resources")) + } + } + } +} diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt index 4deb154a4..83b775513 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt @@ -53,7 +53,9 @@ open class SpigotTasks( val generateSpigotMappings by tasks.registering { 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)) notchToSpigotMappings.set(cache.resolve(OBF_SPIGOT_MAPPINGS)) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/VanillaTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/VanillaTasks.kt index e73f13eb3..7cb51ed8f 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/VanillaTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/VanillaTasks.kt @@ -49,7 +49,9 @@ open class VanillaTasks( val remapJar by tasks.registering { inputJar.set(filterVanillaJar.flatMap { it.outputJar }) - mappingsFile.set(generateMappings.flatMap { it.outputMappings }) + // TODO fix hypo for v1 stuff + // 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) toNamespace.set(DEOBF_NAMESPACE) remapper.from(project.configurations.named(REMAPPER_CONFIG)) diff --git a/paperweight-lib/build.gradle.kts b/paperweight-lib/build.gradle.kts index c3d6203c6..3fc65f709 100644 --- a/paperweight-lib/build.gradle.kts +++ b/paperweight-lib/build.gradle.kts @@ -9,6 +9,8 @@ repositories { dependencies { implementation(libs.httpclient) implementation(libs.bundles.kotson) + implementation(libs.coroutines) + implementation(libs.jgit) // ASM for inspection implementation(libs.bundles.asm) @@ -19,9 +21,16 @@ dependencies { implementation(libs.lorenzTiny) + implementation(libs.feather.core) + implementation(libs.feather.gson) + implementation(libs.jbsdiff) + implementation(libs.restamp) + implementation(variantOf(libs.diffpatch) { classifier("all") }) { isTransitive = false } + + testImplementation(libs.mockk) } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/DownloadService.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/DownloadService.kt index 0833b603a..12aae51cd 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/DownloadService.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/DownloadService.kt @@ -32,6 +32,8 @@ import java.time.format.DateTimeFormatter import java.util.Locale import java.util.concurrent.TimeUnit import kotlin.io.path.* +import kotlinx.coroutines.async +import kotlinx.coroutines.coroutineScope import org.apache.http.HttpHost import org.apache.http.HttpStatus 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.impl.client.CloseableHttpClient import org.apache.http.impl.client.HttpClientBuilder +import org.gradle.api.file.DirectoryProperty import org.gradle.api.logging.Logger import org.gradle.api.logging.Logging import org.gradle.api.services.BuildService import org.gradle.api.services.BuildServiceParameters -abstract class DownloadService : BuildService, AutoCloseable { +abstract class DownloadService : BuildService, AutoCloseable { + + interface Params : BuildServiceParameters { + val projectPath: DirectoryProperty + } private companion object { val LOGGER: Logger = Logging.getLogger(DownloadService::class.java) @@ -64,13 +71,19 @@ abstract class DownloadService : BuildService, Auto 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) { download(source, target) if (hash == null) { return } val dlHash = target.hashFile(hash.algorithm).asHexString().lowercase(Locale.ENGLISH) - if (dlHash == hash.valueLower) { + if (hash.value == "" || dlHash == hash.valueLower) { return } LOGGER.warn( @@ -91,6 +104,15 @@ abstract class DownloadService : BuildService, Auto private fun download(source: URL, target: Path) { 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") etagDir.createDirectories() diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyCraftBukkitPatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyCraftBukkitPatches.kt index cf180928f..08a31ea95 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyCraftBukkitPatches.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyCraftBukkitPatches.kt @@ -120,7 +120,7 @@ abstract class ApplyCraftBukkitPatches : ControllableOutputTask() { } git(*Git.add(ignoreGitIgnore, "src")).setupOut().execute() - git("commit", "-m", "Vanilla $ ${Date()}", "--author=Vanilla ").setupOut().execute() + git("commit", "-m", "Vanilla $ ${Date()}", "--author=Vanilla ").setupOut().execute() // Apply patches for (file in patchList) { @@ -135,7 +135,7 @@ abstract class ApplyCraftBukkitPatches : ControllableOutputTask() { } git(*Git.add(ignoreGitIgnore, "src")).setupOut().execute() - git("commit", "-m", "CraftBukkit $ ${Date()}", "--author=CraftBukkit ").setupOut().execute() + git("commit", "-m", "CraftBukkit $ ${Date()}", "--author=CraftBukkit ").setupOut().execute() } finally { if (rootPatchDir != patchDir.pathOrNull) { rootPatchDir.deleteRecursive() diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyGitPatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyGitPatches.kt index 9bc3ab134..27d8db0bb 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyGitPatches.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyGitPatches.kt @@ -107,7 +107,7 @@ abstract class ApplyGitPatches : ControllableOutputTask() { if (unneededFiles.isPresent && unneededFiles.get().size > 0) { unneededFiles.get().forEach { path -> outputDir.path.resolve(path).deleteRecursive() } git(*Git.add(ignoreGitIgnore, ".")).executeSilently() - git("commit", "-m", "Initial", "--author=Initial Source ").executeSilently() + git("commit", "-m", "Initial", "--author=Initial Source ").executeSilently() } git("tag", "-d", "base").runSilently(silenceErr = true) @@ -189,16 +189,16 @@ fun Git.disableAutoGpgSigningInRepo() { 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.disableAutoGpgSigningInRepo() - git("remote", "remove", "upstream").runSilently(silenceErr = true) - git("remote", "add", "upstream", upstream.toUri().toString()).executeSilently(silenceErr = true) - git("fetch", "upstream", "--prune").executeSilently(silenceErr = true) - if (git("checkout", "master").runSilently(silenceErr = true) != 0) { - git("checkout", "-b", "master").runSilently(silenceErr = true) + git("remote", "remove", upstreamName).runSilently(silenceErr = true) + git("remote", "add", upstreamName, upstream.toUri().toString()).executeSilently(silenceErr = true) + git("fetch", upstreamName, "--prune", "--prune-tags", "--force").executeSilently(silenceErr = true) + if (git("checkout", branchName).runSilently(silenceErr = true) != 0) { + 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) } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyPaperPatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyPaperPatches.kt index 36b4ab09c..6f1904e67 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyPaperPatches.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyPaperPatches.kt @@ -161,7 +161,7 @@ abstract class ApplyPaperPatches : ControllableOutputTask() { unneededFiles.orNull?.forEach { path -> outputFile.resolve(path).deleteRecursive() } git(*Git.add(ignoreGitIgnore, ".")).executeSilently() - git("commit", "-m", "Initial", "--author=Initial Source ").executeSilently() + git("commit", "-m", "Initial", "--author=Initial Source ").executeSilently() git("tag", "-d", "base").runSilently(silenceErr = true) git("tag", "base").executeSilently() diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/DownloadServerJar.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/DownloadServerJar.kt index 7040764d0..6f13ee7d7 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/DownloadServerJar.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/DownloadServerJar.kt @@ -28,7 +28,7 @@ import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.Property import org.gradle.api.tasks.* -// Not cached since this is Mojang's server jar +@CacheableTask abstract class DownloadServerJar : BaseTask() { @get:Input @@ -41,7 +41,6 @@ abstract class DownloadServerJar : BaseTask() { abstract val downloader: Property @get:Nested - @get:Optional abstract val expectedHash: Property override fun init() { diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ExtractFromBundler.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ExtractFromBundler.kt index afd208eba..4e8ec1a78 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ExtractFromBundler.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ExtractFromBundler.kt @@ -59,11 +59,6 @@ abstract class ExtractFromBundler : BaseTask() { @get:OutputFile abstract val serverVersionsList: RegularFileProperty - override fun init() { - super.init() - serverJar.set(defaultOutput()) - } - @TaskAction fun run() { ServerBundler.extractFromBundler( @@ -99,16 +94,16 @@ object ServerBundler { } 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 -> serverVersionJson.copyTo(output, overwrite = true) } val versionId = gson.fromJson(serverVersionJson)["id"].asString - val versions = bundlerZip.resolve("/META-INF/versions.list").readLines() + val versions = bundlerZip.resolve(FileEntry.VERSIONS_LIST).readLines() .map { it.split('\t') } .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() serverJarPath.copyTo(serverJar, overwrite = true) @@ -117,7 +112,7 @@ object ServerBundler { private fun extractLibraryJars(bundlerZip: Path, serverLibraryJars: Path) { serverLibraryJars.deleteRecursive() serverLibraryJars.parent.createDirectories() - bundlerZip.resolve("/META-INF/libraries").copyRecursivelyTo(serverLibraryJars) + bundlerZip.resolve(FileEntry.LIBRARIES_DIR).copyRecursivelyTo(serverLibraryJars) } private fun writeLibrariesTxt(bundlerZip: Path, serverLibrariesTxt: Path) { diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MacheTask.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MacheTask.kt new file mode 100644 index 000000000..d00a9a702 --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MacheTask.kt @@ -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(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) + // } + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MergeAccessTransforms.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MergeAccessTransforms.kt index c7df0d178..ecc8d2c26 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MergeAccessTransforms.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MergeAccessTransforms.kt @@ -34,6 +34,7 @@ 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 writeLF @CacheableTask abstract class MergeAccessTransforms : BaseTask() { @@ -67,6 +68,6 @@ abstract class MergeAccessTransforms : BaseTask() { outputAt.merge(at) } - AccessTransformFormats.FML.write(outputFile.path, outputAt) + AccessTransformFormats.FML.writeLF(outputFile.path, outputAt) } } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapAccessTransform.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapAccessTransform.kt index 51359dc4f..0f86bab3d 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapAccessTransform.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapAccessTransform.kt @@ -32,6 +32,7 @@ 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 writeLF @CacheableTask abstract class RemapAccessTransform : BaseTask() { @@ -57,6 +58,6 @@ abstract class RemapAccessTransform : BaseTask() { val mappingSet = MappingFormats.TINY.read(mappings.path, SPIGOT_NAMESPACE, DEOBF_NAMESPACE) val resultAt = at.remap(mappingSet) - AccessTransformFormats.FML.write(outputFile.path, resultAt) + AccessTransformFormats.FML.writeLF(outputFile.path, resultAt) } } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSources.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSources.kt index 50d162a91..79e6db3d1 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSources.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSources.kt @@ -51,6 +51,7 @@ import org.gradle.kotlin.dsl.* import org.gradle.workers.WorkAction import org.gradle.workers.WorkParameters import org.gradle.workers.WorkerExecutor +import writeLF @CacheableTask abstract class RemapSources : JavaLauncherTask() { @@ -260,7 +261,7 @@ abstract class RemapSources : JavaLauncherTask() { } if (generatedAtOutPath != null) { - AccessTransformFormats.FML.write(generatedAtOutPath, processAt) + AccessTransformFormats.FML.writeLF(generatedAtOutPath, processAt) } } } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSpigotAt.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSpigotAt.kt index 5f25d777d..909780649 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSpigotAt.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSpigotAt.kt @@ -40,6 +40,7 @@ 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 writeLF @CacheableTask abstract class RemapSpigotAt : BaseTask() { @@ -108,7 +109,7 @@ abstract class RemapSpigotAt : BaseTask() { val mappings = MappingFormats.TINY.read(mapping.path, SPIGOT_NAMESPACE, DEOBF_NAMESPACE) val remappedAt = outputAt.remap(mappings) - AccessTransformFormats.FML.write(outputFile.path, remappedAt) + AccessTransformFormats.FML.writeLF(outputFile.path, remappedAt) } private fun parseAccess(text: String): AccessTransform { diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/download-task.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/download-task.kt index 55f46995d..d3e02b4bb 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/download-task.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/download-task.kt @@ -72,6 +72,9 @@ abstract class DownloadTask : DefaultTask() { fun run() = downloader.get().download(url, outputFile, expectedHash.orNull) } +@CacheableTask +abstract class CacheableDownloadTask : DownloadTask() + @CacheableTask abstract class DownloadMcLibraries : BaseTask() { @@ -101,7 +104,7 @@ abstract class DownloadMcLibraries : BaseTask() { @TaskAction fun run() { - downloadMinecraftLibraries( + downloadLibraries( downloader, workerExecutor, outputDir.path, @@ -112,20 +115,62 @@ abstract class DownloadMcLibraries : BaseTask() { } } -fun downloadMinecraftLibraries( +@CacheableTask +abstract class DownloadPaperLibraries : BaseTask() { + + @get:Input + abstract val paperDependencies: ListProperty + + @get:Input + abstract val repositories: ListProperty + + @get:OutputDirectory + abstract val outputDir: DirectoryProperty + + @get:Internal + abstract val downloader: Property + + @get:Inject + abstract val workerExecutor: WorkerExecutor + + @get:Input + abstract val sources: Property + + 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, workerExecutor: WorkerExecutor, targetDir: Path, repositories: List, - mcLibraries: List, + libraries: List, sources: Boolean ): WorkQueue { val excludes = listOf(targetDir.fileSystem.getPathMatcher("glob:*.etag")) targetDir.deleteRecursive(excludes) + if (!targetDir.exists()) { + targetDir.createDirectories() + } val queue = workerExecutor.noIsolation() - for (lib in mcLibraries) { + for (lib in libraries) { if (sources) { queue.submit(DownloadSourcesToDirAction::class) { repos.set(repositories) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt new file mode 100644 index 000000000..17015b205 --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt @@ -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 + + @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() + } + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt new file mode 100644 index 000000000..48456e60c --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt @@ -0,0 +1,115 @@ +/* + * 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 + + @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() { + if (minecraftClasspath.files.isEmpty()) { + // TODO this shouldn't happen, ideally we somehow make the minecraft classpath available on the first run too + throw RuntimeException("Could not resolve minecraft dependencies, try again") + } + + val out = outputJar.convertToPath().ensureClean() + + val logFile = out.resolveSibling("${out.name}.log") + + try { + 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 + } + } + } catch (e: Exception) { + throw RuntimeException("Error while running codebook, see ${logFile.pathString} for details", e) + } + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt new file mode 100644 index 000000000..b8cd66133 --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt @@ -0,0 +1,216 @@ +/* + * 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.eclipse.jgit.transport.URIish +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> + + @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 + + @get:Optional + @get:InputDirectory + abstract val macheOld: DirectoryProperty + + @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", "noreply+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() + } + + if (macheOld.isPresent) { + println("Using ${macheOld.convertToPath().absolutePathString()} as starting point") + git.remoteRemove().setRemoteName("old").call() + git.remoteAdd().setName("old").setUri(URIish(macheOld.convertToPath().absolutePathString())).call() + git.fetch().setRemote("old").call() + git.checkout().setName("old/mache").call() + git.branchDelete().setBranchNames("main").setForce(true).call() + git.checkout().setName("main").setCreateBranch(true).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...") + if (!macheOld.isPresent) { + // skip this if we are diffing against old, since it would be a commit without mache patches + 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, "noreply+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() + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/PatchApplier.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/PatchApplier.kt index 8944f3f1c..24ddb18f0 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/PatchApplier.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/PatchApplier.kt @@ -54,7 +54,7 @@ class PatchApplier( fun commitPlain(message: String) { git(*Git.add(ignoreGitIgnore, ".")).executeSilently() - git("commit", "-m", message, "--author=Initial ").executeSilently() + git("commit", "-m", message, "--author=Initial ").executeSilently() } fun createBranches() { @@ -64,7 +64,7 @@ class PatchApplier( fun commitInitialRemappedSource() { git(*Git.add(ignoreGitIgnore, ".")).executeSilently() - git("commit", "-m", "Initial Remapped Source", "--author=Initial ").executeSilently() + git("commit", "-m", "Initial Remapped Source", "--author=Initial ").executeSilently() git("tag", remappedBaseTag).executeSilently() } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFeaturePatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFeaturePatches.kt new file mode 100644 index 000000000..5474e07e0 --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFeaturePatches.kt @@ -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 + + 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()) + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatches.kt new file mode 100644 index 000000000..0837044c9 --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatches.kt @@ -0,0 +1,172 @@ +/* + * 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 java.time.Instant +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.* +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 + + @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 + + @get:Optional + @get:OutputDirectory + abstract val rejects: DirectoryProperty + + @get:Optional + @get:Input + abstract val gitFilePatches: Property + + init { + run { + verbose.convention(false) + gitFilePatches.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 result = if (gitFilePatches.get()) { + applyWithGit(outputPath) + } else { + applyWithDiffPatch() + } + + if (!verbose.get()) { + logger.lifecycle("Applied $result patches") + } + } + + private fun applyWithGit(outputPath: Path): Int { + val git = Git(outputPath) + val patches = patches.convertToPath().filesMatchingRecursive("*.patch") + val patchStrings = patches.map { outputPath.relativize(it).pathString } + patchStrings.chunked(12).forEach { + git("apply", "--3way", *it.toTypedArray()).executeSilently(silenceOut = !verbose.get(), silenceErr = !verbose.get()) + } + + commit() + + return patches.size + } + + private fun applyWithDiffPatch(): Int { + val printStream = PrintStream(LoggingOutputStream(logger, LogLevel.LIFECYCLE)) + val builder = 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") + if (rejects.isPresent) { + builder.rejectsPath(rejects.convertToPath()) + } + + val result = builder.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") + } + + return result.summary.changedFiles + } + + 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(PersonIdent("File", "noreply+automated@papermc.io"), Instant.parse("1997-04-20T13:37:42.69Z")) + 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 + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatchesFuzzy.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatchesFuzzy.kt new file mode 100644 index 000000000..445d4eba0 --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatchesFuzzy.kt @@ -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 + + init { + run { + minFuzz.convention("0.5") + } + } + + override fun mode(): PatchMode { + return PatchMode.FUZZY + } + + override fun minFuzz(): Float { + return minFuzz.get().toFloat() + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceAT.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceAT.kt new file mode 100644 index 000000000..2ed1a5462 --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceAT.kt @@ -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 { + 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() + 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() + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/FixupFilePatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/FixupFilePatches.kt new file mode 100644 index 000000000..16ed771d9 --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/FixupFilePatches.kt @@ -0,0 +1,45 @@ +/* + * 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 org.gradle.api.file.DirectoryProperty +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.UntrackedTask + +@UntrackedTask(because = "Always fixup when requested") +abstract class FixupFilePatches : BaseTask() { + + @get:InputDirectory + abstract val repo: DirectoryProperty + + @TaskAction + fun run() { + val git = Git(repo) + git("commit", "add", ".").executeOut() + git("commit", "--fixup", "file").executeOut() + git("-c", "sequence.editor=:", "rebase", "-i", "--autosquash", "mache/main").executeOut() + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt new file mode 100644 index 000000000..ff9c3e8ca --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt @@ -0,0 +1,298 @@ +/* + * 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.PaperweightException +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.intellij.lang.annotations.Language +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 + + @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 + + @get:Optional + @get:Input + abstract val gitFilePatches: Property + + override fun init() { + contextLines.convention(3) + verbose.convention(false) + gitFilePatches.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 + val filesWithNewAts = mutableListOf() + 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", "") + if (handleATInSource(source, ats, className)) { + handleATInBase(decomp, ats, baseDir) + filesWithNewAts.add(it) + } + 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" + ) + } + + if (filesWithNewAts.isNotEmpty()) { + git("status").executeOut() + git("diff").executeOut() + // we removed the comment, we need to commit this + git("add", ".").executeOut() + git("commit", "--amend", "--no-edit").executeOut() + } + + // rebuild patches + val result = if (gitFilePatches.get()) { + rebuildWithGit(git, patchDir) + } else { + rebuildWithDiffPatch(baseDir, inputDir, patchDir) + } + + git("switch", "-").executeSilently(silenceErr = true) + if (filesWithNewAts.isNotEmpty()) { + try { + // we need to rebase, so that the new file commit is part of the tree again. + // for that we use GIT_SEQUENCE_EDITOR to drop the first commit + // and then execs for all the files that remove the papter + // todo detect if sed is not present (windows) and switch out sed for something else + @Language("Shell Script") + val sequenceEditor = "sed -i -e 0,/pick/{s/pick/drop/}" + val execs = filesWithNewAts + .map { "sed -i -e 's|// Paper-AT:.*||g' $it && ((git add $it && git commit --amend --no-edit) || true)" } + .flatMap { listOf("--exec", it) }.toTypedArray() + git.withEnv( + mapOf("GIT_SEQUENCE_EDITOR" to sequenceEditor) + )("rebase", "-i", "file", "--strategy-option=theirs", *execs).executeSilently() + } catch (e: Exception) { + // TODO better message to inform the user on what to do + throw RuntimeException("Encountered conflicts while rebuilding file patches.", e) + } + } + git("stash", "pop").runSilently(silenceErr = true) + + val patchDirGit = Git(patchDir) + patchDirGit("add", "-A", ".").executeSilently() + + logger.lifecycle("Rebuilt $result patches") + } + + private fun rebuildWithGit( + git: Git, + patchDir: Path + ): Int { + val files = git("diff-tree", "--name-only", "--no-commit-id", "-r", "HEAD").getText().split("\n") + files.parallelStream().forEach { filename -> + if (filename.isBlank()) return@forEach + val patch = git( + "format-patch", + "--diff-algorithm=myers", + "--full-index", + "--no-signature", + "--no-stat", + "--no-numbered", + "-1", + "HEAD", + "--stdout", + filename + ).getText() + val patchFile = patchDir.resolve("$filename.patch") + patchFile.createParentDirectories() + patchFile.writeText(patch) + } + + return files.size + } + + private fun rebuildWithDiffPatch( + baseDir: Path, + inputDir: Path, + patchDir: Path + ): Int { + 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() + return result.summary.changedFiles + } + + 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() + + // mmmh, maybe add comment to base too? + + 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): Boolean { + val sourceLines = source.readLines() + var foundNew = false + val fixedLines = ArrayList(sourceLines.size) + sourceLines.forEach { line -> + if (!line.contains("// Paper-AT: ")) { + fixedLines.add(line) + return@forEach + } + + foundNew = true + + val split = line.split("// Paper-AT: ") + val at = split[1] + try { + val atClass = newAts.getOrCreateClass(className) + val parts = at.split(" ") + val accessTransform = atFromString(parts[0]) + val name = parts[1] + val index = name.indexOf('(') + if (index == -1) { + atClass.mergeField(name, accessTransform) + } else { + atClass.mergeMethod(MethodSignature.of(name.substring(0, index), name.substring(index)), accessTransform) + } + logger.lifecycle("Found new AT in $className: $at -> $accessTransform") + } catch (ex: Exception) { + throw PaperweightException("Found invalid AT '$at' in class $className") + } + + fixedLines.add(split[0]) + } + + if (foundNew) { + source.writeText(fixedLines.joinToString("\n", postfix = "\n"), Charsets.UTF_8) + } + + return foundNew + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/SetupPaperScript.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/SetupPaperScript.kt new file mode 100644 index 000000000..c3f2448c8 --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/SetupPaperScript.kt @@ -0,0 +1,230 @@ +/* + * 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 java.io.BufferedReader +import java.io.InputStreamReader +import kotlin.io.path.* +import org.gradle.api.file.DirectoryProperty +import org.gradle.api.provider.Property +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.InputDirectory +import org.gradle.api.tasks.TaskAction +import org.gradle.api.tasks.UntrackedTask +import org.gradle.api.tasks.options.Option + +@UntrackedTask(because = "Always setup paper script") +abstract class SetupPaperScript : BaseTask() { + + data class Command(val name: String, val aliases: List, val description: String, val commands: List) + + @get:Input + @get:Option( + option = "script-name", + description = "Allows setting the script name. Default is paper.", + ) + abstract val scriptName: Property + + @get:InputDirectory + abstract val root: DirectoryProperty + + init { + run { + scriptName.convention("paper") + } + } + + @TaskAction + open fun run() { + val scriptName = scriptName.get() + val rootPath = root.get().convertToPath().absolutePathString() + val commands = listOf( + Command("root", listOf(), "Jumps to the root directory (%root%)", listOf("cd %root%")), + Command("api", listOf("a"), "Jumps to the api directory", listOf("cd %root%/paper-api")), + Command("server", listOf("s"), "Jumps to the server directory", listOf("cd %root%/paper-server")), + Command("vanilla", listOf("v"), "Jumps to the vanilla directory", listOf("cd %root%/paper-server/src/vanilla/java")), + Command("resources", listOf("r"), "Jumps to the resources directory", listOf("cd %root%/paper-server/src/vanilla/resources")), + Command( + "fixupSourcePatches", + listOf("fs"), + "Puts the current source changes into the file patches commit", + listOf( + "cd %root%/paper-server/src/vanilla/java", + "git add .", + "git commit --fixup file", + "git -c sequence.editor=: rebase -i --autosquash mache/main" + ) + ), + Command( + "fixupResourcePatches", + listOf("fr"), + "Puts the current resource changes into the file patches commit", + listOf( + "cd %root%/paper-server/src/vanilla/resources", + "git add .", + "git commit --fixup file", + "git -c sequence.editor=: rebase -i --autosquash mache/main" + ) + ) + ) + + val isWindows = System.getProperty("os.name").lowercase().contains("win") + val script = generateScript(scriptName, rootPath, commands, isWindows) + + if (isWindows) { + val appData = System.getenv("APPDATA") + val paperFolder = Path(appData).resolve(".paper") + val path = paperFolder.resolve("$scriptName.bat") + path.createParentDirectories() + path.writeText(script) + + val alreadyOnPath = System.getenv("PATH").contains(paperFolder.absolutePathString()) + if (!alreadyOnPath) { + val command = """ + [Environment]::SetEnvironmentVariable(\"Path\", [Environment]::GetEnvironmentVariable(\"Path\", \"User\") + \";${paperFolder.absolutePathString()}\", \"User\") + """.trimIndent() + val process = Runtime.getRuntime().exec(arrayOf("powershell.exe", "-Command", command)) + process.waitFor() + val reader = BufferedReader(InputStreamReader(process.inputStream)) + val errorReader = BufferedReader(InputStreamReader(process.errorStream)) + + if (process.exitValue() != 0) { + reader.lines().forEach { println(it) } + errorReader.lines().forEach { println(it) } + println( + "Error while installing $scriptName script, " + + "please add \"${paperFolder.absolutePathString()}\" to PATH manually (exit code ${process.exitValue()})" + ) + } else { + println("$scriptName script installed") + } + } else { + println("$scriptName script created") + } + } else { + val paperFolder = Path("~").resolve(".paper") + val path = paperFolder.resolve("$scriptName.sh") + path.createParentDirectories() + path.writeText(script) + + val alreadyOnPath = System.getenv("PATH").contains(paperFolder.absolutePathString()) + if (!alreadyOnPath) { + // TODO what do you want to do here? + println("setting up path for linux is not supported yet, add ${paperFolder.absolutePathString()} to your path manually pls") + } else { + println("$scriptName script created") + } + } + } + + fun generateScript(scriptName: String, root: String, commands: List, isWindows: Boolean): String { + val script = StringBuilder() + val lineSeparator = if (isWindows) "\r\n" else "\n" + // header + val scriptHeader = if (isWindows) { + "@echo off$lineSeparator" + "goto:main$lineSeparator" + } else { + "#!/bin/bash$lineSeparator" + } + script.append(scriptHeader) + script.append(lineSeparator) + + // help + if (isWindows) { + script.append(":help$lineSeparator") + script.append("setlocal EnableDelayedExpansion$lineSeparator") + script.append("set \"\"=\"$lineSeparator") + script.append("echo Available commands:$lineSeparator") + } else { + script.append("help() {$lineSeparator") + script.append(" echo \"Available commands:\"$lineSeparator") + } + + commands.forEach { command -> + val aliases = command.aliases.joinToString(",", " (alias: ", ")") + val line = "$scriptName ${command.name}$aliases: ${command.description.replace("%root%", root)}" + if (isWindows) { + script.append("echo !\"!$line$lineSeparator") + } else { + script.append(" echo \"$line\"$lineSeparator") + } + } + + if (isWindows) { + script.append("goto:eof$lineSeparator") + } else { + script.append("}$lineSeparator") + } + script.append(lineSeparator) + + // commands + commands.forEach { command -> + if (isWindows) { + script.append(":${command.name}$lineSeparator") + command.commands.forEach { cmd -> + script.append("${cmd.replace("%root%", root)}$lineSeparator") + } + script.append("goto:eof$lineSeparator") + command.aliases.forEach { alias -> + script.append(":$alias$lineSeparator") + script.append("call:${command.name}$lineSeparator") + script.append("goto:eof$lineSeparator") + } + } else { + script.append("${command.name}() {$lineSeparator") + command.commands.forEach { cmd -> + script.append(" ${cmd.replace("%root%", root)}$lineSeparator") + } + script.append("}$lineSeparator") + command.aliases.forEach { alias -> + script.append("$alias() {$lineSeparator") + script.append(" ${command.name}$lineSeparator") + script.append("}$lineSeparator") + } + } + script.append(lineSeparator) + } + + // main + if (isWindows) { + script.append(":main$lineSeparator") + script.append("if \"%1\"==\"\" ($lineSeparator") + script.append(" echo No command provided, try $scriptName help$lineSeparator") + script.append(" exit /b 1$lineSeparator") + script.append(")$lineSeparator") + script.append(lineSeparator) + script.append("call:%1$lineSeparator") + } else { + script.append("if [ \$# -eq 0 ]; then$lineSeparator") + script.append(" echo \"No command provided, try $scriptName help\"$lineSeparator") + script.append(" exit 1$lineSeparator") + script.append("fi$lineSeparator") + script.append(lineSeparator) + script.append("\"$@\"$lineSeparator") + } + + return script.toString() + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/McDev.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/McDev.kt index 41e0f7450..071161843 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/McDev.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/McDev.kt @@ -35,16 +35,17 @@ object McDev { fun importMcDev( patches: Iterable, - decompJar: Path, + decompJar: Path?, importsFile: Path?, targetDir: Path, dataTargetDir: Path? = null, librariesDirs: List = 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() val decompDataFiles = mutableSetOf() @@ -127,7 +128,7 @@ object McDev { } // 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) for ((libraryFileName, importFilePath) in imports) { @@ -170,11 +171,11 @@ object McDev { } } - private fun readPatchLines(patches: Iterable): Pair, Set> { + private fun readPatchLines(patches: Iterable, javaSourceSet: String): Pair, Set> { val srcResult = hashSetOf() val dataResult = hashSetOf() - val javaPrefix = "+++ b/src/main/java/" + val javaPrefix = "+++ b$javaSourceSet/" val dataPrefix = "+++ b/src/main/resources/data/minecraft/" for (patch in patches) { @@ -216,7 +217,7 @@ object McDev { return Pair(srcResult, dataResult) } - private fun findLibraries(libraryImports: Path?, libFiles: List, patchLines: Set): Set { + private fun findLibraries(libraryImports: Path?, libFiles: List, patchLines: Set, javaSourceSet: String): Set { val result = hashSetOf() // Imports from library-imports.txt @@ -233,15 +234,15 @@ object McDev { } // Scan patches for necessary imports - result += findNeededLibraryImports(patchLines, libFiles) + result += findNeededLibraryImports(patchLines, libFiles, javaSourceSet) return result } - private fun findNeededLibraryImports(patchLines: Set, libFiles: List): Set { + private fun findNeededLibraryImports(patchLines: Set, libFiles: List, javaSourceSet: String): Set { val knownImportMap = findPossibleLibraryImports(libFiles) .associateBy { it.importFilePath } - val prefix = "+++ b/src/main/java/" + val prefix = "+++ b$javaSourceSet/" return patchLines.map { it.substringAfter(prefix) } .mapNotNull { knownImportMap[it] } .toSet() diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt new file mode 100644 index 000000000..1b19a872d --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt @@ -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) +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt index 2274e8d25..ec6b575b2 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt @@ -44,6 +44,7 @@ const val REMAPPER_CONFIG = "remapper" const val PLUGIN_REMAPPER_CONFIG = "pluginRemapper" const val DECOMPILER_CONFIG = "decompiler" const val PAPERCLIP_CONFIG = "paperclip" +const val MACHE_CONFIG = "mache" const val DEV_BUNDLE_CONFIG = "paperweightDevelopmentBundle" const val MOJANG_MAPPED_SERVER_CONFIG = "mojangMappedServer" 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 DECOMPILER_REPO_NAME = "paperweightDecompilerRepository" const val REMAPPER_REPO_NAME = "paperweightRemapperRepository" +const val MACHE_REPO_NAME = "paperweightMacheRepository" const val CACHE_PATH = "caches" 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_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" const val SERVER_MAPPINGS = "$MAPPINGS_DIR/server_mappings.txt" 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 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 SPIGOT_MOJANG_PARCHMENT_MAPPINGS = "$MAPPINGS_DIR/spigot-mojang+parchment.tiny" const val OBF_NAMESPACE = "official" const val SPIGOT_NAMESPACE = "spigot" const val DEOBF_NAMESPACE = "mojang+yarn" +const val NEW_DEOBF_NAMESPACE = "mojang+parchment" const val MAPPINGS_NAMESPACE_MANIFEST_KEY = "paperweight-mappings-namespace" 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_LIST = "$BUNDLER_PATH/libraries.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 TASK_CACHE = "$PAPER_PATH/taskCache" 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_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" @@ -119,6 +130,13 @@ const val IVY_REPOSITORY = "$PAPER_PATH/ivyRepository" 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 Task.paperTaskOutput(ext: String) = paperTaskOutput(name, ext) fun paperTaskOutput(name: String, ext: String) = "$TASK_CACHE/$name.$ext" diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheAdditionalDependencies.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheAdditionalDependencies.kt new file mode 100644 index 000000000..417d99c10 --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheAdditionalDependencies.kt @@ -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? = null, + val implementation: List? = null, +) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheDependencies.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheDependencies.kt new file mode 100644 index 000000000..630003ed0 --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheDependencies.kt @@ -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, + val paramMappings: List, + val constants: List, + val remapper: List, + val decompiler: List, +) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheMeta.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheMeta.kt new file mode 100644 index 000000000..e594ed51c --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheMeta.kt @@ -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, + val decompilerArgs: List, + val remapperArgs: List, + val additionalCompileDependencies: MacheAdditionalDependencies? = null, +) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheRepository.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheRepository.kt new file mode 100644 index 000000000..b2f8b4785 --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheRepository.kt @@ -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? = null, +) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MavenArtifact.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MavenArtifact.kt new file mode 100644 index 000000000..33c4d35c2 --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MavenArtifact.kt @@ -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" } ?: "") + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/file.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/file.kt index cc252dea6..7b0d99e14 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/file.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/file.kt @@ -25,16 +25,22 @@ package io.papermc.paperweight.util import io.papermc.paperweight.PaperweightException import java.io.InputStream import java.net.URI +import java.nio.file.FileAlreadyExistsException import java.nio.file.FileSystem +import java.nio.file.FileSystemNotFoundException import java.nio.file.FileSystems import java.nio.file.Files import java.nio.file.Path import java.nio.file.PathMatcher import java.nio.file.attribute.DosFileAttributeView +import java.nio.file.attribute.FileAttribute import java.util.Arrays import java.util.stream.Collectors import java.util.stream.Stream 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.streams.asSequence import org.gradle.api.Project @@ -142,13 +148,41 @@ private fun Path.jarUri(): URI { } fun Path.openZip(): FileSystem { - return FileSystems.newFileSystem(jarUri(), emptyMap()) + return try { + FileSystems.getFileSystem(jarUri()) + } catch (e: FileSystemNotFoundException) { + FileSystems.newFileSystem(jarUri(), emptyMap()) + } } fun Path.writeZip(): FileSystem { 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 { return StreamSupport.stream(rootDirectories.spliterator(), false) .flatMap { Files.walk(it) } @@ -257,3 +291,14 @@ private fun relativeCopyOrMove(baseDir: Path, file: Path, outputDir: Path, move: file.copyTo(destination, overwrite = true) } } + +fun Path.createParentDirectories(vararg attributes: FileAttribute<*>): Path = also { + val parent = it.parent + if (parent != null && !parent.isDirectory()) { + try { + parent.createDirectories(*attributes) + } catch (e: FileAlreadyExistsException) { + if (!parent.isDirectory()) throw e + } + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/git.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/git.kt index 71c9beeec..4d276271a 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/git.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/git.kt @@ -102,6 +102,17 @@ class Git(private val repo: Path, private val env: Map = emptyMa 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 + } } } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt index fa62d0672..1cd863945 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt @@ -75,6 +75,8 @@ import org.gradle.jvm.toolchain.JavaLauncher import org.gradle.jvm.toolchain.JavaToolchainService import org.gradle.kotlin.dsl.* +val whitespace = Regex("\\s+") + val gson: Gson = GsonBuilder().disableHtmlEscaping().setPrettyPrinting().registerTypeHierarchyAdapter(Path::class.java, PathJsonConverter()).create() class PathJsonConverter : JsonDeserializer, JsonSerializer { @@ -108,7 +110,9 @@ fun ProjectLayout.maybeInitSubmodules(offline: Boolean, logger: Logger) { fun ProjectLayout.initSubmodules() { 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 @@ -202,6 +206,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 { return when (this) { is Path -> layout.file(providers.provider { toFile() }) diff --git a/paperweight-lib/src/main/resources/post-rewrite.sh b/paperweight-lib/src/main/resources/post-rewrite.sh new file mode 100644 index 000000000..8918da877 --- /dev/null +++ b/paperweight-lib/src/main/resources/post-rewrite.sh @@ -0,0 +1,11 @@ +#!/bin/sh +input=$(cat) # SP [SP ] LF +fileCommit=$(git rev-list -n 1 file) # current commit tagged as "file" +oldObject=$(echo $input | cut -d' ' -f1) # +newObject=$(echo $input | cut -d' ' -f2) # + +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 diff --git a/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/tasks/PatcherApplyGitPatches.kt b/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/tasks/PatcherApplyGitPatches.kt index c69b8033f..1aa08bcc5 100644 --- a/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/tasks/PatcherApplyGitPatches.kt +++ b/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/tasks/PatcherApplyGitPatches.kt @@ -127,7 +127,7 @@ abstract class PatcherApplyGitPatches : ControllableOutputTask() { upstreamGit("checkout", "-b", upstreamBranch.get()).executeSilently(silenceErr = true) upstreamGit.disableAutoGpgSigningInRepo() upstreamGit("add", ".").executeSilently(silenceErr = true) - upstreamGit("commit", "-m", "Initial Source", "--author=Initial ").executeSilently(silenceErr = true) + upstreamGit("commit", "-m", "Initial Source", "--author=Initial ").executeSilently(silenceErr = true) } } @@ -157,7 +157,7 @@ abstract class PatcherApplyGitPatches : ControllableOutputTask() { } git(*Git.add(ignoreGitIgnore, ".")).executeSilently() - git("commit", "--allow-empty", "-m", "Initial", "--author=Initial Source ").executeSilently() + git("commit", "--allow-empty", "-m", "Initial", "--author=Initial Source ").executeSilently() git("tag", "-d", "base").runSilently(silenceErr = true) git("tag", "base").executeSilently() diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt index a0f393c0e..b2cca41cc 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt @@ -67,7 +67,9 @@ abstract class PaperweightUser : Plugin { 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("cleanAllPaperweightUserdevCaches") { group = "paperweight" diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v2/SetupHandlerImplV2.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v2/SetupHandlerImplV2.kt index ef7727e4e..ade6bbdda 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v2/SetupHandlerImplV2.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v2/SetupHandlerImplV2.kt @@ -70,12 +70,12 @@ class SetupHandlerImplV2( override val hashFile: Path = cache.resolve(paperSetupOutput("minecraftLibraries", "hashes")) override fun run(context: SetupHandler.Context) { - downloadMinecraftLibraries( + downloadLibraries( download = parameters.downloadService, workerExecutor = context.workerExecutor, targetDir = minecraftLibraryJars, repositories = listOf(MC_LIBRARY_URL, MAVEN_CENTRAL_URL), - mcLibraries = bundle.config.buildData.vanillaServerLibraries, + libraries = bundle.config.buildData.vanillaServerLibraries, sources = false ).await() } From 673ce7bf37b783bf1362225f300b4e42b127f5d0 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Sun, 27 Oct 2024 07:57:02 +0100 Subject: [PATCH 02/38] tests --- .../io/papermc/paperweight/FunctionalTest.kt | 238 ++++++++++++++++++ .../kotlin/io/papermc/paperweight/util.kt | 51 ++++ .../src/test/resources/fake_mache/mache.json | 114 +++++++++ .../fake_mache/patches/Test.java.patch | 9 + .../bundle/META-INF/libraries.list | 1 + .../fake_mojang/bundle/META-INF/versions.list | 1 + .../resources/fake_mojang/bundle/version.json | 3 + .../test/resources/fake_mojang/mappings.txt | 19 ++ .../resources/fake_mojang/server/Test.java | 17 ++ .../resources/fake_mojang/server/test.json | 3 + .../test/resources/fake_mojang/version.json | 12 + .../fake_mojang/version_manifest.json | 14 ++ .../resources/functional_test/.editorconfig | 2 + .../test/resources/functional_test/.gitignore | 4 + .../functional_test/build-data/expected.at | 5 + .../functional_test/build-data/fake.at | 4 + .../functional_test/build-data/paper.at | 3 + .../resources/functional_test/build.gradle | 52 ++++ .../fake-patches/expected/0001-Feature.patch | 19 ++ .../fake-patches/expected/Test.java.patch | 15 ++ .../fake-patches/features/0001-Feature.patch | 19 ++ .../fake-patches/resources/test.json.patch | 7 + .../fake-patches/sources/Test.java.patch | 11 + .../0002-Remove-rotten-apples.patch | 28 +++ .../functional_test/lib-patches/Main.java | 27 ++ .../lib-patches/dev-imports.txt | 1 + .../asciiart/widget/PictureWidget.java.patch | 30 +++ .../resources/functional_test/settings.gradle | 18 ++ .../functional_test/test-api/build.gradle | 3 + .../functional_test/test-server/build.gradle | 8 + .../patches/features/0001-something.patch | 18 ++ .../patches/resources/version.json.patch | 11 + .../net/minecraft/CrashReport.java.patch | 15 ++ .../tasks/ApplyAccessTransformTest.kt | 83 ++++++ .../io/papermc/paperweight/tasks/TaskTest.kt | 193 ++++++++++++++ .../tasks/softspoon/ApplyFilePatchesTest.kt | 62 +++++ .../tasks/softspoon/ApplySourceATTest.kt | 85 +++++++ .../tasks/softspoon/RebuildFilePatchesTest.kt | 72 ++++++ .../io/papermc/paperweight/util/ATTest.kt | 47 ++++ .../apply_access_transform/input/Test.java | 13 + .../apply_access_transform/input/ats.at | 5 + .../output/output.javap | 21 ++ .../apply_patches/input/base/Test.java | 13 + .../input/patches/Test.java.patch | 10 + .../apply_patches/output/source/Test.java | 13 + .../resources/apply_source_at/input/Test.java | 13 + .../apply_source_at/input/Unrelated.java | 3 + .../resources/apply_source_at/input/ats.at | 5 + .../apply_source_at/output/Test.java | 13 + .../apply_source_at/output/Unrelated.java | 3 + .../resources/rebuild_patches/input/ats.at | 3 + .../rebuild_patches/input/base/Test.java | 13 + .../rebuild_patches/input/source/Test.java | 13 + .../resources/rebuild_patches/output/ats.at | 5 + .../rebuild_patches/output/base/Test.java | 13 + .../output/patches/Test.java.patch | 10 + .../rebuild_patches/output/source/Test.java | 13 + 57 files changed, 1506 insertions(+) create mode 100644 paperweight-core/src/test/kotlin/io/papermc/paperweight/FunctionalTest.kt create mode 100644 paperweight-core/src/test/kotlin/io/papermc/paperweight/util.kt create mode 100644 paperweight-core/src/test/resources/fake_mache/mache.json create mode 100644 paperweight-core/src/test/resources/fake_mache/patches/Test.java.patch create mode 100644 paperweight-core/src/test/resources/fake_mojang/bundle/META-INF/libraries.list create mode 100644 paperweight-core/src/test/resources/fake_mojang/bundle/META-INF/versions.list create mode 100644 paperweight-core/src/test/resources/fake_mojang/bundle/version.json create mode 100644 paperweight-core/src/test/resources/fake_mojang/mappings.txt create mode 100644 paperweight-core/src/test/resources/fake_mojang/server/Test.java create mode 100644 paperweight-core/src/test/resources/fake_mojang/server/test.json create mode 100644 paperweight-core/src/test/resources/fake_mojang/version.json create mode 100644 paperweight-core/src/test/resources/fake_mojang/version_manifest.json create mode 100644 paperweight-core/src/test/resources/functional_test/.editorconfig create mode 100644 paperweight-core/src/test/resources/functional_test/.gitignore create mode 100644 paperweight-core/src/test/resources/functional_test/build-data/expected.at create mode 100644 paperweight-core/src/test/resources/functional_test/build-data/fake.at create mode 100644 paperweight-core/src/test/resources/functional_test/build-data/paper.at create mode 100644 paperweight-core/src/test/resources/functional_test/build.gradle create mode 100644 paperweight-core/src/test/resources/functional_test/fake-patches/expected/0001-Feature.patch create mode 100644 paperweight-core/src/test/resources/functional_test/fake-patches/expected/Test.java.patch create mode 100644 paperweight-core/src/test/resources/functional_test/fake-patches/features/0001-Feature.patch create mode 100644 paperweight-core/src/test/resources/functional_test/fake-patches/resources/test.json.patch create mode 100644 paperweight-core/src/test/resources/functional_test/fake-patches/sources/Test.java.patch create mode 100644 paperweight-core/src/test/resources/functional_test/lib-patches/0002-Remove-rotten-apples.patch create mode 100644 paperweight-core/src/test/resources/functional_test/lib-patches/Main.java create mode 100644 paperweight-core/src/test/resources/functional_test/lib-patches/dev-imports.txt create mode 100644 paperweight-core/src/test/resources/functional_test/lib-patches/org/alcibiade/asciiart/widget/PictureWidget.java.patch create mode 100644 paperweight-core/src/test/resources/functional_test/settings.gradle create mode 100644 paperweight-core/src/test/resources/functional_test/test-api/build.gradle create mode 100644 paperweight-core/src/test/resources/functional_test/test-server/build.gradle create mode 100644 paperweight-core/src/test/resources/functional_test/test-server/patches/features/0001-something.patch create mode 100644 paperweight-core/src/test/resources/functional_test/test-server/patches/resources/version.json.patch create mode 100644 paperweight-core/src/test/resources/functional_test/test-server/patches/sources/net/minecraft/CrashReport.java.patch create mode 100644 paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/ApplyAccessTransformTest.kt create mode 100644 paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/TaskTest.kt create mode 100644 paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatchesTest.kt create mode 100644 paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceATTest.kt create mode 100644 paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatchesTest.kt create mode 100644 paperweight-lib/src/test/kotlin/io/papermc/paperweight/util/ATTest.kt create mode 100644 paperweight-lib/src/test/resources/apply_access_transform/input/Test.java create mode 100644 paperweight-lib/src/test/resources/apply_access_transform/input/ats.at create mode 100644 paperweight-lib/src/test/resources/apply_access_transform/output/output.javap create mode 100644 paperweight-lib/src/test/resources/apply_patches/input/base/Test.java create mode 100644 paperweight-lib/src/test/resources/apply_patches/input/patches/Test.java.patch create mode 100644 paperweight-lib/src/test/resources/apply_patches/output/source/Test.java create mode 100644 paperweight-lib/src/test/resources/apply_source_at/input/Test.java create mode 100644 paperweight-lib/src/test/resources/apply_source_at/input/Unrelated.java create mode 100644 paperweight-lib/src/test/resources/apply_source_at/input/ats.at create mode 100644 paperweight-lib/src/test/resources/apply_source_at/output/Test.java create mode 100644 paperweight-lib/src/test/resources/apply_source_at/output/Unrelated.java create mode 100644 paperweight-lib/src/test/resources/rebuild_patches/input/ats.at create mode 100644 paperweight-lib/src/test/resources/rebuild_patches/input/base/Test.java create mode 100644 paperweight-lib/src/test/resources/rebuild_patches/input/source/Test.java create mode 100644 paperweight-lib/src/test/resources/rebuild_patches/output/ats.at create mode 100644 paperweight-lib/src/test/resources/rebuild_patches/output/base/Test.java create mode 100644 paperweight-lib/src/test/resources/rebuild_patches/output/patches/Test.java.patch create mode 100644 paperweight-lib/src/test/resources/rebuild_patches/output/source/Test.java diff --git a/paperweight-core/src/test/kotlin/io/papermc/paperweight/FunctionalTest.kt b/paperweight-core/src/test/kotlin/io/papermc/paperweight/FunctionalTest.kt new file mode 100644 index 000000000..7c554ea86 --- /dev/null +++ b/paperweight-core/src/test/kotlin/io/papermc/paperweight/FunctionalTest.kt @@ -0,0 +1,238 @@ +/* + * 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.io.path.readText +import kotlin.io.path.writeText +import kotlin.test.Test +import kotlin.test.assertContains +import kotlin.test.assertEquals +import kotlin.test.assertFalse +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 = true + + @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 + println("adding at to source") + modifyFile(tempDir.resolve("test-server/src/vanilla/java/Test.java")) { + it.replace( + "\"2\";", + "\"2\"; // Woo" + ).replace("public String getTest2() {", "private final String getTest2() {// Paper-AT: private+f getTest2()Ljava/lang/String;") + } + + Git(tempDir.resolve("test-server/src/vanilla/java")).let { git -> + git("add", ".").executeSilently() + git("commit", "--fixup", "file").executeSilently() + git("rebase", "--autosquash", "mache/main").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()) + + // feature patch + println("\nmodifying feature patch\n") + modifyFile(tempDir.resolve("test-server/src/vanilla/java/Test.java")) { + it.replace("wonderful feature", "amazing feature") + } + + Git(tempDir.resolve("test-server/src/vanilla/java")).let { git -> + git("add", ".").executeSilently() + git("commit", "--amend", "--no-edit").executeSilently() + } + + println("\nrebuilding feature patch\n") + val rebP3 = gradleRunner + .withArguments("rebuildPatches", "--stacktrace", "-Dfake=true") + .withDebug(debug) + .build() + assertEquals(rebP3.task(":rebuildPatches")?.outcome, TaskOutcome.SUCCESS) + assertEquals( + testResource.resolve("fake-patches/expected/0001-Feature.patch").readText(), + tempDir.resolve("fake-patches/features/0001-Feature.patch").readText() + ) + + // lib patches + println("\n lib patches\n") + testResource.resolve("lib-patches/Main.java").copyTo(tempDir.resolve("test-server/src/main/java/Main.java").createParentDirectories()) + testResource.resolve("lib-patches/dev-imports.txt").copyTo(tempDir.resolve("build-data/dev-imports.txt")) + testResource.resolve("lib-patches/0002-Remove-rotten-apples.patch") + .copyTo(tempDir.resolve("fake-patches/features/0002-Remove-rotten-apples.patch")) + testResource.resolve("lib-patches/org").copyToRecursively(tempDir.resolve("fake-patches/sources/org"), followLinks = false) + modifyFile(tempDir.resolve("test-server/build.gradle")) { + it.replace( + "implementation project(\":test-api\")", + """ + implementation project(":test-api") + implementation "org.alcibiade:asciiart-core:1.1.0" + """.trimIndent() + ) + } + + val appP2 = gradleRunner + .withArguments("applyPatches", "--stacktrace", "-Dfake=true") + .withDebug(debug) + .build() + + assertEquals(appP2.task(":applyPatches")?.outcome, TaskOutcome.SUCCESS) + assertContains(tempDir.resolve("test-server/src/vanilla/java/oshi/PlatformEnum.java").readText(), "Windows CE") + assertFalse(tempDir.resolve("test-server/src/vanilla/java/oshi/SystemInfo.java").readText().contains("MACOS")) + assertContains(tempDir.resolve("test-server/src/vanilla/java/org/alcibiade/asciiart/widget/PictureWidget.java").readText(), "Trollface") + } + + @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")) + } + + fun modifyFile(path: Path, action: (content: String) -> String) { + path.writeText(action.invoke(path.readText())) + } +} diff --git a/paperweight-core/src/test/kotlin/io/papermc/paperweight/util.kt b/paperweight-core/src/test/kotlin/io/papermc/paperweight/util.kt new file mode 100644 index 000000000..0e5aa0e82 --- /dev/null +++ b/paperweight-core/src/test/kotlin/io/papermc/paperweight/util.kt @@ -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()) +} diff --git a/paperweight-core/src/test/resources/fake_mache/mache.json b/paperweight-core/src/test/resources/fake_mache/mache.json new file mode 100644 index 000000000..9bc8092e3 --- /dev/null +++ b/paperweight-core/src/test/resources/fake_mache/mache.json @@ -0,0 +1,114 @@ +{ + "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.21", + "version": "2024.07.28", + "extension": "zip" + } + ], + "constants": [ + ], + "remapper": [ + { + "group": "net.neoforged", + "name": "AutoRenamingTool", + "version": "1.0.14", + "classifier": "all" + } + ], + "decompiler": [ + { + "group": "org.vineflower", + "name": "vineflower", + "version": "1.11.0-20240829.184116-48" + } + ] + }, + "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": [ + "--synthetic-not-set=true", + "--ternary-constant-simplification=true", + "--include-runtime=current", + "--decompile-complex-constant-dynamic=true", + "--indent-string= ", + "--decompile-inner=true", + "--remove-bridge=true", + "--decompile-generics=true", + "--ascii-strings=false", + "--remove-synthetic=true", + "--include-classpath=true", + "--inline-simple-lambdas=true", + "--ignore-invalid-bytecode=false", + "--bytecode-source-mapping=true", + "--dump-code-lines=true", + "--override-annotation=false", + "--skip-extra-files=true" + ], + "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" + } + ] + } +} diff --git a/paperweight-core/src/test/resources/fake_mache/patches/Test.java.patch b/paperweight-core/src/test/resources/fake_mache/patches/Test.java.patch new file mode 100644 index 000000000..ee7e4b273 --- /dev/null +++ b/paperweight-core/src/test/resources/fake_mache/patches/Test.java.patch @@ -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) { diff --git a/paperweight-core/src/test/resources/fake_mojang/bundle/META-INF/libraries.list b/paperweight-core/src/test/resources/fake_mojang/bundle/META-INF/libraries.list new file mode 100644 index 000000000..5e85ec5d7 --- /dev/null +++ b/paperweight-core/src/test/resources/fake_mojang/bundle/META-INF/libraries.list @@ -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 diff --git a/paperweight-core/src/test/resources/fake_mojang/bundle/META-INF/versions.list b/paperweight-core/src/test/resources/fake_mojang/bundle/META-INF/versions.list new file mode 100644 index 000000000..6c9206a7e --- /dev/null +++ b/paperweight-core/src/test/resources/fake_mojang/bundle/META-INF/versions.list @@ -0,0 +1 @@ +- fake fake/server.jar diff --git a/paperweight-core/src/test/resources/fake_mojang/bundle/version.json b/paperweight-core/src/test/resources/fake_mojang/bundle/version.json new file mode 100644 index 000000000..d31cbf41e --- /dev/null +++ b/paperweight-core/src/test/resources/fake_mojang/bundle/version.json @@ -0,0 +1,3 @@ +{ + "id": "fake" +} diff --git a/paperweight-core/src/test/resources/fake_mojang/mappings.txt b/paperweight-core/src/test/resources/fake_mojang/mappings.txt new file mode 100644 index 000000000..5d04b367e --- /dev/null +++ b/paperweight-core/src/test/resources/fake_mojang/mappings.txt @@ -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 () -> diff --git a/paperweight-core/src/test/resources/fake_mojang/server/Test.java b/paperweight-core/src/test/resources/fake_mojang/server/Test.java new file mode 100644 index 000000000..ab9fb25db --- /dev/null +++ b/paperweight-core/src/test/resources/fake_mojang/server/Test.java @@ -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"; + } +} diff --git a/paperweight-core/src/test/resources/fake_mojang/server/test.json b/paperweight-core/src/test/resources/fake_mojang/server/test.json new file mode 100644 index 000000000..d0ae716db --- /dev/null +++ b/paperweight-core/src/test/resources/fake_mojang/server/test.json @@ -0,0 +1,3 @@ +{ + "test": "test" +} diff --git a/paperweight-core/src/test/resources/fake_mojang/version.json b/paperweight-core/src/test/resources/fake_mojang/version.json new file mode 100644 index 000000000..b6f14b3b3 --- /dev/null +++ b/paperweight-core/src/test/resources/fake_mojang/version.json @@ -0,0 +1,12 @@ +{ + "downloads": { + "server": { + "sha1": "", + "url": "file://project/fake_mojang/bundle.jar" + }, + "server_mappings": { + "sha1": "", + "url": "file://project/fake_mojang/mappings.txt" + } + } +} diff --git a/paperweight-core/src/test/resources/fake_mojang/version_manifest.json b/paperweight-core/src/test/resources/fake_mojang/version_manifest.json new file mode 100644 index 000000000..7aa49bb62 --- /dev/null +++ b/paperweight-core/src/test/resources/fake_mojang/version_manifest.json @@ -0,0 +1,14 @@ +{ + "latest": { + "release": "fake", + "snapshot": "fake" + }, + "versions": [ + { + "id": "fake", + "type": "release", + "url": "file://project/fake_mojang/version.json", + "sha1": "" + } + ] +} diff --git a/paperweight-core/src/test/resources/functional_test/.editorconfig b/paperweight-core/src/test/resources/functional_test/.editorconfig new file mode 100644 index 000000000..42953013c --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/.editorconfig @@ -0,0 +1,2 @@ +[*.patch] +trim_trailing_whitespace=false diff --git a/paperweight-core/src/test/resources/functional_test/.gitignore b/paperweight-core/src/test/resources/functional_test/.gitignore new file mode 100644 index 000000000..8ae0eecb3 --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/.gitignore @@ -0,0 +1,4 @@ +.gradle +gradle +build +.idea diff --git a/paperweight-core/src/test/resources/functional_test/build-data/expected.at b/paperweight-core/src/test/resources/functional_test/build-data/expected.at new file mode 100644 index 000000000..ca799db8f --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/build-data/expected.at @@ -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; diff --git a/paperweight-core/src/test/resources/functional_test/build-data/fake.at b/paperweight-core/src/test/resources/functional_test/build-data/fake.at new file mode 100644 index 000000000..7627e75c1 --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/build-data/fake.at @@ -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; diff --git a/paperweight-core/src/test/resources/functional_test/build-data/paper.at b/paperweight-core/src/test/resources/functional_test/build-data/paper.at new file mode 100644 index 000000000..7883d5602 --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/build-data/paper.at @@ -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; diff --git a/paperweight-core/src/test/resources/functional_test/build.gradle b/paperweight-core/src/test/resources/functional_test/build.gradle new file mode 100644 index 000000000..e2819e10e --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/build.gradle @@ -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.21.1+build.1' + } +} + +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/features')) + + additionalAts.set(file('build-data/fake.at')) + + paperServerDir.set(file('test-server')) + } + } else { + minecraftVersion = '1.21.1' + + paper { + paperServerDir.set(file('test-server')) + } + } + + serverProject = project(':test-server') +} diff --git a/paperweight-core/src/test/resources/functional_test/fake-patches/expected/0001-Feature.patch b/paperweight-core/src/test/resources/functional_test/fake-patches/expected/0001-Feature.patch new file mode 100644 index 000000000..4dca565c5 --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/fake-patches/expected/0001-Feature.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MiniDigger | Martin +Date: Sun, 20 Oct 2024 09:24:36 +0200 +Subject: [PATCH] Feature + + +diff --git a/Test.java b/Test.java +index 372d9f877b361130deb341f1918d8f8c3ed0cf27..b24553b410c3b559c568dad6c811adc0a0bc6540 100644 +--- a/Test.java ++++ b/Test.java +@@ -13,4 +13,8 @@ public class Test { + private final String getTest2() { + return this.test + "2"; // Woo + } ++ ++ public String feature() { ++ return "amazing feature"; ++ } + } diff --git a/paperweight-core/src/test/resources/functional_test/fake-patches/expected/Test.java.patch b/paperweight-core/src/test/resources/functional_test/fake-patches/expected/Test.java.patch new file mode 100644 index 000000000..fb1457ba5 --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/fake-patches/expected/Test.java.patch @@ -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 + } + } diff --git a/paperweight-core/src/test/resources/functional_test/fake-patches/features/0001-Feature.patch b/paperweight-core/src/test/resources/functional_test/fake-patches/features/0001-Feature.patch new file mode 100644 index 000000000..9fe99c6a9 --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/fake-patches/features/0001-Feature.patch @@ -0,0 +1,19 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MiniDigger | Martin +Date: Sun, 20 Oct 2024 09:24:36 +0200 +Subject: [PATCH] Feature + + +diff --git a/Test.java b/Test.java +index 418548ec7dd11e57f0838d1dae048b99a2669ea3..95266c0cad0b100367ca840d286b7a004b93f4ef 100644 +--- a/Test.java ++++ b/Test.java +@@ -13,4 +13,8 @@ public class Test { + public String getTest2() { + return this.test + "2"; + } ++ ++ public String feature() { ++ return "wonderful feature"; ++ } + } diff --git a/paperweight-core/src/test/resources/functional_test/fake-patches/resources/test.json.patch b/paperweight-core/src/test/resources/functional_test/fake-patches/resources/test.json.patch new file mode 100644 index 000000000..a29ad924c --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/fake-patches/resources/test.json.patch @@ -0,0 +1,7 @@ +--- a/test.json ++++ b/test.json +@@ -1,3 +_,3 @@ + { +- "test": "test" ++ "test": "test2" + } diff --git a/paperweight-core/src/test/resources/functional_test/fake-patches/sources/Test.java.patch b/paperweight-core/src/test/resources/functional_test/fake-patches/sources/Test.java.patch new file mode 100644 index 000000000..f52ee82aa --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/fake-patches/sources/Test.java.patch @@ -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() { diff --git a/paperweight-core/src/test/resources/functional_test/lib-patches/0002-Remove-rotten-apples.patch b/paperweight-core/src/test/resources/functional_test/lib-patches/0002-Remove-rotten-apples.patch new file mode 100644 index 000000000..b2e9623a8 --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/lib-patches/0002-Remove-rotten-apples.patch @@ -0,0 +1,28 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MiniDigger | Martin +Date: Sun, 27 Oct 2024 09:06:58 +0100 +Subject: [PATCH] Remove rotten apples + + +diff --git a/oshi/SystemInfo.java b/oshi/SystemInfo.java +index 86a360a772f253d354533ba91f673d734bc51dbd..6b17e8669a9364f3e5bfd7651f3764532300d6c8 100644 +--- a/oshi/SystemInfo.java ++++ b/oshi/SystemInfo.java +@@ -83,8 +83,6 @@ public class SystemInfo { + case LINUX: + case ANDROID: + return new LinuxOperatingSystem(); +- case MACOS: +- return new MacOperatingSystem(); + case SOLARIS: + return new SolarisOperatingSystem(); + case FREEBSD: +@@ -114,8 +112,6 @@ public class SystemInfo { + case LINUX: + case ANDROID: + return new LinuxHardwareAbstractionLayer(); +- case MACOS: +- return new MacHardwareAbstractionLayer(); + case SOLARIS: + return new SolarisHardwareAbstractionLayer(); + case FREEBSD: diff --git a/paperweight-core/src/test/resources/functional_test/lib-patches/Main.java b/paperweight-core/src/test/resources/functional_test/lib-patches/Main.java new file mode 100644 index 000000000..e5400a833 --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/lib-patches/Main.java @@ -0,0 +1,27 @@ +import org.alcibiade.asciiart.coord.TextBoxSize; +import org.alcibiade.asciiart.image.rasterize.ShapeRasterizer; +import org.alcibiade.asciiart.raster.ExtensibleCharacterRaster; +import org.alcibiade.asciiart.raster.Raster; +import org.alcibiade.asciiart.raster.RasterContext; +import org.alcibiade.asciiart.widget.PictureWidget; +import org.alcibiade.asciiart.widget.TextWidget; + +import javax.imageio.ImageIO; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +public class Main { + + public static void main(String[] args) throws IOException, URISyntaxException { + BufferedImage circleImage = ImageIO.read(new URI("https://raw.githubusercontent.com/PaperMC/docs/refs/heads/main/static/img/paper.png").toURL()); + + TextWidget widget = new PictureWidget(new TextBoxSize(100, 30), + circleImage, new ShapeRasterizer()); + Raster raster = new ExtensibleCharacterRaster(); + + widget.render(new RasterContext(raster)); + System.out.println(raster); + } +} diff --git a/paperweight-core/src/test/resources/functional_test/lib-patches/dev-imports.txt b/paperweight-core/src/test/resources/functional_test/lib-patches/dev-imports.txt new file mode 100644 index 000000000..ebe8c2f26 --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/lib-patches/dev-imports.txt @@ -0,0 +1 @@ +oshi-core oshi.PlatformEnum diff --git a/paperweight-core/src/test/resources/functional_test/lib-patches/org/alcibiade/asciiart/widget/PictureWidget.java.patch b/paperweight-core/src/test/resources/functional_test/lib-patches/org/alcibiade/asciiart/widget/PictureWidget.java.patch new file mode 100644 index 000000000..d9bece558 --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/lib-patches/org/alcibiade/asciiart/widget/PictureWidget.java.patch @@ -0,0 +1,30 @@ +--- a/org/alcibiade/asciiart/widget/PictureWidget.java ++++ b/org/alcibiade/asciiart/widget/PictureWidget.java +@@ -1,10 +_,13 @@ + package org.alcibiade.asciiart.widget; + +-import java.awt.image.BufferedImage; + import org.alcibiade.asciiart.coord.TextBoxSize; + import org.alcibiade.asciiart.image.rasterize.Rasterizer; + import org.alcibiade.asciiart.raster.RasterContext; + ++import javax.imageio.ImageIO; ++import java.awt.image.BufferedImage; ++import java.net.URI; ++ + public class PictureWidget extends TextWidget { + + private TextBoxSize size; +@@ -13,7 +_,11 @@ + + public PictureWidget(TextBoxSize size, BufferedImage image, Rasterizer rasterizer) { + this.size = size; +- this.image = image; ++ try { ++ this.image = ImageIO.read(new URI("https://upload.wikimedia.org/wikipedia/en/7/73/Trollface.png").toURL()); ++ } catch (Exception e) { ++ this.image = image; ++ } + this.rasterizer = rasterizer; + } + diff --git a/paperweight-core/src/test/resources/functional_test/settings.gradle b/paperweight-core/src/test/resources/functional_test/settings.gradle new file mode 100644 index 000000000..4ce338cd1 --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/settings.gradle @@ -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' diff --git a/paperweight-core/src/test/resources/functional_test/test-api/build.gradle b/paperweight-core/src/test/resources/functional_test/test-api/build.gradle new file mode 100644 index 000000000..0e306a7b6 --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/test-api/build.gradle @@ -0,0 +1,3 @@ +plugins { + id "java-library" +} diff --git a/paperweight-core/src/test/resources/functional_test/test-server/build.gradle b/paperweight-core/src/test/resources/functional_test/test-server/build.gradle new file mode 100644 index 000000000..cd2984f12 --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/test-server/build.gradle @@ -0,0 +1,8 @@ +plugins { + id "java" + id "com.github.johnrengelman.shadow" +} + +dependencies { + implementation project(":test-api") +} diff --git a/paperweight-core/src/test/resources/functional_test/test-server/patches/features/0001-something.patch b/paperweight-core/src/test/resources/functional_test/test-server/patches/features/0001-something.patch new file mode 100644 index 000000000..75f088852 --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/test-server/patches/features/0001-something.patch @@ -0,0 +1,18 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: MiniDigger | Martin +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\""); + } diff --git a/paperweight-core/src/test/resources/functional_test/test-server/patches/resources/version.json.patch b/paperweight-core/src/test/resources/functional_test/test-server/patches/resources/version.json.patch new file mode 100644 index 000000000..978105f3b --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/test-server/patches/resources/version.json.patch @@ -0,0 +1,11 @@ +--- a/version.json ++++ b/version.json +@@ -1,6 +_,6 @@ + { +- "id": "1.21.1", +- "name": "1.21.1", ++ "id": "1.21.1-paper", ++ "name": "1.21.1 - Paper", + "world_version": 3955, + "series_id": "main", + "protocol_version": 767, diff --git a/paperweight-core/src/test/resources/functional_test/test-server/patches/sources/net/minecraft/CrashReport.java.patch b/paperweight-core/src/test/resources/functional_test/test-server/patches/sources/net/minecraft/CrashReport.java.patch new file mode 100644 index 000000000..1341d625e --- /dev/null +++ b/paperweight-core/src/test/resources/functional_test/test-server/patches/sources/net/minecraft/CrashReport.java.patch @@ -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() { diff --git a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/ApplyAccessTransformTest.kt b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/ApplyAccessTransformTest.kt new file mode 100644 index 000000000..b534103fe --- /dev/null +++ b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/ApplyAccessTransformTest.kt @@ -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().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") + } +} diff --git a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/TaskTest.kt b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/TaskTest.kt new file mode 100644 index 000000000..c483b68d0 --- /dev/null +++ b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/TaskTest.kt @@ -0,0 +1,193 @@ +/* + * 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 setupGitHook(repo: File) { + val hook = repo.toPath().resolve(".git/hooks/post-rewrite") + hook.parent.createDirectories() + hook.writeText(javaClass.getResource("/post-rewrite.sh")!!.readText()) + hook.toFile().setExecutable(true) + } + + 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") + } +} diff --git a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatchesTest.kt b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatchesTest.kt new file mode 100644 index 000000000..fa0acf011 --- /dev/null +++ b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatchesTest.kt @@ -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") + } +} diff --git a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceATTest.kt b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceATTest.kt new file mode 100644 index 000000000..bbb757d92 --- /dev/null +++ b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceATTest.kt @@ -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().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) + } +} diff --git a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatchesTest.kt b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatchesTest.kt new file mode 100644 index 000000000..60cbe80e5 --- /dev/null +++ b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatchesTest.kt @@ -0,0 +1,72 @@ +/* + * 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.CleanupMode +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(cleanup = CleanupMode.ON_SUCCESS) tempDir: Path) { + println("running in $tempDir") + 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") + setupGitRepo(tempDir.toFile(), "main", "dum") + setupGitHook(source) + 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") + } +} diff --git a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/util/ATTest.kt b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/util/ATTest.kt new file mode 100644 index 000000000..125f370f3 --- /dev/null +++ b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/util/ATTest.kt @@ -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")) + } +} diff --git a/paperweight-lib/src/test/resources/apply_access_transform/input/Test.java b/paperweight-lib/src/test/resources/apply_access_transform/input/Test.java new file mode 100644 index 000000000..b8cb9b8ab --- /dev/null +++ b/paperweight-lib/src/test/resources/apply_access_transform/input/Test.java @@ -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; + } +} diff --git a/paperweight-lib/src/test/resources/apply_access_transform/input/ats.at b/paperweight-lib/src/test/resources/apply_access_transform/input/ats.at new file mode 100644 index 000000000..693b10bf2 --- /dev/null +++ b/paperweight-lib/src/test/resources/apply_access_transform/input/ats.at @@ -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; diff --git a/paperweight-lib/src/test/resources/apply_access_transform/output/output.javap b/paperweight-lib/src/test/resources/apply_access_transform/output/output.javap new file mode 100644 index 000000000..77a6ccfa6 --- /dev/null +++ b/paperweight-lib/src/test/resources/apply_access_transform/output/output.javap @@ -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."":()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 +} diff --git a/paperweight-lib/src/test/resources/apply_patches/input/base/Test.java b/paperweight-lib/src/test/resources/apply_patches/input/base/Test.java new file mode 100644 index 000000000..b8cb9b8ab --- /dev/null +++ b/paperweight-lib/src/test/resources/apply_patches/input/base/Test.java @@ -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; + } +} diff --git a/paperweight-lib/src/test/resources/apply_patches/input/patches/Test.java.patch b/paperweight-lib/src/test/resources/apply_patches/input/patches/Test.java.patch new file mode 100644 index 000000000..58d2f2fdb --- /dev/null +++ b/paperweight-lib/src/test/resources/apply_patches/input/patches/Test.java.patch @@ -0,0 +1,10 @@ +--- a/Test.java ++++ b/Test.java +@@ -8,6 +_,6 @@ + } + + public String getTest() { +- return test; ++ return test + "Test"; // Test + } + } diff --git a/paperweight-lib/src/test/resources/apply_patches/output/source/Test.java b/paperweight-lib/src/test/resources/apply_patches/output/source/Test.java new file mode 100644 index 000000000..bb72c175b --- /dev/null +++ b/paperweight-lib/src/test/resources/apply_patches/output/source/Test.java @@ -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 + } +} diff --git a/paperweight-lib/src/test/resources/apply_source_at/input/Test.java b/paperweight-lib/src/test/resources/apply_source_at/input/Test.java new file mode 100644 index 000000000..b8cb9b8ab --- /dev/null +++ b/paperweight-lib/src/test/resources/apply_source_at/input/Test.java @@ -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; + } +} diff --git a/paperweight-lib/src/test/resources/apply_source_at/input/Unrelated.java b/paperweight-lib/src/test/resources/apply_source_at/input/Unrelated.java new file mode 100644 index 000000000..c821a33ff --- /dev/null +++ b/paperweight-lib/src/test/resources/apply_source_at/input/Unrelated.java @@ -0,0 +1,3 @@ +class Unrealted { + +} diff --git a/paperweight-lib/src/test/resources/apply_source_at/input/ats.at b/paperweight-lib/src/test/resources/apply_source_at/input/ats.at new file mode 100644 index 000000000..693b10bf2 --- /dev/null +++ b/paperweight-lib/src/test/resources/apply_source_at/input/ats.at @@ -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; diff --git a/paperweight-lib/src/test/resources/apply_source_at/output/Test.java b/paperweight-lib/src/test/resources/apply_source_at/output/Test.java new file mode 100644 index 000000000..869744fb8 --- /dev/null +++ b/paperweight-lib/src/test/resources/apply_source_at/output/Test.java @@ -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; + } +} diff --git a/paperweight-lib/src/test/resources/apply_source_at/output/Unrelated.java b/paperweight-lib/src/test/resources/apply_source_at/output/Unrelated.java new file mode 100644 index 000000000..c821a33ff --- /dev/null +++ b/paperweight-lib/src/test/resources/apply_source_at/output/Unrelated.java @@ -0,0 +1,3 @@ +class Unrealted { + +} diff --git a/paperweight-lib/src/test/resources/rebuild_patches/input/ats.at b/paperweight-lib/src/test/resources/rebuild_patches/input/ats.at new file mode 100644 index 000000000..c46fe9b71 --- /dev/null +++ b/paperweight-lib/src/test/resources/rebuild_patches/input/ats.at @@ -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 diff --git a/paperweight-lib/src/test/resources/rebuild_patches/input/base/Test.java b/paperweight-lib/src/test/resources/rebuild_patches/input/base/Test.java new file mode 100644 index 000000000..b8cb9b8ab --- /dev/null +++ b/paperweight-lib/src/test/resources/rebuild_patches/input/base/Test.java @@ -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; + } +} diff --git a/paperweight-lib/src/test/resources/rebuild_patches/input/source/Test.java b/paperweight-lib/src/test/resources/rebuild_patches/input/source/Test.java new file mode 100644 index 000000000..1e61ad8fc --- /dev/null +++ b/paperweight-lib/src/test/resources/rebuild_patches/input/source/Test.java @@ -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 + } +} diff --git a/paperweight-lib/src/test/resources/rebuild_patches/output/ats.at b/paperweight-lib/src/test/resources/rebuild_patches/output/ats.at new file mode 100644 index 000000000..3b4280360 --- /dev/null +++ b/paperweight-lib/src/test/resources/rebuild_patches/output/ats.at @@ -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 diff --git a/paperweight-lib/src/test/resources/rebuild_patches/output/base/Test.java b/paperweight-lib/src/test/resources/rebuild_patches/output/base/Test.java new file mode 100644 index 000000000..fd852a162 --- /dev/null +++ b/paperweight-lib/src/test/resources/rebuild_patches/output/base/Test.java @@ -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; + } +} diff --git a/paperweight-lib/src/test/resources/rebuild_patches/output/patches/Test.java.patch b/paperweight-lib/src/test/resources/rebuild_patches/output/patches/Test.java.patch new file mode 100644 index 000000000..aaa46dd44 --- /dev/null +++ b/paperweight-lib/src/test/resources/rebuild_patches/output/patches/Test.java.patch @@ -0,0 +1,10 @@ +--- a/Test.java ++++ b/Test.java +@@ -8,6 +_,6 @@ + } + + private final String getTest() { +- return test; ++ return test + "Test"; // Test + } + } diff --git a/paperweight-lib/src/test/resources/rebuild_patches/output/source/Test.java b/paperweight-lib/src/test/resources/rebuild_patches/output/source/Test.java new file mode 100644 index 000000000..a2d35e435 --- /dev/null +++ b/paperweight-lib/src/test/resources/rebuild_patches/output/source/Test.java @@ -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 + } +} From 862063530c5b178bf299ff734cbb3a79642df590 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:20:38 -0700 Subject: [PATCH 03/38] Fixes - Test with 1.21.4 - Apply paperweight to -server, not root - Rework mc classpath to use mache variants - Don't try to resolve implementation --- .../paperweight/core/PaperweightCore.kt | 4 +- .../core/extension/PaperExtension.kt | 2 +- .../core/taskcontainers/AllTasks.kt | 13 +-- .../core/taskcontainers/SoftSpoonTasks.kt | 80 ++++++------------- .../io/papermc/paperweight/FunctionalTest.kt | 35 +++----- .../src/test/resources/fake_mache/mache.json | 2 +- .../test/resources/fake_mojang/version.json | 4 +- .../fake_mojang/version_manifest.json | 2 +- .../resources/functional_test/build.gradle | 57 ++----------- .../resources/functional_test/settings.gradle | 4 + .../functional_test/test-server/build.gradle | 47 ++++++++++- .../patches/resources/version.json.patch | 12 +-- .../paperweight/tasks/mache/RemapJar.kt | 5 -- .../papermc/paperweight/util/MacheOutput.kt | 16 ++++ .../kotlin/io/papermc/paperweight/util/at.kt | 2 +- .../io/papermc/paperweight/tasks/TaskTest.kt | 2 +- settings.gradle.kts | 2 +- 17 files changed, 134 insertions(+), 155 deletions(-) create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/MacheOutput.kt diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt index 98e3efd56..420c294b1 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt @@ -74,7 +74,9 @@ class PaperweightCore : Plugin { target.configurations.create(REMAPPER_CONFIG) target.configurations.create(DECOMPILER_CONFIG) target.configurations.create(PAPERCLIP_CONFIG) - target.configurations.create(MACHE_CONFIG) + target.configurations.create(MACHE_CONFIG) { + attributes.attribute(MacheOutput.ATTRIBUTE, target.objects.named(MacheOutput.ZIP)) + } if (target.providers.gradleProperty("paperweight.dev").orNull == "true") { target.tasks.register("diff") { diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperExtension.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperExtension.kt index d9184ab68..22ddeeba5 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperExtension.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperExtension.kt @@ -46,7 +46,7 @@ open class PaperExtension(objects: ObjectFactory, layout: ProjectLayout) { val featurePatchDir: DirectoryProperty = objects.dirFrom(paperServerDir, "patches/features") @Suppress("MemberVisibilityCanBePrivate") - val buildDataDir: DirectoryProperty = objects.dirWithDefault(layout, "build-data") + val buildDataDir: DirectoryProperty = objects.dirWithDefault(layout, "../build-data") val additionalSpigotClassMappings: RegularFileProperty = objects.fileProperty() val devImports: RegularFileProperty = objects.fileFrom(buildDataDir, "dev-imports.txt") val additionalAts: RegularFileProperty = objects.fileFrom(buildDataDir, "paper.at") diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt index f6ac77d1e..497742c62 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt @@ -31,6 +31,8 @@ import io.papermc.paperweight.util.constants.* import java.nio.file.Path import org.gradle.api.Project import org.gradle.api.Task +import org.gradle.api.artifacts.component.ModuleComponentIdentifier +import org.gradle.api.plugins.JavaPlugin import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskContainer import org.gradle.kotlin.dsl.* @@ -103,11 +105,12 @@ open class AllTasks( val downloadPaperLibrariesSources by tasks.registering { 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}" + project.configurations.named(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME).flatMap { configuration -> + configuration.incoming.artifacts.resolvedArtifacts + }.map { artifacts -> + artifacts.mapNotNull { + val id = it.id.componentIdentifier as? ModuleComponentIdentifier ?: return@mapNotNull null + "${id.group}:${id.module}:${id.version}" } } ) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt index 1aa6d5bea..ee8cf8323 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt @@ -36,7 +36,6 @@ 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 @@ -119,7 +118,10 @@ open class SoftSpoonTasks( ats.set(mergeCollectedAts.flatMap { it.outputFile }) minecraftClasspath.from(macheMinecraft) - libraries.from(allTasks.downloadPaperLibrariesSources.flatMap { it.outputDir }, allTasks.downloadMcLibrariesSources.flatMap { it.outputDir }) + 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)) @@ -142,7 +144,7 @@ open class SoftSpoonTasks( 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") }) + output.set(layout.projectDirectory.dir("src/vanilla/java")) patches.set(project.ext.paper.sourcePatchDir) rejects.set(project.ext.paper.rejectsDir) gitFilePatches.set(project.ext.gitFilePatches) @@ -153,7 +155,7 @@ open class SoftSpoonTasks( 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") }) + output.set(layout.projectDirectory.dir("src/vanilla/java")) patches.set(project.ext.paper.sourcePatchDir) rejects.set(project.ext.paper.rejectsDir) gitFilePatches.set(project.ext.gitFilePatches) @@ -164,7 +166,7 @@ open class SoftSpoonTasks( 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") }) + output.set(layout.projectDirectory.dir("src/vanilla/resources")) patches.set(project.ext.paper.resourcePatchDir) } @@ -179,7 +181,7 @@ open class SoftSpoonTasks( description = "Applies all feature patches" dependsOn(applyFilePatches) - repo.set(project.ext.serverProject.map { it.layout.projectDirectory.dir("src/vanilla/java") }) + repo.set(layout.projectDirectory.dir("src/vanilla/java")) patches.set(project.ext.paper.featurePatchDir) } @@ -198,7 +200,7 @@ open class SoftSpoonTasks( 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") }) + input.set(layout.projectDirectory.dir("src/vanilla/java")) patches.set(project.ext.paper.sourcePatchDir) gitFilePatches.set(project.ext.gitFilePatches) } @@ -208,7 +210,7 @@ open class SoftSpoonTasks( 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") }) + input.set(layout.projectDirectory.dir("src/vanilla/resources")) patches.set(project.ext.paper.resourcePatchDir) } @@ -223,7 +225,7 @@ open class SoftSpoonTasks( description = "Rebuilds all feature patches" dependsOn(rebuildFilePatches) - inputDir.set(project.ext.serverProject.map { it.layout.projectDirectory.dir("src/vanilla/java") }) + inputDir.set(layout.projectDirectory.dir("src/vanilla/java")) patchDir.set(project.ext.paper.featurePatchDir) baseRef.set("file") } @@ -238,14 +240,14 @@ open class SoftSpoonTasks( group = "softspoon" description = "Puts the currently tracked source changes into the file patches commit" - repo.set(project.ext.serverProject.map { it.layout.projectDirectory.dir("src/vanilla/java") }) + repo.set(layout.projectDirectory.dir("src/vanilla/java")) } val fixupResourcePatches by tasks.registering(FixupFilePatches::class) { group = "softspoon" description = "Puts the currently tracked resource changes into the file patches commit" - repo.set(project.ext.serverProject.map { it.layout.projectDirectory.dir("src/vanilla/resources") }) + repo.set(layout.projectDirectory.dir("src/vanilla/resources")) } val setupPaperScript by tasks.registering(SetupPaperScript::class) { @@ -282,27 +284,18 @@ open class SoftSpoonTasks( 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)) - } - } - } - } + extendsFrom(project.configurations.getByName(MACHE_CONFIG)) } macheMinecraftExtended { extendsFrom(macheMinecraft.get()) withDependencies { - project.dependencies { - add(create(project.files(project.layout.cache.resolve(FINAL_REMAPPED_CODEBOOK_JAR)))) - } + add( + project.dependencies.create( + project.files(macheRemapJar.flatMap { it.outputJar }) + ) + ) } } @@ -325,48 +318,25 @@ open class SoftSpoonTasks( } } - 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) + project.configurations.named(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME) { + extendsFrom(macheMinecraft.get()) } // repos - repositories { + project.repositories { mavenCentral() maven(PAPER_MAVEN_REPO_URL) maven(MC_LIBRARY_URL) } // add vanilla source set - the().sourceSets.named(SourceSet.MAIN_SOURCE_SET_NAME) { + project.the().sourceSets.named(SourceSet.MAIN_SOURCE_SET_NAME) { java { - srcDirs(projectDir.resolve("src/vanilla/java")) + srcDirs(project.projectDir.resolve("src/vanilla/java")) } resources { - srcDirs(projectDir.resolve("src/vanilla/resources")) + srcDirs(project.projectDir.resolve("src/vanilla/resources")) } } } diff --git a/paperweight-core/src/test/kotlin/io/papermc/paperweight/FunctionalTest.kt b/paperweight-core/src/test/kotlin/io/papermc/paperweight/FunctionalTest.kt index 7c554ea86..3f44a9e26 100644 --- a/paperweight-core/src/test/kotlin/io/papermc/paperweight/FunctionalTest.kt +++ b/paperweight-core/src/test/kotlin/io/papermc/paperweight/FunctionalTest.kt @@ -68,14 +68,6 @@ class FunctionalTest { 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 @@ -83,7 +75,7 @@ class FunctionalTest { .withDebug(debug) .build() - assertEquals(appP.task(":applyPatches")?.outcome, TaskOutcome.SUCCESS) + assertEquals(appP.task(":test-server:applyPatches")?.outcome, TaskOutcome.SUCCESS) // clean rebuild rebP -> changes nothing println("\nrunning rebuildPatches\n") @@ -92,7 +84,7 @@ class FunctionalTest { .withDebug(debug) .build() - assertEquals(rebP.task(":rebuildPatches")?.outcome, TaskOutcome.SUCCESS) + assertEquals(rebP.task(":test-server:rebuildPatches")?.outcome, TaskOutcome.SUCCESS) assertEquals( testResource.resolve("fake-patches/sources/Test.java.patch").readText(), tempDir.resolve("fake-patches/sources/Test.java.patch").readText() @@ -119,7 +111,7 @@ class FunctionalTest { .withDebug(debug) .build() - assertEquals(rebP2.task(":rebuildPatches")?.outcome, TaskOutcome.SUCCESS) + assertEquals(rebP2.task(":test-server:rebuildPatches")?.outcome, TaskOutcome.SUCCESS) assertEquals( testResource.resolve("fake-patches/expected/Test.java.patch").readText(), tempDir.resolve("fake-patches/sources/Test.java.patch").readText() @@ -142,7 +134,7 @@ class FunctionalTest { .withArguments("rebuildPatches", "--stacktrace", "-Dfake=true") .withDebug(debug) .build() - assertEquals(rebP3.task(":rebuildPatches")?.outcome, TaskOutcome.SUCCESS) + assertEquals(rebP3.task(":test-server:rebuildPatches")?.outcome, TaskOutcome.SUCCESS) assertEquals( testResource.resolve("fake-patches/expected/0001-Feature.patch").readText(), tempDir.resolve("fake-patches/features/0001-Feature.patch").readText() @@ -170,7 +162,7 @@ class FunctionalTest { .withDebug(debug) .build() - assertEquals(appP2.task(":applyPatches")?.outcome, TaskOutcome.SUCCESS) + assertEquals(appP2.task(":test-server:applyPatches")?.outcome, TaskOutcome.SUCCESS) assertContains(tempDir.resolve("test-server/src/vanilla/java/oshi/PlatformEnum.java").readText(), "Windows CE") assertFalse(tempDir.resolve("test-server/src/vanilla/java/oshi/SystemInfo.java").readText().contains("MACOS")) assertContains(tempDir.resolve("test-server/src/vanilla/java/org/alcibiade/asciiart/widget/PictureWidget.java").readText(), "Trollface") @@ -181,19 +173,12 @@ class FunctionalTest { 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") + .withArguments("applyPatches", ":test-server:dependencies", "--stacktrace", "-Dfake=false") .withDebug(debug) .build() - assertEquals(result.task(":applyPatches")?.outcome, TaskOutcome.SUCCESS) + assertEquals(result.task(":test-server:applyPatches")?.outcome, TaskOutcome.SUCCESS) } fun setupMache(macheName: String, target: Path) { @@ -224,11 +209,11 @@ class FunctionalTest { 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/") + val oshiFolder = target.resolve("bundle/META-INF/libraries/com/github/oshi/oshi-core/6.6.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()) + "oshi-core-6.6.5.jar" + ).writeBytes(URL("https://libraries.minecraft.net/com/github/oshi/oshi-core/6.6.5/oshi-core-6.6.5.jar").readBytes()) zip(target.resolve("bundle"), target.resolve("bundle.jar")) } diff --git a/paperweight-core/src/test/resources/fake_mache/mache.json b/paperweight-core/src/test/resources/fake_mache/mache.json index 9bc8092e3..5bf2d2a6d 100644 --- a/paperweight-core/src/test/resources/fake_mache/mache.json +++ b/paperweight-core/src/test/resources/fake_mache/mache.json @@ -32,7 +32,7 @@ { "group": "org.vineflower", "name": "vineflower", - "version": "1.11.0-20240829.184116-48" + "version": "1.11.0-20241204.173358-53" } ] }, diff --git a/paperweight-core/src/test/resources/fake_mojang/version.json b/paperweight-core/src/test/resources/fake_mojang/version.json index b6f14b3b3..dcc420504 100644 --- a/paperweight-core/src/test/resources/fake_mojang/version.json +++ b/paperweight-core/src/test/resources/fake_mojang/version.json @@ -2,11 +2,11 @@ "downloads": { "server": { "sha1": "", - "url": "file://project/fake_mojang/bundle.jar" + "url": "file://project/../fake_mojang/bundle.jar" }, "server_mappings": { "sha1": "", - "url": "file://project/fake_mojang/mappings.txt" + "url": "file://project/../fake_mojang/mappings.txt" } } } diff --git a/paperweight-core/src/test/resources/fake_mojang/version_manifest.json b/paperweight-core/src/test/resources/fake_mojang/version_manifest.json index 7aa49bb62..afe0cfcd6 100644 --- a/paperweight-core/src/test/resources/fake_mojang/version_manifest.json +++ b/paperweight-core/src/test/resources/fake_mojang/version_manifest.json @@ -7,7 +7,7 @@ { "id": "fake", "type": "release", - "url": "file://project/fake_mojang/version.json", + "url": "file://project/../fake_mojang/version.json", "sha1": "" } ] diff --git a/paperweight-core/src/test/resources/functional_test/build.gradle b/paperweight-core/src/test/resources/functional_test/build.gradle index e2819e10e..f460a6862 100644 --- a/paperweight-core/src/test/resources/functional_test/build.gradle +++ b/paperweight-core/src/test/resources/functional_test/build.gradle @@ -1,52 +1,11 @@ -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.21.1+build.1' - } -} - -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/features')) - - additionalAts.set(file('build-data/fake.at')) - - paperServerDir.set(file('test-server')) - } - } else { - minecraftVersion = '1.21.1' - - paper { - paperServerDir.set(file('test-server')) +subprojects { + plugins.apply('java') + java { + toolchain { + languageVersion.set(JavaLanguageVersion.of(21)) } } - - serverProject = project(':test-server') + tasks.withType(JavaCompile) { + options.release = 21 + } } diff --git a/paperweight-core/src/test/resources/functional_test/settings.gradle b/paperweight-core/src/test/resources/functional_test/settings.gradle index 4ce338cd1..40b7985e6 100644 --- a/paperweight-core/src/test/resources/functional_test/settings.gradle +++ b/paperweight-core/src/test/resources/functional_test/settings.gradle @@ -12,6 +12,10 @@ pluginManagement { } } +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0" +} + rootProject.name = 'functional_test' include 'test-api' diff --git a/paperweight-core/src/test/resources/functional_test/test-server/build.gradle b/paperweight-core/src/test/resources/functional_test/test-server/build.gradle index cd2984f12..9ea0f49b7 100644 --- a/paperweight-core/src/test/resources/functional_test/test-server/build.gradle +++ b/paperweight-core/src/test/resources/functional_test/test-server/build.gradle @@ -1,8 +1,53 @@ plugins { id "java" - id "com.github.johnrengelman.shadow" + id 'io.papermc.paperweight.core' } +repositories { + mavenLocal() + mavenCentral() +} + +def fake = Boolean.getBoolean("fake") + dependencies { implementation project(":test-api") + + if (fake) { + mache files('../mache.zip') // use fake mache for testing + + // TODO: fake mache does not have dependencies + // this could be resolved by creating a fake maven repo that holds proper module metadata + implementation 'com.github.oshi:oshi-core:6.6.5' + } else { + mache 'io.papermc:mache:1.21.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/features')) + + additionalAts.set(file('../build-data/fake.at')) + + paperServerDir.set(file('./')) + } + } else { + minecraftVersion = '1.21.4' + + paper { + paperServerDir.set(file('./')) + } + } + + serverProject = project(':test-server') } diff --git a/paperweight-core/src/test/resources/functional_test/test-server/patches/resources/version.json.patch b/paperweight-core/src/test/resources/functional_test/test-server/patches/resources/version.json.patch index 978105f3b..ad1f75bc4 100644 --- a/paperweight-core/src/test/resources/functional_test/test-server/patches/resources/version.json.patch +++ b/paperweight-core/src/test/resources/functional_test/test-server/patches/resources/version.json.patch @@ -2,10 +2,10 @@ +++ b/version.json @@ -1,6 +_,6 @@ { -- "id": "1.21.1", -- "name": "1.21.1", -+ "id": "1.21.1-paper", -+ "name": "1.21.1 - Paper", - "world_version": 3955, +- "id": "1.21.4", +- "name": "1.21.4", ++ "id": "1.21.4-paper", ++ "name": "1.21.4 - Paper", + "world_version": 4189, "series_id": "main", - "protocol_version": 767, + "protocol_version": 769, diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt index 48456e60c..0f74c518a 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt @@ -74,11 +74,6 @@ abstract class RemapJar : DefaultTask() { @TaskAction fun run() { - if (minecraftClasspath.files.isEmpty()) { - // TODO this shouldn't happen, ideally we somehow make the minecraft classpath available on the first run too - throw RuntimeException("Could not resolve minecraft dependencies, try again") - } - val out = outputJar.convertToPath().ensureClean() val logFile = out.resolveSibling("${out.name}.log") diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/MacheOutput.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/MacheOutput.kt new file mode 100644 index 000000000..94f2b639a --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/MacheOutput.kt @@ -0,0 +1,16 @@ +package io.papermc.paperweight.util + +import org.gradle.api.Named +import org.gradle.api.attributes.Attribute + +interface MacheOutput : Named { + companion object { + val ATTRIBUTE = Attribute.of( + "io.papermc.mache.output", + MacheOutput::class.java + ) + + const val ZIP = "zip" + const val SERVER_DEPENDENCIES = "serverDependencies" + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt index 1b19a872d..f89e6f336 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt @@ -68,7 +68,7 @@ fun atToString(at: AccessTransform): String { fun AccessTransformFormat.writeLF(path: Path, at: AccessTransformSet, header: String = "") { val stringWriter = StringWriter() val writer = BufferedWriter(stringWriter) - AccessTransformFormats.FML.write(writer, at) + write(writer, at) writer.close() // unify line endings val lines = stringWriter.toString().replace("\r\n", "\n").split("\n") diff --git a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/TaskTest.kt b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/TaskTest.kt index c483b68d0..e5a403808 100644 --- a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/TaskTest.kt +++ b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/TaskTest.kt @@ -106,7 +106,7 @@ open class TaskTest { val git = Git.init().setDirectory(directory).setInitialBranch(mainBranch).call() git.add().addFilepattern(".").call() - git.commit().setMessage("Test").call() + git.commit().setSign(false).setMessage("Test").call() if (tag != null) { git.tag().setName(tag).call() } diff --git a/settings.gradle.kts b/settings.gradle.kts index 30d593823..7331fbc3f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" + id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0" } rootProject.name = "paperweight" From 392668cd1725bf2df76efe05e123f2da06265411 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:26:56 -0700 Subject: [PATCH 04/38] run spotless --- .../papermc/paperweight/util/MacheOutput.kt | 22 +++++++++++++++++++ .../kotlin/io/papermc/paperweight/util/at.kt | 1 - 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/MacheOutput.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/MacheOutput.kt index 94f2b639a..b433ca887 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/MacheOutput.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/MacheOutput.kt @@ -1,3 +1,25 @@ +/* + * 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 org.gradle.api.Named diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt index f89e6f336..b5a0dad83 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt @@ -29,7 +29,6 @@ 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 From edacf053f8b3b76b9afc5a54af5e0544608f8b09 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Fri, 6 Dec 2024 13:43:04 -0700 Subject: [PATCH 05/38] Fix slf4j issue --- buildSrc/src/main/kotlin/config-publish.gradle.kts | 3 ++- gradle/libs.versions.toml | 1 - paperweight-lib/build.gradle.kts | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/buildSrc/src/main/kotlin/config-publish.gradle.kts b/buildSrc/src/main/kotlin/config-publish.gradle.kts index 71aff53e7..c88fc5e63 100644 --- a/buildSrc/src/main/kotlin/config-publish.gradle.kts +++ b/buildSrc/src/main/kotlin/config-publish.gradle.kts @@ -26,6 +26,7 @@ fun ShadowJar.configureStandard() { dependencies { exclude(dependency("org.jetbrains.kotlin:.*:.*")) + exclude(dependency("org.slf4j:.*:.*")) } exclude("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA", "OSGI-INF/**", "*.profile", "module-info.class", "ant_tasks/**") @@ -83,7 +84,7 @@ val shadowJar by tasks.existing(ShadowJar::class) { "org.objectweb.asm", "org.osgi", "org.tukaani.xz", - "org.slf4j", + //"org.slf4j", "codechicken.diffpatch", "codechicken.repack" ).forEach { pack -> diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c5ad7b8c0..6f0e1d218 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -29,7 +29,6 @@ hypo-hydrate = { module = "dev.denwav.hypo:hypo-hydrate", version.ref = "hypo" } hypo-asm-core = { module = "dev.denwav.hypo:hypo-asm", version.ref = "hypo" } hypo-asm-hydrate = { module = "dev.denwav.hypo:hypo-asm-hydrate", version.ref = "hypo" } hypo-mappings = { module = "dev.denwav.hypo:hypo-mappings", version.ref = "hypo" } -slf4j-jdk14 = "org.slf4j:slf4j-jdk14:1.7.32" lorenzTiny = "net.fabricmc:lorenz-tiny:3.0.0" jbsdiff = "io.sigpipe:jbsdiff:1.0" diff --git a/paperweight-lib/build.gradle.kts b/paperweight-lib/build.gradle.kts index 3fc65f709..4c01aff32 100644 --- a/paperweight-lib/build.gradle.kts +++ b/paperweight-lib/build.gradle.kts @@ -16,7 +16,6 @@ dependencies { implementation(libs.bundles.asm) implementation(libs.bundles.hypo) - implementation(libs.slf4j.jdk14) // slf4j impl for hypo implementation(libs.bundles.cadix) implementation(libs.lorenzTiny) From 9d336e168ae02885be80e8f56b9f7d0fbcbdef0e Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:31:38 -0700 Subject: [PATCH 06/38] Remove redundant repository injection We only need to add the mache repo and any repos declared in it's meta mache repo: needs propagation to userdev config any other repos should be declared in paper itself and also added to the dev bundle library repos --- .../core/taskcontainers/SoftSpoonTasks.kt | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt index ee8cf8323..d47a3634e 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt @@ -277,11 +277,6 @@ open class SoftSpoonTasks( } } } - - maven(MC_LIBRARY_URL) { - name = "Minecraft" - } - mavenCentral() } // setup mc deps @@ -323,13 +318,6 @@ open class SoftSpoonTasks( extendsFrom(macheMinecraft.get()) } - // repos - project.repositories { - mavenCentral() - maven(PAPER_MAVEN_REPO_URL) - maven(MC_LIBRARY_URL) - } - // add vanilla source set project.the().sourceSets.named(SourceSet.MAIN_SOURCE_SET_NAME) { java { From 2a3351741dc183616409cb0add5214c379e5e2c6 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:54:26 -0700 Subject: [PATCH 07/38] add paper repo to functional test project --- .../test/resources/functional_test/test-server/build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/paperweight-core/src/test/resources/functional_test/test-server/build.gradle b/paperweight-core/src/test/resources/functional_test/test-server/build.gradle index 9ea0f49b7..3ef965985 100644 --- a/paperweight-core/src/test/resources/functional_test/test-server/build.gradle +++ b/paperweight-core/src/test/resources/functional_test/test-server/build.gradle @@ -6,6 +6,9 @@ plugins { repositories { mavenLocal() mavenCentral() + maven { + url "https://repo.papermc.io/repository/maven-public/" + } } def fake = Boolean.getBoolean("fake") From 9a0c0f2291a2174b41878bab833d519a1a4c1c44 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Fri, 6 Dec 2024 15:01:46 -0700 Subject: [PATCH 08/38] align some file locations with conventions --- .../kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt | 2 +- .../main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt index 17015b205..7c6fa7f10 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt @@ -75,7 +75,7 @@ abstract class DecompileJar : DefaultTask() { fun run() { val out = outputJar.convertToPath().ensureClean() - val cfgFile = layout.buildDirectory.file(DECOMP_CFG).convertToPath().ensureClean() + val cfgFile = layout.cache.resolve(DECOMP_CFG).ensureClean() val cfgText = buildString { for (file in minecraftClasspath.files) { append("-e=") diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt index 0f74c518a..b48a98d87 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt @@ -88,7 +88,7 @@ abstract class RemapJar : DefaultTask() { remapperArgs.get().forEach { arg -> args( arg - .replace(Regex("\\{tempDir}")) { layout.buildDirectory.dir(".tmp_codebook").get().asFile.absolutePath } + .replace(Regex("\\{tempDir}")) { temporaryDir.absolutePath } .replace(Regex("\\{remapperFile}")) { remapperClasspath.singleFile.absolutePath } .replace(Regex("\\{mappingsFile}")) { serverMappings.get().asFile.absolutePath } .replace(Regex("\\{paramsFile}")) { paramMappings.singleFile.absolutePath } From b4750b2ea5321adf1a767f61e9e9170b8746a8fb Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sat, 7 Dec 2024 01:42:31 -0700 Subject: [PATCH 09/38] Start bringing back reobf mappings gen & packaging --- gradle/libs.versions.toml | 2 +- .../paperweight/core/PaperweightCore.kt | 22 +++++++ .../core/extension/SpigotExtension.kt | 5 ++ .../core/taskcontainers/AllTasks.kt | 4 +- .../core/taskcontainers/GeneralTasks.kt | 4 -- .../core/taskcontainers/SpigotTasks.kt | 34 +++++++--- .../core/taskcontainers/VanillaTasks.kt | 2 +- .../taskcontainers/BundlerJarTasks.kt | 3 +- .../io/papermc/paperweight/tasks/CloneRepo.kt | 52 +++++++++++++++ .../paperweight/tasks/GenerateMappings.kt | 31 +++++---- .../tasks/GenerateReobfMappings.kt | 5 +- .../paperweight/tasks/SpigotRemapJar.kt | 5 +- .../tasks/UnpackSpigotBuildData.kt | 64 +++++++++++++++++++ .../papermc/paperweight/util/project-util.kt | 28 ++------ 14 files changed, 203 insertions(+), 58 deletions(-) create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CloneRepo.kt create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/UnpackSpigotBuildData.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6f0e1d218..97c358d32 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,7 +1,7 @@ [versions] asm = "9.7.1" lorenz = "0.5.8" -hypo = "2.3.0" +hypo = "1.2.4" serialize = "1.5.1" feather = "1.1.0" diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt index 420c294b1..b4a9ccf8c 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt @@ -39,6 +39,7 @@ import org.gradle.api.Project import org.gradle.api.logging.Logging import org.gradle.api.tasks.Delete import org.gradle.api.tasks.TaskProvider +import org.gradle.api.tasks.bundling.AbstractArchiveTask import org.gradle.api.tasks.bundling.Zip import org.gradle.kotlin.dsl.* @@ -100,6 +101,27 @@ class PaperweightCore : Plugin { val softSpoonTasks = SoftSpoonTasks(target, tasks) + val jar = target.tasks.named("jar", AbstractArchiveTask::class) + tasks.generateReobfMappings { + inputJar.set(jar.flatMap { it.archiveFile }) + } + tasks.generateRelocatedReobfMappings { + inputJar.set(jar.flatMap { it.archiveFile }) + } + val (includeMappings, reobfJar) = target.createBuildTasks( + ext.spigot.packageVersion, + ext.paper.reobfPackagesToFix, + tasks.generateRelocatedReobfMappings + ) + bundlerJarTasks.configureBundlerTasks( + tasks.extractFromBundler.flatMap { it.versionJson }, + tasks.extractFromBundler.flatMap { it.serverLibrariesList }, + tasks.downloadServerJar.flatMap { it.outputJar }, + includeMappings.flatMap { it.outputJar }, + reobfJar, + ext.minecraftVersion + ) + target.createPatchRemapTask(tasks) target.tasks.register(PAPERWEIGHT_PREPARE_DOWNSTREAM) { diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/SpigotExtension.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/SpigotExtension.kt index 544bf8ebd..c0bcfd77f 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/SpigotExtension.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/SpigotExtension.kt @@ -25,9 +25,14 @@ package io.papermc.paperweight.core.extension import io.papermc.paperweight.util.* import org.gradle.api.file.DirectoryProperty import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.Property +import org.gradle.kotlin.dsl.* open class SpigotExtension(objects: ObjectFactory, workDir: DirectoryProperty) { + val buildDataRef: Property = objects.property() + val packageVersion: Property = objects.property() + @Suppress("MemberVisibilityCanBePrivate") val spigotDir: DirectoryProperty = objects.dirFrom(workDir, "Spigot") val spigotApiDir: DirectoryProperty = objects.dirFrom(spigotDir, "Spigot-API") diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt index 497742c62..2a826d6fa 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt @@ -181,7 +181,8 @@ open class AllTasks( inputMappings.set(patchMappings.flatMap { it.outputMappings }) notchToSpigotMappings.set(generateSpigotMappings.flatMap { it.notchToSpigotMappings }) sourceMappings.set(generateMappings.flatMap { it.outputMappings }) - spigotRecompiledClasses.set(remapSpigotSources.flatMap { it.spigotRecompiledClasses }) + // TODO: spigot uses javac now(?) so is this needed anymore? + // spigotRecompiledClasses.set(remapSpigotSources.flatMap { it.spigotRecompiledClasses }) reobfMappings.set(cache.resolve(REOBF_MOJANG_SPIGOT_MAPPINGS)) } @@ -199,5 +200,6 @@ open class AllTasks( val generateRelocatedReobfMappings by tasks.registering { inputMappings.set(patchReobfMappings.flatMap { it.outputMappings }) outputMappings.set(cache.resolve(RELOCATED_PATCHED_REOBF_MOJANG_SPIGOT_MAPPINGS)) + craftBukkitPackageVersion.set(extension.spigot.packageVersion) } } diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt index 217714170..c17b0222e 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt @@ -44,10 +44,6 @@ open class GeneralTasks( offlineMode.set(project.offlineMode()) } - val buildDataInfo: Provider = project.contents(extension.craftBukkit.buildDataInfo) { - gson.fromJson(it) - } - val filterVanillaJar by tasks.registering { inputJar.set(extractFromBundler.flatMap { it.serverJar }) includes.set(extension.vanillaJarIncludes) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt index 83b775513..9d90bd5bf 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt @@ -22,6 +22,7 @@ package io.papermc.paperweight.core.taskcontainers +import com.github.salomonbrys.kotson.fromJson import io.papermc.paperweight.DownloadService import io.papermc.paperweight.core.ext import io.papermc.paperweight.core.extension.PaperweightCoreExtension @@ -44,6 +45,19 @@ open class SpigotTasks( downloadService: Provider = project.download, ) : VanillaTasks(project) { + val cloneSpigotBuildData by tasks.registering { + url.set("https://hub.spigotmc.org/stash/scm/spigot/builddata.git") + ref.set(project.ext.spigot.buildDataRef) + } + + val unpackSpigotBuildData by tasks.registering { + buildDataZip.set(cloneSpigotBuildData.flatMap { it.outputZip }) + } + + val buildDataInfo: Provider = unpackSpigotBuildData + .flatMap { it.buildDataInfoFile } + .map { gson.fromJson(it.path) } + val addAdditionalSpigotMappings by tasks.registering { dependsOn(initSubmodules) classSrg.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.classMappings })) @@ -51,11 +65,11 @@ open class SpigotTasks( } val generateSpigotMappings by tasks.registering { - classMappings.set(addAdditionalSpigotMappings.flatMap { it.outputClassSrg }) + classMappings.set(unpackSpigotBuildData.flatMap { it.classMappings }) // 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")) + // sourceMappings.set(Path.of("D:\\IntellijProjects\\PaperClean\\.gradle\\caches\\paperweight\\mappings\\official-mojang+yarn.tiny")) + sourceMappings.set(generateMappings.flatMap { it.outputMappings }) outputMappings.set(cache.resolve(SPIGOT_MOJANG_YARN_MAPPINGS)) notchToSpigotMappings.set(cache.resolve(OBF_SPIGOT_MAPPINGS)) @@ -64,17 +78,17 @@ open class SpigotTasks( val spigotRemapJar by tasks.registering { inputJar.set(filterVanillaJar.flatMap { it.outputJar }) - classMappings.set(addAdditionalSpigotMappings.flatMap { it.outputClassSrg }) - accessTransformers.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.accessTransforms })) + classMappings.set(unpackSpigotBuildData.flatMap { it.classMappings }) + accessTransformers.set(unpackSpigotBuildData.flatMap { it.atFile }) memberMappings.set(generateSpigotMappings.flatMap { it.spigotMemberMappings }) mcVersion.set(extension.minecraftVersion) - workDirName.set(extension.craftBukkit.buildDataInfo.asFile.map { it.parentFile.parentFile.name }) + // workDirName.set(extension.craftBukkit.buildDataInfo.asFile.map { it.parentFile.parentFile.name }) - specialSourceJar.set(extension.craftBukkit.specialSourceJar) - specialSource2Jar.set(extension.craftBukkit.specialSource2Jar) + specialSourceJar.set(unpackSpigotBuildData.flatMap { it.specialSourceJar }) + specialSource2Jar.set(unpackSpigotBuildData.flatMap { it.specialSource2Jar }) classMapCommand.set(buildDataInfo.map { it.classMapCommand }) memberMapCommand.set(buildDataInfo.map { it.memberMapCommand }) @@ -109,7 +123,7 @@ open class SpigotTasks( val filterSpigotExcludes by tasks.registering { inputZip.set(spigotRemapJar.flatMap { it.outputJar }) - excludesFile.set(extension.craftBukkit.excludesFile) + excludesFile.set(unpackSpigotBuildData.flatMap { it.excludesFile }) } val spigotDecompileJar by tasks.registering { @@ -180,7 +194,7 @@ open class SpigotTasks( val remapSpigotAt by tasks.registering { inputJar.set(spigotRemapJar.flatMap { it.outputJar }) mapping.set(patchMappings.flatMap { it.outputMappings }) - spigotAt.set(extension.craftBukkit.atFile) + spigotAt.set(unpackSpigotBuildData.flatMap { it.atFile }) } @Suppress("DuplicatedCode") diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/VanillaTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/VanillaTasks.kt index 7cb51ed8f..bb195ec73 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/VanillaTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/VanillaTasks.kt @@ -42,7 +42,7 @@ open class VanillaTasks( libraries.from(extractFromBundler.map { it.serverLibraryJars.asFileTree }) vanillaMappings.set(downloadMappings.flatMap { it.outputFile }) - paramMappings.fileProvider(project.configurations.named(PARAM_MAPPINGS_CONFIG).map { it.singleFile }) + // paramMappings.fileProvider(project.configurations.named(PARAM_MAPPINGS_CONFIG).map { it.singleFile }) outputMappings.set(cache.resolve(MOJANG_YARN_MAPPINGS)) } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/BundlerJarTasks.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/BundlerJarTasks.kt index 2bfcbcaea..737c61a4f 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/BundlerJarTasks.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/BundlerJarTasks.kt @@ -29,6 +29,7 @@ import io.papermc.paperweight.util.constants.* import org.gradle.api.NamedDomainObjectContainer import org.gradle.api.Project import org.gradle.api.file.RegularFile +import org.gradle.api.plugins.JavaPlugin import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskProvider import org.gradle.kotlin.dsl.* @@ -121,7 +122,7 @@ class BundlerJarTasks( vanillaJar: Provider, serverJar: Provider, ) = this { - libraryArtifacts.set(project.configurations.named(SERVER_RUNTIME_CLASSPATH)) + libraryArtifacts.set(project.configurations.named(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)) serverLibrariesList.set(serverLibrariesListFile) vanillaBundlerJar.set(vanillaJar) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CloneRepo.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CloneRepo.kt new file mode 100644 index 000000000..f12e9e7ac --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CloneRepo.kt @@ -0,0 +1,52 @@ +package io.papermc.paperweight.tasks + +import io.papermc.paperweight.util.* +import java.nio.file.Path +import kotlin.io.path.* +import org.gradle.api.provider.Property +import org.gradle.api.tasks.CacheableTask +import org.gradle.api.tasks.Input + +@CacheableTask +abstract class CloneRepo : ZippedTask() { + @get:Input + abstract val url: Property + + @get:Input + abstract val ref: Property + + @get:Input + abstract val shallowClone: Property + + override fun init() { + super.init() + shallowClone.convention(true) + } + + override fun run(dir: Path) { + Git.checkForGit() + + val urlText = url.get().trim() + + if (dir.resolve(".git").notExists()) { + dir.deleteRecursive() + dir.createDirectories() + + Git(dir)("init", "--quiet").executeSilently() + } + + val git = Git(dir) + git("remote", "add", "origin", urlText).executeSilently(silenceErr = true) + git.fetch() + + git("checkout", "-f", "FETCH_HEAD").executeSilently(silenceErr = true) + } + + private fun Git.fetch() { + if (shallowClone.get()) { + this("fetch", "--depth", "1", "origin", ref.get()).executeSilently(silenceErr = true) + } else { + this("fetch", "origin", ref.get()).executeSilently(silenceErr = true) + } + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateMappings.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateMappings.kt index 8605f0be8..f436351b6 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateMappings.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateMappings.kt @@ -66,7 +66,7 @@ fun generateMappings( vanillaJarPath: Path, libraryPaths: List, vanillaMappingsPath: Path, - paramMappingsPath: Path, + paramMappingsPath: Path?, outputMappingsPath: Path, workerExecutor: WorkerExecutor, launcher: JavaLauncher, @@ -102,6 +102,7 @@ abstract class GenerateMappings : JavaLauncherTask() { abstract val vanillaMappings: RegularFileProperty @get:InputFile + @get:Optional @get:PathSensitive(PathSensitivity.NONE) abstract val paramMappings: RegularFileProperty @@ -126,7 +127,7 @@ abstract class GenerateMappings : JavaLauncherTask() { vanillaJar.path, libraries.files.map { it.toPath() }, vanillaMappings.path, - paramMappings.path, + paramMappings.pathOrNull, outputMappings.path, workerExecutor, launcher.get(), @@ -147,19 +148,23 @@ abstract class GenerateMappings : JavaLauncherTask() { override fun execute() { val vanillaMappings = MappingFormats.PROGUARD.createReader(parameters.vanillaMappings.path).use { it.read() }.reverse() - val paramMappings = parameters.paramMappings.path.openZip().use { fs -> - val path = fs.getPath("mappings", "mappings.tiny") - MappingFormats.TINY.read(path, "official", "named") + val paramMappings = parameters.paramMappings.orNull?.let { mappingsFile -> + mappingsFile.path.openZip().use { fs -> + val path = fs.getPath("mappings", "mappings.tiny") + MappingFormats.TINY.read(path, "official", "named") + } } - val merged = MappingSetMerger.create( - vanillaMappings, - paramMappings, - MergeConfig.builder() - .withFieldMergeStrategy(FieldMergeStrategy.STRICT) - .withMergeHandler(ParamsMergeHandler()) - .build() - ).merge() + val merged = paramMappings?.let { + MappingSetMerger.create( + vanillaMappings, + it, + MergeConfig.builder() + .withFieldMergeStrategy(FieldMergeStrategy.STRICT) + .withMergeHandler(ParamsMergeHandler()) + .build() + ).merge() + } ?: vanillaMappings val filledMerged = HypoContext.builder() .withProvider(AsmClassDataProvider.of(ClassProviderRoot.fromJar(parameters.vanillaJar.path))) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateReobfMappings.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateReobfMappings.kt index 916a49300..ad585f820 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateReobfMappings.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateReobfMappings.kt @@ -80,6 +80,7 @@ abstract class GenerateReobfMappings : JavaLauncherTask() { abstract val workerExecutor: WorkerExecutor @get:InputFile + @get:Optional @get:PathSensitive(PathSensitivity.NONE) abstract val spigotRecompiledClasses: RegularFileProperty @@ -101,7 +102,7 @@ abstract class GenerateReobfMappings : JavaLauncherTask() { notchToSpigotMappings.set(this@GenerateReobfMappings.notchToSpigotMappings) sourceMappings.set(this@GenerateReobfMappings.sourceMappings) inputJar.set(this@GenerateReobfMappings.inputJar) - spigotRecompiles.set(spigotRecompiledClasses.path) + spigotRecompiles.set(spigotRecompiledClasses.pathOrNull) reobfMappings.set(this@GenerateReobfMappings.reobfMappings) } @@ -207,7 +208,7 @@ abstract class GenerateReobfMappings : JavaLauncherTask() { val outputMappings = mergeSpigotWithMojangMemberMappings(obfToSpigot, obfToMojang, spigotToMojang) - val spigotRecompiles = parameters.spigotRecompiles.path.readLines().toSet() + val spigotRecompiles = setOf() // TODO parameters.spigotRecompiles.path.readLines().toSet() val cleanedOutputMappings = HypoContext.builder() .withConfig(HypoConfig.builder().setRequireFullClasspath(false).withParallelism(1).build()) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/SpigotRemapJar.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/SpigotRemapJar.kt index 376eb9dd3..7abe3c0fd 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/SpigotRemapJar.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/SpigotRemapJar.kt @@ -51,9 +51,6 @@ abstract class SpigotRemapJar : JavaLauncherTask() { @get:PathSensitive(PathSensitivity.NONE) abstract val accessTransformers: RegularFileProperty - @get:Input - abstract val workDirName: Property - @get:Classpath abstract val specialSourceJar: RegularFileProperty @@ -95,7 +92,7 @@ abstract class SpigotRemapJar : JavaLauncherTask() { val spigotMembersPath = memberMappings.path.absolutePathString() - val work = layout.projectDirectory.file(workDirName.get()) + val work = temporaryDir.toPath() val spigotEmptyMappings = layout.cache.resolve("spigot-empty-package-mappings.csrg") spigotEmptyMappings.writeText("") diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/UnpackSpigotBuildData.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/UnpackSpigotBuildData.kt new file mode 100644 index 000000000..ddbb1b35c --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/UnpackSpigotBuildData.kt @@ -0,0 +1,64 @@ +package io.papermc.paperweight.tasks + +import io.papermc.paperweight.util.* +import java.nio.file.Path +import kotlin.io.path.* +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.tasks.InputFile +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction + +abstract class UnpackSpigotBuildData : BaseTask() { + @get:InputFile + abstract val buildDataZip: RegularFileProperty + + @get:OutputFile + abstract val buildDataInfoFile: RegularFileProperty + + @get:OutputFile + abstract val excludesFile: RegularFileProperty + + @get:OutputFile + abstract val atFile: RegularFileProperty + + @get:OutputFile + abstract val classMappings: RegularFileProperty + + @get:OutputFile + abstract val specialSourceJar: RegularFileProperty + + @get:OutputFile + abstract val specialSource2Jar: RegularFileProperty + + override fun init() { + buildDataInfoFile.convention(defaultOutput("spigot-build-data-info", "json")) + excludesFile.convention(defaultOutput("spigot-excludes", "exclude")) + atFile.convention(defaultOutput("spigot-ats", "at")) + classMappings.convention(defaultOutput("spigot-class-mapping", "csrg")) + specialSourceJar.convention(defaultOutput("special-source", "jar")) + specialSource2Jar.convention(defaultOutput("special-source-2", "jar")) + } + + @TaskAction + fun run() { + buildDataZip.path.openZip().use { + val root = it.getPath("/") + root.resolve("info.json") + .copyTo(buildDataInfoFile.path.createParentDirectories(), overwrite = true) + val mappings = root.resolve("mappings") + bukkitFileFrom(mappings, "exclude") + .copyTo(excludesFile.path.createParentDirectories(), overwrite = true) + bukkitFileFrom(mappings, "at") + .copyTo(atFile.path.createParentDirectories(), overwrite = true) + bukkitFileFrom(mappings, "csrg") + .copyTo(classMappings.path.createParentDirectories(), overwrite = true) + root.resolve("bin/SpecialSource.jar") + .copyTo(specialSourceJar.path.createParentDirectories(), overwrite = true) + root.resolve("bin/SpecialSource-2.jar") + .copyTo(specialSource2Jar.path.createParentDirectories(), overwrite = true) + } + } + + private fun bukkitFileFrom(dir: Path, extension: String): Path = + dir.useDirectoryEntries { it.filter { f -> f.name.endsWith(extension) }.single() } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt index d25c16f5b..a3981a66a 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt @@ -36,6 +36,7 @@ import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.provider.Provider import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.TaskProvider +import org.gradle.api.tasks.bundling.AbstractArchiveTask import org.gradle.api.tasks.bundling.Jar import org.gradle.api.tasks.bundling.Zip import org.gradle.kotlin.dsl.* @@ -111,7 +112,7 @@ fun Project.setupServerProject( addMcDevSourcesRoot(mcDevSourceDir) - return createBuildTasks(parent, serverExt, serverJar, vanillaServer, packagesToFix, relocatedReobfMappings) + error("No longer implemented") } private fun Project.exportRuntimeClasspathTo(parent: Project) { @@ -142,28 +143,13 @@ private fun Project.exportRuntimeClasspathTo(parent: Project) { } } -private fun Project.createBuildTasks( - parent: Project, - serverExt: PaperweightServerExtension, - serverJar: TaskProvider, - vanillaServer: Configuration, +fun Project.createBuildTasks( + craftBukkitPackageVersion: Provider, packagesToFix: Provider?>, relocatedReobfMappings: TaskProvider ): ServerTasks { - serverJar { - destinationDirectory.set(layout.buildDirectory.dir("libs")) - archiveExtension.set("jar") - archiveClassifier.set("mojang-mapped") - from(zipTree(tasks.named("jar").flatMap { it.archiveFile }.map { it.asFile })) - from(vanillaServer.elements.map { it.map { f -> zipTree(f.asFile) } }) { - exclude("META-INF/MANIFEST.MF") - } - isReproducibleFileOrder = true - isPreserveFileTimestamps = false - } - val fixJarForReobf by tasks.registering { - inputJar.set(serverJar.flatMap { it.archiveFile }) + inputJar.set(tasks.named("jar", AbstractArchiveTask::class).flatMap { it.archiveFile }) packagesToProcess.set(packagesToFix) } @@ -179,7 +165,7 @@ private fun Project.createBuildTasks( } afterEvaluate { relocateConstants { - relocate("org.bukkit.craftbukkit", "org.bukkit.craftbukkit.${serverExt.craftBukkitPackageVersion.get()}") { + relocate("org.bukkit.craftbukkit", "org.bukkit.craftbukkit.${craftBukkitPackageVersion.get()}") { // This is not actually needed as there are no string constant references to Main // exclude("org.bukkit.craftbukkit.Main*") } @@ -197,7 +183,7 @@ private fun Project.createBuildTasks( fromNamespace.set(DEOBF_NAMESPACE) toNamespace.set(SPIGOT_NAMESPACE) - remapper.from(parent.configurations.named(REMAPPER_CONFIG)) + remapper.from(configurations.named(REMAPPER_CONFIG)) remapperArgs.set(TinyRemapper.minecraftRemapArgs) outputJar.set(layout.buildDirectory.map { it.dir("libs").file("${project.name}-${project.version}-reobf.jar") }) From 64589ec96bfa2d4d7318591545fbfb114a2f4968 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sat, 7 Dec 2024 02:14:52 -0700 Subject: [PATCH 10/38] Use spigot recompiles if present --- .../io/papermc/paperweight/tasks/GenerateReobfMappings.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateReobfMappings.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateReobfMappings.kt index ad585f820..899448a1b 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateReobfMappings.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateReobfMappings.kt @@ -208,7 +208,7 @@ abstract class GenerateReobfMappings : JavaLauncherTask() { val outputMappings = mergeSpigotWithMojangMemberMappings(obfToSpigot, obfToMojang, spigotToMojang) - val spigotRecompiles = setOf() // TODO parameters.spigotRecompiles.path.readLines().toSet() + val spigotRecompiles = parameters.spigotRecompiles.pathOrNull?.readLines()?.toSet() ?: emptySet() val cleanedOutputMappings = HypoContext.builder() .withConfig(HypoConfig.builder().setRequireFullClasspath(false).withParallelism(1).build()) From 80d00b043f52196335154d80ec866582be065a13 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Sat, 7 Dec 2024 12:17:21 +0100 Subject: [PATCH 11/38] cleanup relocations --- .../src/main/kotlin/config-publish.gradle.kts | 39 ++++++++++++------- .../tasks/MergeAccessTransforms.kt | 1 - .../paperweight/tasks/RemapAccessTransform.kt | 1 - .../papermc/paperweight/tasks/RemapSources.kt | 1 - .../paperweight/tasks/RemapSpigotAt.kt | 1 - .../tasks/softspoon/RebuildFilePatches.kt | 2 - .../kotlin/io/papermc/paperweight/util/at.kt | 1 + 7 files changed, 27 insertions(+), 19 deletions(-) diff --git a/buildSrc/src/main/kotlin/config-publish.gradle.kts b/buildSrc/src/main/kotlin/config-publish.gradle.kts index c88fc5e63..d3b244fd6 100644 --- a/buildSrc/src/main/kotlin/config-publish.gradle.kts +++ b/buildSrc/src/main/kotlin/config-publish.gradle.kts @@ -29,7 +29,7 @@ fun ShadowJar.configureStandard() { exclude(dependency("org.slf4j:.*:.*")) } - exclude("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA", "OSGI-INF/**", "*.profile", "module-info.class", "ant_tasks/**") + exclude("META-INF/*.SF", "META-INF/*.DSA", "META-INF/*.RSA", "OSGI-INF/**", "*.profile", "module-info.class", "ant_tasks/**", "OSGI-OPT/**", "META-INF/*.pro") mergeServiceFiles() } @@ -67,26 +67,39 @@ val shadowJar by tasks.existing(ShadowJar::class) { val prefix = "paper.libs" listOf( + "codechicken.diffpatch", + /* -> */ "codechicken.repack", "com.github.salomonbrys.kotson", - "com.google.errorprone.annotations", "com.google.gson", "dev.denwav.hypo", + /* -> */ "org.jgrapht", + /* -> */ "org.jheaps", + /* -> */ "com.google.errorprone.annotations", + /* -> */ "org.objectweb.asm", "io.sigpipe.jbsdiff", - "me.jamiemansfield", + /* -> */ "org.tukaani.xz", "net.fabricmc", - "org.apache.commons", - "org.apache.felix", "org.apache.http", + /* -> */ "org.apache.commons", "org.cadixdev", - "org.eclipse", - "org.jgrapht", - "org.jheaps", - "org.objectweb.asm", - "org.osgi", - "org.tukaani.xz", + /* -> */ "me.jamiemansfield", + /* -> */ "org.eclipse", + /* ----> */ "org.apache.felix", + /* ----> */ "org.osgi", + "org.parchmentmc.feather", + /* -> */ "com.google.common", + /* ----> */ "com.google.j2objc", + /* ----> */ "com.google.thirdparty", + /* ----> */ "org.checkerframework", + /* ----> */ "javax.annotation", + "org.eclipse.jgit", + /* -> */ "com.googlecode.javaewah", + /* -> */ "com.googlecode.javaewah32", + "kotlinx.coroutines", //"org.slf4j", - "codechicken.diffpatch", - "codechicken.repack" + // used by multiple + "org.intellij.lang", + "org.jetbrains.annotations" ).forEach { pack -> relocate(pack, "$prefix.$pack") } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MergeAccessTransforms.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MergeAccessTransforms.kt index ecc8d2c26..fc97cb807 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MergeAccessTransforms.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MergeAccessTransforms.kt @@ -34,7 +34,6 @@ 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 writeLF @CacheableTask abstract class MergeAccessTransforms : BaseTask() { diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapAccessTransform.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapAccessTransform.kt index 0f86bab3d..dd9e70e9a 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapAccessTransform.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapAccessTransform.kt @@ -32,7 +32,6 @@ 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 writeLF @CacheableTask abstract class RemapAccessTransform : BaseTask() { diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSources.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSources.kt index 79e6db3d1..c99eaad93 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSources.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSources.kt @@ -51,7 +51,6 @@ import org.gradle.kotlin.dsl.* import org.gradle.workers.WorkAction import org.gradle.workers.WorkParameters import org.gradle.workers.WorkerExecutor -import writeLF @CacheableTask abstract class RemapSources : JavaLauncherTask() { diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSpigotAt.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSpigotAt.kt index 909780649..0087dd5ba 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSpigotAt.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSpigotAt.kt @@ -40,7 +40,6 @@ 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 writeLF @CacheableTask abstract class RemapSpigotAt : BaseTask() { diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt index ff9c3e8ca..f1334984d 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt @@ -22,7 +22,6 @@ package io.papermc.paperweight.tasks.softspoon -import atFromString import codechicken.diffpatch.cli.DiffOperation import codechicken.diffpatch.util.LogLevel import codechicken.diffpatch.util.LoggingOutputStream @@ -46,7 +45,6 @@ import org.gradle.api.tasks.* import org.gradle.api.tasks.options.Option import org.intellij.lang.annotations.Language import org.openrewrite.InMemoryExecutionContext -import writeLF @UntrackedTask(because = "Always rebuild patches") abstract class RebuildFilePatches : BaseTask() { diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt index b5a0dad83..15528e7f8 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA */ +package io.papermc.paperweight.util import java.io.BufferedWriter import java.io.StringWriter From 27246cdb9760ce5c134abeea8441ccfa47cdaeb4 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Sat, 7 Dec 2024 15:43:28 +0100 Subject: [PATCH 12/38] spotless --- .../core/taskcontainers/GeneralTasks.kt | 2 -- .../io/papermc/paperweight/tasks/CloneRepo.kt | 22 +++++++++++++++++++ .../tasks/UnpackSpigotBuildData.kt | 22 +++++++++++++++++++ .../kotlin/io/papermc/paperweight/util/at.kt | 1 + .../papermc/paperweight/util/project-util.kt | 1 - 5 files changed, 45 insertions(+), 3 deletions(-) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt index c17b0222e..6c7d19ec4 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt @@ -22,13 +22,11 @@ package io.papermc.paperweight.core.taskcontainers -import com.github.salomonbrys.kotson.fromJson import io.papermc.paperweight.core.ext import io.papermc.paperweight.core.extension.PaperweightCoreExtension import io.papermc.paperweight.tasks.* import io.papermc.paperweight.util.* import org.gradle.api.Project -import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskContainer import org.gradle.kotlin.dsl.* diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CloneRepo.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CloneRepo.kt index f12e9e7ac..2be38a6df 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CloneRepo.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CloneRepo.kt @@ -1,3 +1,25 @@ +/* + * 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.* diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/UnpackSpigotBuildData.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/UnpackSpigotBuildData.kt index ddbb1b35c..6fbc2bd20 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/UnpackSpigotBuildData.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/UnpackSpigotBuildData.kt @@ -1,3 +1,25 @@ +/* + * 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.* diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt index 15528e7f8..9e15a8cfe 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 * USA */ + package io.papermc.paperweight.util import java.io.BufferedWriter diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt index a3981a66a..f2d7e15f0 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt @@ -37,7 +37,6 @@ import org.gradle.api.provider.Provider import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.bundling.AbstractArchiveTask -import org.gradle.api.tasks.bundling.Jar import org.gradle.api.tasks.bundling.Zip import org.gradle.kotlin.dsl.* import org.gradle.plugins.ide.idea.model.IdeaModel From e89033286c4d1e7582fb9d7994793b926fc90a77 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Sat, 7 Dec 2024 15:55:12 +0100 Subject: [PATCH 13/38] dont break nbt files --- .../paperweight/tasks/mache/SetupVanilla.kt | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt index b8cd66133..5ca19a77c 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt @@ -128,12 +128,17 @@ abstract class SetupVanilla : BaseTask() { .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" + if (it.toString().endsWith(".nbt")) { + // nbt files are binary, so we can't just copy them + it.copyTo(target) + } else { + // make sure we have a trailing newline + var content = it.readText() + if (!content.endsWith("\n")) { + content += "\n" + } + target.writeText(content) } - target.writeText(content) } println("Setup git repo...") From ad779453b7c55c2e89125472a8d3f5b6df20d609 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Sat, 7 Dec 2024 15:57:41 +0100 Subject: [PATCH 14/38] fix compile --- .../src/test/kotlin/io/papermc/paperweight/util/ATTest.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/util/ATTest.kt b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/util/ATTest.kt index 125f370f3..922edc26e 100644 --- a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/util/ATTest.kt +++ b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/util/ATTest.kt @@ -22,7 +22,6 @@ package io.papermc.paperweight.util -import atFromString import kotlin.test.Test import kotlin.test.assertEquals import org.cadixdev.at.AccessChange From 331988fdcd20d61696e6d9afeb605b0a5cddc962 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Sat, 7 Dec 2024 15:59:28 +0100 Subject: [PATCH 15/38] make sure comment is actually accurate thanks copilot --- .../kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt index 5ca19a77c..331e7c046 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt @@ -129,10 +129,10 @@ abstract class SetupVanilla : BaseTask() { val target = outputPath.resolve(it.toString().substring(1)) target.parent.createDirectories() if (it.toString().endsWith(".nbt")) { - // nbt files are binary, so we can't just copy them + // nbt files are binary, so we can just copy them it.copyTo(target) } else { - // make sure we have a trailing newline + // for text files we make sure we have a trailing newline var content = it.readText() if (!content.endsWith("\n")) { content += "\n" From 23970f9e4721097755e3f8b754519ff493fbe83a Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sat, 7 Dec 2024 14:27:51 -0700 Subject: [PATCH 16/38] Fix decompile not using java toolchain --- .../paperweight/tasks/mache/DecompileJar.kt | 60 ++++++++----------- 1 file changed, 24 insertions(+), 36 deletions(-) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt index 7c6fa7f10..5e324b4c2 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt @@ -22,32 +22,18 @@ package io.papermc.paperweight.tasks.mache +import io.papermc.paperweight.tasks.* 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 kotlin.io.path.* 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 +import org.gradle.api.provider.Property +import org.gradle.api.tasks.* @CacheableTask -abstract class DecompileJar : DefaultTask() { +abstract class DecompileJar : JavaLauncherTask() { @get:PathSensitive(PathSensitivity.NONE) @get:InputFile @@ -65,11 +51,13 @@ abstract class DecompileJar : DefaultTask() { @get:OutputFile abstract val outputJar: RegularFileProperty - @get:Inject - abstract val exec: ExecOperations + @get:Input + abstract val memory: Property - @get:Inject - abstract val layout: ProjectLayout + override fun init() { + super.init() + memory.convention("4G") + } @TaskAction fun run() { @@ -87,23 +75,23 @@ abstract class DecompileJar : DefaultTask() { 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") + val args = mutableListOf() - maxHeapSize = "3G" + args += decompilerArgs.get() - args(decompilerArgs.get()) - args("-cfg", cfgFile.absolutePathString()) + args += "-cfg" + args += cfgFile.absolutePathString() - args(inputJar.convertToPath().absolutePathString()) - args(out.absolutePathString()) + args += inputJar.convertToPath().absolutePathString() + args += out.absolutePathString() - standardOutput = log - errorOutput = log - } - } + launcher.runJar( + decompiler, + temporaryDir, + logs, + jvmArgs = listOf("-Xmx${memory.get()}"), + args = args.toTypedArray() + ) out.openZip().use { root -> root.getPath("META-INF", "MANIFEST.MF").deleteIfExists() From e03710c8d95c56de62f2ac5d30b5a4917e2a4116 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sat, 7 Dec 2024 14:40:41 -0700 Subject: [PATCH 17/38] Don't shade restamp --- buildSrc/src/main/kotlin/config-publish.gradle.kts | 6 +++++- gradle/libs.versions.toml | 2 +- paperweight-core/build.gradle.kts | 1 + paperweight-lib/build.gradle.kts | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/buildSrc/src/main/kotlin/config-publish.gradle.kts b/buildSrc/src/main/kotlin/config-publish.gradle.kts index d3b244fd6..56d52d6e1 100644 --- a/buildSrc/src/main/kotlin/config-publish.gradle.kts +++ b/buildSrc/src/main/kotlin/config-publish.gradle.kts @@ -16,9 +16,13 @@ if (noRelocate) { } } +val download: Configuration by configurations.creating +configurations.shadowRuntimeElements { + extendsFrom(download) +} val shade: Configuration by configurations.creating configurations.implementation { - extendsFrom(shade) + extendsFrom(shade, download) } fun ShadowJar.configureStandard() { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 97c358d32..feb8f6f4a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -41,7 +41,7 @@ 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" +restamp = "io.papermc.restamp:restamp:1.1.0" # test mockk = "io.mockk:mockk:1.13.8" diff --git a/paperweight-core/build.gradle.kts b/paperweight-core/build.gradle.kts index 5957f60d9..5c546d620 100644 --- a/paperweight-core/build.gradle.kts +++ b/paperweight-core/build.gradle.kts @@ -5,6 +5,7 @@ plugins { dependencies { shade(projects.paperweightLib) + download(libs.restamp) implementation(libs.bundles.kotson) implementation(libs.coroutines) diff --git a/paperweight-lib/build.gradle.kts b/paperweight-lib/build.gradle.kts index 4c01aff32..46dd7f0b2 100644 --- a/paperweight-lib/build.gradle.kts +++ b/paperweight-lib/build.gradle.kts @@ -25,7 +25,7 @@ dependencies { implementation(libs.jbsdiff) - implementation(libs.restamp) + compileOnly(libs.restamp) implementation(variantOf(libs.diffpatch) { classifier("all") }) { isTransitive = false From a38e7aaf0cb3864a6bcbef9d32a317e8ec865ad8 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sat, 7 Dec 2024 14:47:46 -0700 Subject: [PATCH 18/38] Revert "Don't shade restamp" This reverts commit e03710c8d95c56de62f2ac5d30b5a4917e2a4116. --- buildSrc/src/main/kotlin/config-publish.gradle.kts | 6 +----- gradle/libs.versions.toml | 2 +- paperweight-core/build.gradle.kts | 1 - paperweight-lib/build.gradle.kts | 2 +- 4 files changed, 3 insertions(+), 8 deletions(-) diff --git a/buildSrc/src/main/kotlin/config-publish.gradle.kts b/buildSrc/src/main/kotlin/config-publish.gradle.kts index 56d52d6e1..d3b244fd6 100644 --- a/buildSrc/src/main/kotlin/config-publish.gradle.kts +++ b/buildSrc/src/main/kotlin/config-publish.gradle.kts @@ -16,13 +16,9 @@ if (noRelocate) { } } -val download: Configuration by configurations.creating -configurations.shadowRuntimeElements { - extendsFrom(download) -} val shade: Configuration by configurations.creating configurations.implementation { - extendsFrom(shade, download) + extendsFrom(shade) } fun ShadowJar.configureStandard() { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index feb8f6f4a..97c358d32 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -41,7 +41,7 @@ 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.0" +restamp = "io.papermc.restamp:restamp:1.1.1-SNAPSHOT" # test mockk = "io.mockk:mockk:1.13.8" diff --git a/paperweight-core/build.gradle.kts b/paperweight-core/build.gradle.kts index 5c546d620..5957f60d9 100644 --- a/paperweight-core/build.gradle.kts +++ b/paperweight-core/build.gradle.kts @@ -5,7 +5,6 @@ plugins { dependencies { shade(projects.paperweightLib) - download(libs.restamp) implementation(libs.bundles.kotson) implementation(libs.coroutines) diff --git a/paperweight-lib/build.gradle.kts b/paperweight-lib/build.gradle.kts index 46dd7f0b2..4c01aff32 100644 --- a/paperweight-lib/build.gradle.kts +++ b/paperweight-lib/build.gradle.kts @@ -25,7 +25,7 @@ dependencies { implementation(libs.jbsdiff) - compileOnly(libs.restamp) + implementation(libs.restamp) implementation(variantOf(libs.diffpatch) { classifier("all") }) { isTransitive = false From 362bdd6e71f5a7d0ea0a3962dc53d620bd161d6b Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sat, 7 Dec 2024 18:03:18 -0700 Subject: [PATCH 19/38] Resolve restamp at runtime and run it using isolated workers --- gradle/libs.versions.toml | 6 +- paperweight-core/build.gradle.kts | 33 ++++ .../extension/PaperweightCoreExtension.kt | 2 +- .../core/taskcontainers/SoftSpoonTasks.kt | 10 ++ paperweight-lib/build.gradle.kts | 45 ++++- .../paperweight/tasks/mache/SetupVanilla.kt | 42 ++--- .../tasks/softspoon/ApplySourceAT.kt | 64 +------ .../tasks/softspoon/RebuildFilePatches.kt | 132 +++----------- .../kotlin/io/papermc/paperweight/util/at.kt | 40 +---- .../paperweight/util/constants/constants.kt | 1 + .../io/papermc/paperweight/util/file.kt | 35 ---- .../io/papermc/paperweight/util/utils.kt | 10 -- .../paperweight/restamp/RestampVersion.kt.peb | 27 +++ .../restamp/ApplySourceATWorker.kt | 86 +++++++++ .../RebuildFilePatchesRestampWorker.kt | 167 ++++++++++++++++++ .../restamp/SetupVanillaRestampWorker.kt | 72 ++++++++ .../paperweight/restamp/restamp-utils.kt | 66 +++++++ .../paperweight/PaperweightException.kt | 0 .../papermc/paperweight/util/shared-file.kt | 62 +++++++ .../papermc/paperweight/util/shared-utils.kt | 39 ++++ .../tasks/softspoon/ApplySourceATTest.kt | 5 +- .../tasks/softspoon/RebuildFilePatchesTest.kt | 4 + .../io/papermc/paperweight/util/ATTest.kt | 1 + paperweight-patcher/build.gradle.kts | 1 + paperweight-userdev/build.gradle.kts | 1 + 25 files changed, 677 insertions(+), 274 deletions(-) create mode 100644 paperweight-lib/src/restamp/kotlin-templates/io/papermc/paperweight/restamp/RestampVersion.kt.peb create mode 100644 paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/ApplySourceATWorker.kt create mode 100644 paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/RebuildFilePatchesRestampWorker.kt create mode 100644 paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/SetupVanillaRestampWorker.kt create mode 100644 paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/restamp-utils.kt rename paperweight-lib/src/{main => shared}/kotlin/io/papermc/paperweight/PaperweightException.kt (100%) create mode 100644 paperweight-lib/src/shared/kotlin/io/papermc/paperweight/util/shared-file.kt create mode 100644 paperweight-lib/src/shared/kotlin/io/papermc/paperweight/util/shared-utils.kt diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 97c358d32..71fffa162 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,6 +4,7 @@ lorenz = "0.5.8" hypo = "1.2.4" serialize = "1.5.1" feather = "1.1.0" +restamp = "1.1.0" [libraries] asm-core = { module = "org.ow2.asm:asm", version.ref = "asm" } @@ -21,7 +22,6 @@ cadix-lorenz-proguard = { module = "org.cadixdev:lorenz-io-proguard", version.re cadix-atlas = "org.cadixdev:atlas:0.2.1" cadix-at = "org.cadixdev:at:0.1.0-rc1" 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-core = { module = "dev.denwav.hypo:hypo-core", version.ref = "hypo" } @@ -41,7 +41,7 @@ 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" +restamp = {module = "io.papermc.restamp:restamp", version.ref = "restamp" } # test mockk = "io.mockk:mockk:1.13.8" @@ -56,6 +56,6 @@ gradle-plugin-publish = "com.gradle.publish:plugin-publish-plugin:1.2.1" [bundles] asm = ["asm-core", "asm-tree"] -cadix = ["cadix-lorenz-core", "cadix-lorenz-asm", "cadix-lorenz-proguard", "cadix-atlas", "cadix-at", "cadix-mercury", "cadix-bombe-jar"] +cadix = ["cadix-lorenz-core", "cadix-lorenz-asm", "cadix-lorenz-proguard", "cadix-atlas", "cadix-at", "cadix-mercury"] hypo = ["hypo-model", "hypo-core", "hypo-hydrate", "hypo-asm-core", "hypo-asm-hydrate", "hypo-mappings"] kotson = ["kotson", "gson"] diff --git a/paperweight-core/build.gradle.kts b/paperweight-core/build.gradle.kts index 5957f60d9..891621287 100644 --- a/paperweight-core/build.gradle.kts +++ b/paperweight-core/build.gradle.kts @@ -3,8 +3,15 @@ plugins { `config-publish` } +val restamp: Configuration by configurations.creating +configurations.implementation { + extendsFrom(restamp) +} + dependencies { shade(projects.paperweightLib) + shade(project(projects.paperweightLib.dependencyProject.path, "sharedRuntime")) + restamp(project(projects.paperweightLib.dependencyProject.path, "restampRuntime")) implementation(libs.bundles.kotson) implementation(libs.coroutines) @@ -16,3 +23,29 @@ gradlePlugin { implementationClass = "io.papermc.paperweight.core.PaperweightCore" } } + +val finalJar = tasks.register("finalJar", Zip::class) { + archiveExtension.set("jar") + from(zipTree(tasks.shadowJar.flatMap { it.archiveFile })) + from(zipTree(restamp.elements.map { it.single() })) { + exclude("META-INF/MANIFEST.MF") + } +} +val finalRuntimeElements by configurations.registering { + attributes { + attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) + attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.SHADOWED)) + attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR)) + attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME)) + } + outgoing.artifact(finalJar) +} +val javaComponent = project.components.getByName("java") as AdhocComponentWithVariants +afterEvaluate { + javaComponent.withVariantsFromConfiguration(configurations.shadowRuntimeElements.get()) { + skip() + } +} +javaComponent.addVariantsFromConfiguration(finalRuntimeElements.get()) { + mapToMavenScope("runtime") +} diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt index cf41a9ded..0a005cfb3 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt @@ -53,7 +53,7 @@ open class PaperweightCoreExtension(project: Project, objects: ObjectFactory, la val paramMappingsRepo: Property = objects.property() val decompileRepo: Property = objects.property() val remapRepo: Property = objects.property() - val macheRepo: Property = objects.property().convention("https://repo.papermc.io/repository/maven-public/") + val macheRepo: Property = objects.property().convention(PAPER_MAVEN_REPO_URL) val macheOldPath: DirectoryProperty = objects.directoryProperty() val gitFilePatches: Property = objects.property().convention(false) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt index d47a3634e..2d5be21d5 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt @@ -23,6 +23,7 @@ package io.papermc.paperweight.core.taskcontainers import io.papermc.paperweight.core.ext +import io.papermc.paperweight.restamp.RestampVersion import io.papermc.paperweight.tasks.* import io.papermc.paperweight.tasks.mache.* import io.papermc.paperweight.tasks.mache.RemapJar @@ -70,6 +71,11 @@ open class SoftSpoonTasks( } val macheMinecraft by project.configurations.registering val macheMinecraftExtended by project.configurations.registering + val restampConfig = project.configurations.register(RESTAMP_CONFIG) { + defaultDependencies { + add(project.dependencies.create("io.papermc.restamp:restamp:${RestampVersion.VERSION}")) + } + } val macheRemapJar by tasks.registering(RemapJar::class) { group = "mache" @@ -128,6 +134,8 @@ open class SoftSpoonTasks( inputFile.set(macheDecompileJar.flatMap { it.outputJar }) predicate.set { Files.isRegularFile(it) && it.toString().endsWith(".java") } outputDir.set(layout.cache.resolve(BASE_PROJECT).resolve("sources")) + + restamp.from(restampConfig) } val setupMacheResources by tasks.registering(SetupVanilla::class) { @@ -203,6 +211,8 @@ open class SoftSpoonTasks( input.set(layout.projectDirectory.dir("src/vanilla/java")) patches.set(project.ext.paper.sourcePatchDir) gitFilePatches.set(project.ext.gitFilePatches) + + restamp.from(restampConfig) } val rebuildResourcePatches by tasks.registering(RebuildFilePatches::class) { diff --git a/paperweight-lib/build.gradle.kts b/paperweight-lib/build.gradle.kts index 4c01aff32..5402f4a7e 100644 --- a/paperweight-lib/build.gradle.kts +++ b/paperweight-lib/build.gradle.kts @@ -1,12 +1,55 @@ plugins { `config-kotlin` + id("net.kyori.blossom") version "2.1.0" } repositories { gradlePluginPortal() } +val shared = sourceSets.create("shared") +val sharedJar by tasks.creating(Jar::class) { + archiveClassifier = "shared" + from(shared.output) +} +tasks.jar { + from(shared.output) +} +val restamp = sourceSets.create("restamp") { + blossom { + kotlinSources { + properties.put("restamp_version", libs.versions.restamp) + } + } +} +val restampJar by tasks.creating(Jar::class) { + archiveClassifier = "restamp" + from(restamp.output) +} + +configurations { + consumable("restampRuntime") { + outgoing.artifact(restampJar) + } + consumable("sharedRuntime") { + outgoing.artifact(sharedJar) + } +} + dependencies { + shared.compileOnlyConfigurationName(gradleApi()) + shared.compileOnlyConfigurationName(gradleKotlinDsl()) + compileOnly(shared.output) + testImplementation(shared.output) + + restamp.implementationConfigurationName(libs.restamp) + restamp.implementationConfigurationName(shared.output) + restamp.compileOnlyConfigurationName(gradleApi()) + restamp.compileOnlyConfigurationName(gradleKotlinDsl()) + compileOnly(restamp.output) + testImplementation(restamp.output) + testImplementation(libs.restamp) + implementation(libs.httpclient) implementation(libs.bundles.kotson) implementation(libs.coroutines) @@ -25,8 +68,6 @@ dependencies { implementation(libs.jbsdiff) - implementation(libs.restamp) - implementation(variantOf(libs.diffpatch) { classifier("all") }) { isTransitive = false } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt index 331e7c046..dfd5be141 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt @@ -25,15 +25,13 @@ 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.restamp.SetupVanillaRestampWorker 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 javax.inject.Inject 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 @@ -44,9 +42,10 @@ 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 +import org.gradle.kotlin.dsl.* +import org.gradle.workers.WorkerExecutor -abstract class SetupVanilla : BaseTask() { +abstract class SetupVanilla : JavaLauncherTask() { @get:PathSensitive(PathSensitivity.NONE) @get:InputFile @@ -90,6 +89,12 @@ abstract class SetupVanilla : BaseTask() { @get:InputDirectory abstract val macheOld: DirectoryProperty + @get:Inject + abstract val workerExecutor: WorkerExecutor + + @get:CompileClasspath + abstract val restamp: ConfigurableFileCollection + @TaskAction fun run() { val outputPath = outputDir.convertToPath() @@ -175,23 +180,20 @@ abstract class SetupVanilla : BaseTask() { 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()) + val queue = workerExecutor.processIsolation { + forkOptions { + maxHeapSize = "2G" + executable(launcher.get().executablePath.path.absolutePathString()) + classpath.from(restamp) } } + queue.submit(SetupVanillaRestampWorker::class) { + this.ats.set(this@SetupVanilla.ats.pathOrNull) + this.outputPath.set(outputPath) + this.classpath.from(classPath) + } + queue.await() commitAndTag(git, "ATs") } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceAT.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceAT.kt index 2ed1a5462..8b9086d2b 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceAT.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceAT.kt @@ -22,26 +22,20 @@ package io.papermc.paperweight.tasks.softspoon +import io.papermc.paperweight.restamp.ApplySourceATWorker 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 +// TODO: This task is only used in tests? @CacheableTask -abstract class ApplySourceAT : BaseTask() { +abstract class ApplySourceAT : JavaLauncherTask() { @get:Classpath abstract val inputJar: RegularFileProperty @@ -70,13 +64,14 @@ abstract class ApplySourceAT : BaseTask() { val queue = worker.processIsolation { forkOptions { maxHeapSize = "2G" + executable(launcher.get().executablePath.path.absolutePathString()) } } val classPath = minecraftClasspath.files.map { it.toPath() }.toMutableList() classPath.add(inputJar.convertToPath()) - queue.submit(RestampWorker::class) { + queue.submit(ApplySourceATWorker::class) { minecraftClasspath.from(minecraftClasspath) atFile.set(atFile) inputJar.set(inputJar) @@ -84,52 +79,3 @@ abstract class ApplySourceAT : BaseTask() { } } } - -abstract class RestampWorker : WorkAction { - 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() - 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() - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt index f1334984d..39b77a753 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt @@ -25,29 +25,25 @@ package io.papermc.paperweight.tasks.softspoon import codechicken.diffpatch.cli.DiffOperation import codechicken.diffpatch.util.LogLevel import codechicken.diffpatch.util.LoggingOutputStream -import io.papermc.paperweight.PaperweightException +import io.papermc.paperweight.restamp.RebuildFilePatchesRestampWorker 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 javax.inject.Inject 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.gradle.kotlin.dsl.* +import org.gradle.workers.WorkerExecutor import org.intellij.lang.annotations.Language -import org.openrewrite.InMemoryExecutionContext @UntrackedTask(because = "Always rebuild patches") -abstract class RebuildFilePatches : BaseTask() { +abstract class RebuildFilePatches : JavaLauncherTask() { @get:Input @get:Option( @@ -84,7 +80,14 @@ abstract class RebuildFilePatches : BaseTask() { @get:Input abstract val gitFilePatches: Property + @get:Inject + abstract val worker: WorkerExecutor + + @get:CompileClasspath + abstract val restamp: ConfigurableFileCollection + override fun init() { + super.init() contextLines.convention(3) verbose.convention(false) gitFilePatches.convention(false) @@ -97,38 +100,28 @@ abstract class RebuildFilePatches : BaseTask() { 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 - val filesWithNewAts = mutableListOf() - baseDir.walk() - .map { it.relativeTo(baseDir).toString().replace("\\", "/") } - .filter { - !it.startsWith(".git") && !it.endsWith(".nbt") && !it.endsWith(".mcassetsroot") + val queue = worker.processIsolation { + forkOptions { + maxHeapSize = "2G" + executable(launcher.get().executablePath.path.absolutePathString()) + classpath.from(restamp) } - .forEach { - val ats = AccessTransformSet.create() - val source = inputDir.resolve(it) - val decomp = baseDir.resolve(it) - val className = it.replace(".java", "") - if (handleATInSource(source, ats, className)) { - handleATInBase(decomp, ats, baseDir) - filesWithNewAts.add(it) - } - 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" - ) } + val filesWithNewAtsPath = temporaryDir.toPath().resolve("filesWithNewAts.txt") + queue.submit(RebuildFilePatchesRestampWorker::class) { + this.baseDir.set(baseDir) + this.inputDir.set(inputDir) + this.atFile.set(this@RebuildFilePatches.atFile.orNull) + this.atFileOut.set(this@RebuildFilePatches.atFileOut.orNull) + this.minecraftClasspath.from(this@RebuildFilePatches.minecraftClasspath) + this.filesWithNewAts.set(filesWithNewAtsPath) + } + queue.await() + val filesWithNewAts = filesWithNewAtsPath.readLines() if (filesWithNewAts.isNotEmpty()) { git("status").executeOut() @@ -224,73 +217,4 @@ abstract class RebuildFilePatches : BaseTask() { .operate() return result.summary.changedFiles } - - 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() - - // mmmh, maybe add comment to base too? - - 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): Boolean { - val sourceLines = source.readLines() - var foundNew = false - val fixedLines = ArrayList(sourceLines.size) - sourceLines.forEach { line -> - if (!line.contains("// Paper-AT: ")) { - fixedLines.add(line) - return@forEach - } - - foundNew = true - - val split = line.split("// Paper-AT: ") - val at = split[1] - try { - val atClass = newAts.getOrCreateClass(className) - val parts = at.split(" ") - val accessTransform = atFromString(parts[0]) - val name = parts[1] - val index = name.indexOf('(') - if (index == -1) { - atClass.mergeField(name, accessTransform) - } else { - atClass.mergeMethod(MethodSignature.of(name.substring(0, index), name.substring(index)), accessTransform) - } - logger.lifecycle("Found new AT in $className: $at -> $accessTransform") - } catch (ex: Exception) { - throw PaperweightException("Found invalid AT '$at' in class $className") - } - - fixedLines.add(split[0]) - } - - if (foundNew) { - source.writeText(fixedLines.joinToString("\n", postfix = "\n"), Charsets.UTF_8) - } - - return foundNew - } } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt index 9e15a8cfe..027166336 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/at.kt @@ -26,46 +26,10 @@ 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 -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 -} - +// This is copy-pasted into restamp-utils.kt, make sure to update it fun AccessTransformFormat.writeLF(path: Path, at: AccessTransformSet, header: String = "") { val stringWriter = StringWriter() val writer = BufferedWriter(stringWriter) @@ -73,6 +37,6 @@ fun AccessTransformFormat.writeLF(path: Path, at: AccessTransformSet, header: St 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 + // remove last empty line, sort, then add it back path.writeText(lines.subList(0, lines.size - 1).sorted().joinToString("\n", header, "\n"), Charsets.UTF_8) } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt index ec6b575b2..1ee5f179e 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt @@ -45,6 +45,7 @@ const val PLUGIN_REMAPPER_CONFIG = "pluginRemapper" const val DECOMPILER_CONFIG = "decompiler" const val PAPERCLIP_CONFIG = "paperclip" const val MACHE_CONFIG = "mache" +const val RESTAMP_CONFIG = "restamp" const val DEV_BUNDLE_CONFIG = "paperweightDevelopmentBundle" const val MOJANG_MAPPED_SERVER_CONFIG = "mojangMappedServer" const val MOJANG_MAPPED_SERVER_RUNTIME_CONFIG = "mojangMappedServerRuntime" diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/file.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/file.kt index 7b0d99e14..c9dbd3679 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/file.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/file.kt @@ -24,11 +24,7 @@ package io.papermc.paperweight.util import io.papermc.paperweight.PaperweightException import java.io.InputStream -import java.net.URI import java.nio.file.FileAlreadyExistsException -import java.nio.file.FileSystem -import java.nio.file.FileSystemNotFoundException -import java.nio.file.FileSystems import java.nio.file.Files import java.nio.file.Path import java.nio.file.PathMatcher @@ -36,8 +32,6 @@ import java.nio.file.attribute.DosFileAttributeView import java.nio.file.attribute.FileAttribute import java.util.Arrays import java.util.stream.Collectors -import java.util.stream.Stream -import java.util.stream.StreamSupport import java.util.zip.ZipEntry import java.util.zip.ZipInputStream import java.util.zip.ZipOutputStream @@ -45,7 +39,6 @@ import kotlin.io.path.* import kotlin.streams.asSequence import org.gradle.api.Project import org.gradle.api.file.DirectoryProperty -import org.gradle.api.file.FileSystemLocation import org.gradle.api.file.FileSystemLocationProperty import org.gradle.api.file.RegularFileProperty import org.gradle.api.logging.Logging @@ -53,13 +46,6 @@ import org.gradle.api.provider.Provider // utils for dealing with java.nio.file.Path and java.io.File -val FileSystemLocation.path: Path - get() = asFile.toPath() -val Provider.path: Path - get() = get().path -val Provider.pathOrNull: Path? - get() = orNull?.path - fun FileSystemLocationProperty<*>.set(path: Path?) = set(path?.toFile()) fun

> P.pathProvider(path: Provider) = apply { fileProvider(path.map { it.toFile() }) } @@ -143,22 +129,6 @@ fun Path.filesMatchingRecursive(glob: String = "*"): List { } } -private fun Path.jarUri(): URI { - return URI.create("jar:${toUri()}") -} - -fun Path.openZip(): FileSystem { - return try { - FileSystems.getFileSystem(jarUri()) - } catch (e: FileSystemNotFoundException) { - FileSystems.newFileSystem(jarUri(), emptyMap()) - } -} - -fun Path.writeZip(): FileSystem { - return FileSystems.newFileSystem(jarUri(), mapOf("create" to "true")) -} - inline fun Path.writeZipStream(func: (ZipOutputStream) -> Unit) { ZipOutputStream(this.outputStream().buffered()).use(func) } @@ -183,11 +153,6 @@ fun copyEntry(input: InputStream, output: ZipOutputStream, entry: ZipEntry) { } } -fun FileSystem.walk(): Stream { - return StreamSupport.stream(rootDirectories.spliterator(), false) - .flatMap { Files.walk(it) } -} - fun ProcessBuilder.directory(path: Path?): ProcessBuilder = directory(path?.toFile()) fun Path.hashFile(algorithm: HashingAlgorithm): ByteArray = inputStream().use { input -> input.hash(algorithm) } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt index 1cd863945..655b7c053 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt @@ -196,16 +196,6 @@ class DelegatingOutputStream(vararg delegates: OutputStream) : OutputStream() { } } -fun Any.convertToPath(): Path { - return when (this) { - is Path -> this - is File -> this.toPath() - is FileSystemLocation -> this.path - is Provider<*> -> this.get().convertToPath() - else -> throw PaperweightException("Unknown type representing a file: ${this.javaClass.name}") - } -} - fun Path.ensureClean(): Path { try { deleteRecursively() diff --git a/paperweight-lib/src/restamp/kotlin-templates/io/papermc/paperweight/restamp/RestampVersion.kt.peb b/paperweight-lib/src/restamp/kotlin-templates/io/papermc/paperweight/restamp/RestampVersion.kt.peb new file mode 100644 index 000000000..3c486897c --- /dev/null +++ b/paperweight-lib/src/restamp/kotlin-templates/io/papermc/paperweight/restamp/RestampVersion.kt.peb @@ -0,0 +1,27 @@ +/* + * 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.restamp + +object RestampVersion { + const val VERSION: String = "{{ restamp_version }}" +} diff --git a/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/ApplySourceATWorker.kt b/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/ApplySourceATWorker.kt new file mode 100644 index 000000000..11939dcb8 --- /dev/null +++ b/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/ApplySourceATWorker.kt @@ -0,0 +1,86 @@ +/* + * 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.restamp + +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 kotlin.io.path.readText +import kotlin.io.path.writeText +import org.cadixdev.at.io.AccessTransformFormats +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.RegularFileProperty +import org.gradle.workers.WorkAction +import org.gradle.workers.WorkParameters +import org.openrewrite.InMemoryExecutionContext + +abstract class ApplySourceATWorker : WorkAction { + interface Params : WorkParameters { + val minecraftClasspath: ConfigurableFileCollection + val atFile: RegularFileProperty + val inputJar: RegularFileProperty + val outputJar: RegularFileProperty + } + + override fun execute() { + val inputZip = parameters.inputJar.path.openZip() + + val classPath = parameters.minecraftClasspath.files.map { it.toPath() }.toMutableList() + classPath.add(parameters.inputJar.path) + + val configuration = RestampContextConfiguration.builder() + .accessTransformers(parameters.atFile.path, 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.path.writeZip().use { zip -> + val alreadyWritten = mutableSetOf() + 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() + } +} diff --git a/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/RebuildFilePatchesRestampWorker.kt b/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/RebuildFilePatchesRestampWorker.kt new file mode 100644 index 000000000..35f768ad5 --- /dev/null +++ b/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/RebuildFilePatchesRestampWorker.kt @@ -0,0 +1,167 @@ +/* + * 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.restamp + +import io.papermc.paperweight.PaperweightException +import io.papermc.paperweight.util.path +import io.papermc.restamp.Restamp +import io.papermc.restamp.RestampContextConfiguration +import io.papermc.restamp.RestampInput +import java.nio.file.Path +import kotlin.io.path.readLines +import kotlin.io.path.relativeTo +import kotlin.io.path.walk +import kotlin.io.path.writeLines +import kotlin.io.path.writeText +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.logging.Logger +import org.gradle.api.logging.Logging +import org.gradle.workers.WorkAction +import org.gradle.workers.WorkParameters +import org.openrewrite.InMemoryExecutionContext + +abstract class RebuildFilePatchesRestampWorker : WorkAction { + companion object { + private val logger: Logger = Logging.getLogger(RebuildFilePatchesRestampWorker::class.java) + } + + interface Params : WorkParameters { + val baseDir: DirectoryProperty + val inputDir: DirectoryProperty + val atFile: RegularFileProperty + val atFileOut: RegularFileProperty + val minecraftClasspath: ConfigurableFileCollection + val filesWithNewAts: RegularFileProperty + } + + override fun execute() { + val oldAts = if (parameters.atFile.isPresent) { + AccessTransformFormats.FML.read(parameters.atFile.path) + } else { + AccessTransformSet.create() + } + + // handle AT + val filesWithNewAts = mutableListOf() + parameters.baseDir.path.walk() + .map { it.relativeTo(parameters.baseDir.path).toString().replace("\\", "/") } + .filter { + !it.startsWith(".git") && !it.endsWith(".nbt") && !it.endsWith(".mcassetsroot") + } + .forEach { + val ats = AccessTransformSet.create() + val source = parameters.inputDir.path.resolve(it) + val decomp = parameters.baseDir.path.resolve(it) + val className = it.replace(".java", "") + if (handleATInSource(source, ats, className)) { + handleATInBase(decomp, ats, parameters.baseDir.path) + filesWithNewAts.add(it) + } + oldAts.merge(ats) + } + + if (parameters.atFileOut.isPresent) { + AccessTransformFormats.FML.writeLF( + parameters.atFileOut.path, + oldAts, + "# This file is auto generated, any changes may be overridden!\n# See CONTRIBUTING.md on how to add access transformers.\n" + ) + } + + parameters.filesWithNewAts.path.writeLines(filesWithNewAts) + } + + 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(parameters.minecraftClasspath.files.map { it.toPath() }) + .executionContext(InMemoryExecutionContext { it.printStackTrace() }) + .build() + + // mmmh, maybe add comment to base too? + + 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): Boolean { + val sourceLines = source.readLines() + var foundNew = false + val fixedLines = ArrayList(sourceLines.size) + sourceLines.forEach { line -> + if (!line.contains("// Paper-AT: ")) { + fixedLines.add(line) + return@forEach + } + + foundNew = true + + val split = line.split("// Paper-AT: ") + val at = split[1] + try { + val atClass = newAts.getOrCreateClass(className) + val parts = at.split(" ") + val accessTransform = atFromString(parts[0]) + val name = parts[1] + val index = name.indexOf('(') + if (index == -1) { + atClass.mergeField(name, accessTransform) + } else { + atClass.mergeMethod(MethodSignature.of(name.substring(0, index), name.substring(index)), accessTransform) + } + logger.lifecycle("Found new AT in $className: $at -> $accessTransform") + } catch (ex: Exception) { + throw PaperweightException("Found invalid AT '$at' in class $className") + } + + fixedLines.add(split[0]) + } + + if (foundNew) { + source.writeText(fixedLines.joinToString("\n", postfix = "\n"), Charsets.UTF_8) + } + + return foundNew + } +} diff --git a/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/SetupVanillaRestampWorker.kt b/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/SetupVanillaRestampWorker.kt new file mode 100644 index 000000000..7dd7430de --- /dev/null +++ b/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/SetupVanillaRestampWorker.kt @@ -0,0 +1,72 @@ +/* + * 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.restamp + +import io.papermc.paperweight.util.path +import io.papermc.restamp.Restamp +import io.papermc.restamp.RestampContextConfiguration +import io.papermc.restamp.RestampInput +import java.nio.file.Path +import kotlin.io.path.writeText +import org.cadixdev.at.io.AccessTransformFormats +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.RegularFileProperty +import org.gradle.workers.WorkAction +import org.gradle.workers.WorkParameters +import org.openrewrite.InMemoryExecutionContext + +abstract class SetupVanillaRestampWorker : WorkAction { + interface Params : WorkParameters { + val ats: RegularFileProperty + val outputPath: RegularFileProperty + val classpath: ConfigurableFileCollection + } + + override fun execute() { + setupVanillaRestamp( + parameters.ats, + parameters.outputPath.path, + parameters.classpath.files.map { it.toPath() } + ) + } + + private fun setupVanillaRestamp(ats: RegularFileProperty, outputPath: Path, classPath: List) { + val configuration = RestampContextConfiguration.builder() + .accessTransformers(ats.path, 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()) + } + } + } +} diff --git a/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/restamp-utils.kt b/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/restamp-utils.kt new file mode 100644 index 000000000..191a783bb --- /dev/null +++ b/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/restamp-utils.kt @@ -0,0 +1,66 @@ +/* + * 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.restamp + +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 + +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) +} + +// TODO: Don't copy paste this somehow +// Start copied from at.kt +fun AccessTransformFormat.writeLF(path: Path, at: AccessTransformSet, header: String = "") { + val stringWriter = StringWriter() + val writer = BufferedWriter(stringWriter) + write(writer, at) + writer.close() + // unify line endings + val lines = stringWriter.toString().replace("\r\n", "\n").split("\n") + // remove last empty line, sort, then add it back + path.writeText(lines.subList(0, lines.size - 1).sorted().joinToString("\n", header, "\n"), Charsets.UTF_8) +} +// End copied from at.kt diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/PaperweightException.kt b/paperweight-lib/src/shared/kotlin/io/papermc/paperweight/PaperweightException.kt similarity index 100% rename from paperweight-lib/src/main/kotlin/io/papermc/paperweight/PaperweightException.kt rename to paperweight-lib/src/shared/kotlin/io/papermc/paperweight/PaperweightException.kt diff --git a/paperweight-lib/src/shared/kotlin/io/papermc/paperweight/util/shared-file.kt b/paperweight-lib/src/shared/kotlin/io/papermc/paperweight/util/shared-file.kt new file mode 100644 index 000000000..ecfc22d08 --- /dev/null +++ b/paperweight-lib/src/shared/kotlin/io/papermc/paperweight/util/shared-file.kt @@ -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.util + +import java.net.URI +import java.nio.file.FileSystem +import java.nio.file.FileSystemNotFoundException +import java.nio.file.FileSystems +import java.nio.file.Files +import java.nio.file.Path +import java.util.stream.Stream +import java.util.stream.StreamSupport +import org.gradle.api.file.FileSystemLocation +import org.gradle.api.provider.Provider + +val FileSystemLocation.path: Path + get() = asFile.toPath() +val Provider.path: Path + get() = get().path +val Provider.pathOrNull: Path? + get() = orNull?.path + +private fun Path.jarUri(): URI { + return URI.create("jar:${toUri()}") +} + +fun Path.openZip(): FileSystem { + return try { + FileSystems.getFileSystem(jarUri()) + } catch (e: FileSystemNotFoundException) { + FileSystems.newFileSystem(jarUri(), emptyMap()) + } +} + +fun Path.writeZip(): FileSystem { + return FileSystems.newFileSystem(jarUri(), mapOf("create" to "true")) +} + +fun FileSystem.walk(): Stream { + return StreamSupport.stream(rootDirectories.spliterator(), false) + .flatMap { Files.walk(it) } +} diff --git a/paperweight-lib/src/shared/kotlin/io/papermc/paperweight/util/shared-utils.kt b/paperweight-lib/src/shared/kotlin/io/papermc/paperweight/util/shared-utils.kt new file mode 100644 index 000000000..19a0d3752 --- /dev/null +++ b/paperweight-lib/src/shared/kotlin/io/papermc/paperweight/util/shared-utils.kt @@ -0,0 +1,39 @@ +/* + * 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 io.papermc.paperweight.PaperweightException +import java.io.File +import java.nio.file.Path +import org.gradle.api.file.FileSystemLocation +import org.gradle.api.provider.Provider + +fun Any.convertToPath(): Path { + return when (this) { + is Path -> this + is File -> this.toPath() + is FileSystemLocation -> this.path + is Provider<*> -> this.get().convertToPath() + else -> throw PaperweightException("Unknown type representing a file: ${this.javaClass.name}") + } +} diff --git a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceATTest.kt b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceATTest.kt index bbb757d92..c27ca9346 100644 --- a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceATTest.kt +++ b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceATTest.kt @@ -25,6 +25,7 @@ package io.papermc.paperweight.tasks.softspoon import io.mockk.every import io.mockk.mockk import io.mockk.mockkObject +import io.papermc.paperweight.restamp.ApplySourceATWorker import io.papermc.paperweight.tasks.* import java.nio.file.Path import kotlin.test.BeforeTest @@ -48,8 +49,8 @@ class ApplySourceATTest : TaskTest() { every { task.worker } returns workerExecutor every { workerExecutor.processIsolation(any()) } returns workQueue - every { workQueue.submit(RestampWorker::class, any()) } answers { - val action = object : RestampWorker() { + every { workQueue.submit(ApplySourceATWorker::class, any()) } answers { + val action = object : ApplySourceATWorker() { override fun getParameters(): Params { return mockk().also { every { it.inputJar.get() } returns task.inputJar.get() diff --git a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatchesTest.kt b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatchesTest.kt index 60cbe80e5..f424dac5d 100644 --- a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatchesTest.kt +++ b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatchesTest.kt @@ -27,6 +27,7 @@ import java.nio.file.Path import kotlin.test.BeforeTest import kotlin.test.Test import org.gradle.kotlin.dsl.* +import org.junit.jupiter.api.Disabled import org.junit.jupiter.api.io.CleanupMode import org.junit.jupiter.api.io.TempDir @@ -36,9 +37,12 @@ class RebuildFilePatchesTest : TaskTest() { @BeforeTest fun setup() { val project = setupProject() + project.plugins.apply("java") task = project.tasks.register("rebuildPatches", RebuildFilePatches::class).get() } + // TODO + @Disabled("worker api not available here") @Test fun `should rebuild patches`(@TempDir(cleanup = CleanupMode.ON_SUCCESS) tempDir: Path) { println("running in $tempDir") diff --git a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/util/ATTest.kt b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/util/ATTest.kt index 922edc26e..a76294e72 100644 --- a/paperweight-lib/src/test/kotlin/io/papermc/paperweight/util/ATTest.kt +++ b/paperweight-lib/src/test/kotlin/io/papermc/paperweight/util/ATTest.kt @@ -22,6 +22,7 @@ package io.papermc.paperweight.util +import io.papermc.paperweight.restamp.atFromString import kotlin.test.Test import kotlin.test.assertEquals import org.cadixdev.at.AccessChange diff --git a/paperweight-patcher/build.gradle.kts b/paperweight-patcher/build.gradle.kts index a3448b881..3e4e1c4ec 100644 --- a/paperweight-patcher/build.gradle.kts +++ b/paperweight-patcher/build.gradle.kts @@ -5,6 +5,7 @@ plugins { dependencies { shade(projects.paperweightLib) + shade(project(projects.paperweightLib.dependencyProject.path, "sharedRuntime")) implementation(libs.bundles.kotson) } diff --git a/paperweight-userdev/build.gradle.kts b/paperweight-userdev/build.gradle.kts index 863e802b9..784dea566 100644 --- a/paperweight-userdev/build.gradle.kts +++ b/paperweight-userdev/build.gradle.kts @@ -5,6 +5,7 @@ plugins { dependencies { shade(projects.paperweightLib) + shade(project(projects.paperweightLib.dependencyProject.path, "sharedRuntime")) implementation(libs.bundles.kotson) implementation(variantOf(libs.diffpatch) { classifier("all") }) { isTransitive = false From eead554644ee8875480694fbfbb0087a575bf73d Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sat, 7 Dec 2024 18:16:16 -0700 Subject: [PATCH 20/38] Start ripping out legacy code removes mercury dependency, jar back down to ~15mb --- .../src/main/kotlin/config-publish.gradle.kts | 3 - gradle/libs.versions.toml | 3 +- paperweight-core/build.gradle.kts | 3 + .../paperweight/core/PaperweightCore.kt | 54 +-- .../core/taskcontainers/AllTasks.kt | 105 ----- .../core/taskcontainers/SpigotTasks.kt | 22 - .../papermc/paperweight/tasks/RemapSources.kt | 430 ------------------ .../patchremap/PatchSourceRemapWorker.kt | 78 ---- .../tasks/patchremap/RemapPatches.kt | 296 ------------ .../io/papermc/paperweight/util/PaperAt.kt | 88 ---- 10 files changed, 8 insertions(+), 1074 deletions(-) delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSources.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/PatchSourceRemapWorker.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/RemapPatches.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/PaperAt.kt diff --git a/buildSrc/src/main/kotlin/config-publish.gradle.kts b/buildSrc/src/main/kotlin/config-publish.gradle.kts index d3b244fd6..02d6693d5 100644 --- a/buildSrc/src/main/kotlin/config-publish.gradle.kts +++ b/buildSrc/src/main/kotlin/config-publish.gradle.kts @@ -83,9 +83,6 @@ val shadowJar by tasks.existing(ShadowJar::class) { /* -> */ "org.apache.commons", "org.cadixdev", /* -> */ "me.jamiemansfield", - /* -> */ "org.eclipse", - /* ----> */ "org.apache.felix", - /* ----> */ "org.osgi", "org.parchmentmc.feather", /* -> */ "com.google.common", /* ----> */ "com.google.j2objc", diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 71fffa162..f513ef092 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,7 +21,6 @@ cadix-lorenz-asm = { module = "org.cadixdev:lorenz-asm", version.ref = "lorenz" cadix-lorenz-proguard = { module = "org.cadixdev:lorenz-io-proguard", version.ref = "lorenz" } cadix-atlas = "org.cadixdev:atlas:0.2.1" cadix-at = "org.cadixdev:at:0.1.0-rc1" -cadix-mercury = "org.cadixdev:mercury:0.1.2-paperweight-SNAPSHOT" hypo-model = { module = "dev.denwav.hypo:hypo-model", version.ref = "hypo" } hypo-core = { module = "dev.denwav.hypo:hypo-core", version.ref = "hypo" } @@ -56,6 +55,6 @@ gradle-plugin-publish = "com.gradle.publish:plugin-publish-plugin:1.2.1" [bundles] 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"] hypo = ["hypo-model", "hypo-core", "hypo-hydrate", "hypo-asm-core", "hypo-asm-hydrate", "hypo-mappings"] kotson = ["kotson", "gson"] diff --git a/paperweight-core/build.gradle.kts b/paperweight-core/build.gradle.kts index 891621287..3b2c1fc1c 100644 --- a/paperweight-core/build.gradle.kts +++ b/paperweight-core/build.gradle.kts @@ -31,6 +31,9 @@ val finalJar = tasks.register("finalJar", Zip::class) { exclude("META-INF/MANIFEST.MF") } } +tasks.assemble { + dependsOn(finalJar) +} val finalRuntimeElements by configurations.registering { attributes { attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.LIBRARY)) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt index b4a9ccf8c..55a11769d 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt @@ -26,19 +26,15 @@ import io.papermc.paperweight.DownloadService import io.papermc.paperweight.core.extension.PaperweightCoreExtension 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.taskcontainers.BundlerJarTasks import io.papermc.paperweight.taskcontainers.DevBundleTasks import io.papermc.paperweight.tasks.* -import io.papermc.paperweight.tasks.patchremap.RemapPatches import io.papermc.paperweight.util.* import io.papermc.paperweight.util.constants.* -import java.io.File import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.logging.Logging import org.gradle.api.tasks.Delete -import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.bundling.AbstractArchiveTask import org.gradle.api.tasks.bundling.Zip import org.gradle.kotlin.dsl.* @@ -122,8 +118,7 @@ class PaperweightCore : Plugin { ext.minecraftVersion ) - target.createPatchRemapTask(tasks) - + /* target.tasks.register(PAPERWEIGHT_PREPARE_DOWNSTREAM) { dependsOn(tasks.applyPatchesLegacy) vanillaJar.set(tasks.downloadServerJar.flatMap { it.outputJar }) @@ -154,6 +149,7 @@ class PaperweightCore : Plugin { ) ) } + */ target.afterEvaluate { println("SoftSpoon: ${ext.softSpoon.get()}") @@ -198,6 +194,7 @@ class PaperweightCore : Plugin { inputJar.set(serverJar.flatMap { it.archiveFile }) } + /* val (includeMappings, reobfJar) = serverProj.setupServerProject( target, tasks.lineMapJar.flatMap { it.outputJar }, @@ -241,50 +238,7 @@ class PaperweightCore : Plugin { reobfJar, ext.minecraftVersion ) - } - } - - private fun Project.createPatchRemapTask(allTasks: AllTasks) { - val extension: PaperweightCoreExtension = ext - - /* - * To ease the waiting time for debugging this task, all of the task dependencies have been removed (notice all - * of those .get() calls). This means when you make changes to paperweight Gradle won't know that this task - * technically depends on the output of all of those other tasks. - * - * In order to run all of the other necessary tasks before running this task in order to setup the inputs, run: - * - * ./gradlew patchPaper applyVanillaSrgAt - * - * Then you should be able to run `./gradlew remapPatches` without having to worry about all of the other tasks - * running whenever you make changes to paperweight. - */ - - @Suppress("UNUSED_VARIABLE") - val remapPatches: TaskProvider by tasks.registering { - group = "paperweight" - description = "NOT FOR TYPICAL USE: Attempt to remap Paper's patches from Spigot mappings to Mojang mappings." - - inputPatchDir.set(extension.paper.unmappedSpigotServerPatchDir) - apiPatchDir.set(extension.paper.spigotApiPatchDir) - - mappingsFile.set(allTasks.patchMappings.flatMap { it.outputMappings }.get()) - ats.set(allTasks.remapSpigotSources.flatMap { it.generatedAt }.get()) - - // Pull in as many jars as possible to reduce the possibility of type bindings not resolving - classpathJars.from(allTasks.applyMergedAt.flatMap { it.outputJar }.get()) // final remapped jar - classpathJars.from(allTasks.remapSpigotSources.flatMap { it.vanillaRemappedSpigotJar }.get()) // Spigot remapped jar - classpathJars.from(allTasks.extractFromBundler.flatMap { it.serverJar }.get()) // pure vanilla jar - - spigotApiDir.set(allTasks.patchSpigotApi.flatMap { it.outputDir }.get()) - spigotServerDir.set(allTasks.patchSpigotServer.flatMap { it.outputDir }.get()) - spigotDecompJar.set(allTasks.spigotDecompileJar.flatMap { it.outputJar }.get()) - - // library class imports - mcLibrarySourcesDir.set(allTasks.downloadMcLibrariesSources.flatMap { it.outputDir }.get()) - devImports.set(extension.paper.devImports) - - outputPatchDir.set(extension.paper.remappedSpigotServerPatchDir) + */ } } } diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt index 2a826d6fa..97a395063 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/AllTasks.kt @@ -30,7 +30,6 @@ import io.papermc.paperweight.util.* import io.papermc.paperweight.util.constants.* import java.nio.file.Path import org.gradle.api.Project -import org.gradle.api.Task import org.gradle.api.artifacts.component.ModuleComponentIdentifier import org.gradle.api.plugins.JavaPlugin import org.gradle.api.provider.Provider @@ -46,54 +45,6 @@ open class AllTasks( downloadService: Provider = project.download ) : SpigotTasks(project) { - val mergeAdditionalAts by tasks.registering { - firstFile.set(mergeGeneratedAts.flatMap { it.outputFile }) - secondFile.set(mergePaperAts.flatMap { it.outputFile }) - } - - val applyMergedAt by tasks.registering { - inputJar.set(fixJar.flatMap { it.outputJar }) - atFile.set(mergeAdditionalAts.flatMap { it.outputFile }) - } - - val copyResources by tasks.registering { - inputJar.set(applyMergedAt.flatMap { it.outputJar }) - vanillaJar.set(extractFromBundler.flatMap { it.serverJar }) - } - - val decompileJar by tasks.registering { - executable.from(project.configurations.named(DECOMPILER_CONFIG)) - - inputJar.set(copyResources.flatMap { it.outputJar }) - libraries.from(extractFromBundler.map { it.serverLibraryJars.asFileTree }) - - outputJar.set(cache.resolve(FINAL_DECOMPILE_JAR)) - } - - val lineMapJar by tasks.registering { - inputJar.set(copyResources.flatMap { it.outputJar }) - outputJar.set(cache.resolve(FINAL_REMAPPED_JAR)) - decompiledJar.set(decompileJar.flatMap { it.outputJar }) - } - - val applyApiPatches by tasks.registering { - group = "paper" - description = "Setup the Paper-API project" - - if (project.isBaseExecution) { - doNotTrackState("$name should always run when requested as part of the base execution.") - } - printOutput.set(project.isBaseExecution) - - branch.set("HEAD") - upstreamBranch.set("upstream") - upstream.set(patchSpigotApi.flatMap { it.outputDir }) - patchDir.set(extension.paper.spigotApiPatchDir) - unneededFiles.value(listOf("README.md")) - - outputDir.set(extension.paper.paperApiDir) - } - val downloadMcLibrariesSources by tasks.registering { mcLibrariesFile.set(extractFromBundler.flatMap { it.serverLibrariesTxt }) repositories.set(listOf(MC_LIBRARY_URL, MAVEN_CENTRAL_URL)) @@ -121,62 +72,6 @@ open class AllTasks( downloader.set(downloadService) } - @Suppress("DuplicatedCode") - val applyServerPatches by tasks.registering { - group = "paper" - description = "Setup the Paper-Server project" - - if (project.isBaseExecution) { - doNotTrackState("$name should always run when requested as part of the base execution.") - } - printOutput.set(project.isBaseExecution) - - patchDir.set(extension.paper.spigotServerPatchDir) - remappedSource.set(remapSpigotSources.flatMap { it.sourcesOutputZip }) - remappedTests.set(remapSpigotSources.flatMap { it.testsOutputZip }) - caseOnlyClassNameChanges.set(cleanupSourceMappings.flatMap { it.caseOnlyNameChanges }) - upstreamDir.set(patchSpigotServer.flatMap { it.outputDir }) - sourceMcDevJar.set(decompileJar.flatMap { it.outputJar }) - mcLibrariesDir.set(downloadMcLibrariesSources.flatMap { it.outputDir }) - spigotLibrariesDir.set(downloadSpigotDependencies.flatMap { it.outputSourcesDir }) - devImports.set(extension.paper.devImports.fileExists(project)) - unneededFiles.value(listOf("nms-patches", "applyPatches.sh", "CONTRIBUTING.md", "makePatches.sh", "README.md")) - - outputDir.set(extension.paper.paperServerDir) - mcDevSources.set(extension.mcDevSourceDir) - } - - val applyPatchesLegacy by tasks.registering { - group = "paper" - description = "Set up the Paper development environment" - dependsOn(applyApiPatches, applyServerPatches) - } - - val rebuildApiPatches by tasks.registering { - group = "paper" - description = "Rebuilds patches to api" - inputDir.set(extension.paper.paperApiDir) - baseRef.set("base") - - patchDir.set(extension.paper.spigotApiPatchDir) - } - - val rebuildServerPatches by tasks.registering { - group = "paper" - description = "Rebuilds patches to server" - inputDir.set(extension.paper.paperServerDir) - baseRef.set("base") - - patchDir.set(extension.paper.spigotServerPatchDir) - } - - @Suppress("unused") - val rebuildPatchesLegacy by tasks.registering { - group = "paper" - description = "Rebuilds patches to api and server" - dependsOn(rebuildApiPatches, rebuildServerPatches) - } - val generateReobfMappings by tasks.registering { inputMappings.set(patchMappings.flatMap { it.outputMappings }) notchToSpigotMappings.set(generateSpigotMappings.flatMap { it.notchToSpigotMappings }) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt index 9d90bd5bf..05f5ecf54 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt @@ -196,26 +196,4 @@ open class SpigotTasks( mapping.set(patchMappings.flatMap { it.outputMappings }) spigotAt.set(unpackSpigotBuildData.flatMap { it.atFile }) } - - @Suppress("DuplicatedCode") - val remapSpigotSources by tasks.registering { - spigotServerDir.set(patchSpigotServer.flatMap { it.outputDir }) - spigotApiDir.set(patchSpigotApi.flatMap { it.outputDir }) - mappings.set(cleanupSourceMappings.flatMap { it.outputMappings }) - vanillaJar.set(extractFromBundler.flatMap { it.serverJar }) - mojangMappedVanillaJar.set(fixJar.flatMap { it.outputJar }) - vanillaRemappedSpigotJar.set(filterSpigotExcludes.flatMap { it.outputZip }) - spigotDeps.from(downloadSpigotDependencies.map { it.outputDir.asFileTree }) - additionalAts.set(mergePaperAts.flatMap { it.outputFile }) - } - - val remapGeneratedAt by tasks.registering { - inputFile.set(remapSpigotSources.flatMap { it.generatedAt }) - mappings.set(patchMappings.flatMap { it.outputMappings }) - } - - val mergeGeneratedAts by tasks.registering { - firstFile.set(remapGeneratedAt.flatMap { it.outputFile }) - secondFile.set(remapSpigotAt.flatMap { it.outputFile }) - } } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSources.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSources.kt deleted file mode 100644 index c99eaad93..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapSources.kt +++ /dev/null @@ -1,430 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks - -import io.papermc.paperweight.PaperweightException -import io.papermc.paperweight.util.* -import io.papermc.paperweight.util.constants.* -import java.nio.file.Files -import java.nio.file.Path -import javax.inject.Inject -import kotlin.io.path.* -import kotlin.streams.asSequence -import org.cadixdev.at.AccessTransformSet -import org.cadixdev.at.io.AccessTransformFormats -import org.cadixdev.mercury.Mercury -import org.cadixdev.mercury.RewriteContext -import org.cadixdev.mercury.SourceProcessor -import org.cadixdev.mercury.SourceRewriter -import org.cadixdev.mercury.at.AccessTransformerRewriter -import org.cadixdev.mercury.extra.AccessAnalyzerProcessor -import org.cadixdev.mercury.remapper.MercuryRemapper -import org.eclipse.jdt.core.JavaCore -import org.eclipse.jdt.core.dom.* -import org.gradle.api.file.ConfigurableFileCollection -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.ListProperty -import org.gradle.api.provider.Property -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 - -@CacheableTask -abstract class RemapSources : JavaLauncherTask() { - - @get:CompileClasspath - abstract val vanillaJar: RegularFileProperty - - @get:CompileClasspath - abstract val mojangMappedVanillaJar: RegularFileProperty - - @get:CompileClasspath - abstract val vanillaRemappedSpigotJar: RegularFileProperty - - @get:InputFile - @get:PathSensitive(PathSensitivity.NONE) - abstract val mappings: RegularFileProperty - - @get:CompileClasspath - abstract val spigotDeps: ConfigurableFileCollection - - @get:InputDirectory - @get:PathSensitive(PathSensitivity.RELATIVE) - abstract val spigotServerDir: DirectoryProperty - - @get:InputDirectory - @get:PathSensitive(PathSensitivity.RELATIVE) - abstract val spigotApiDir: DirectoryProperty - - @get:Optional - @get:InputFile - @get:PathSensitive(PathSensitivity.NONE) - abstract val additionalAts: RegularFileProperty - - @get:OutputFile - abstract val generatedAt: RegularFileProperty - - @get:OutputFile - abstract val sourcesOutputZip: RegularFileProperty - - @get:OutputFile - abstract val testsOutputZip: RegularFileProperty - - @get:Internal - abstract val jvmargs: ListProperty - - @get:Inject - abstract val workerExecutor: WorkerExecutor - - @get:OutputFile - abstract val spigotRecompiledClasses: RegularFileProperty - - @get:Input - abstract val sourceCompatibility: Property - - override fun init() { - super.init() - - jvmargs.convention(listOf("-Xmx2G")) - sourcesOutputZip.convention(defaultOutput("$name-sources", "jar")) - testsOutputZip.convention(defaultOutput("$name-tests", "jar")) - generatedAt.convention(defaultOutput("at")) - spigotRecompiledClasses.convention(defaultOutput("spigotRecompiledClasses", "txt")) - sourceCompatibility.convention(21) - } - - @TaskAction - fun run() { - val srcOut = findOutputDir(sourcesOutputZip.path).apply { createDirectories() } - val testOut = findOutputDir(testsOutputZip.path).apply { createDirectories() } - - try { - val queue = workerExecutor.processIsolation { - forkOptions.jvmArgs(jvmargs.get()) - forkOptions.executable(launcher.get().executablePath.path.absolutePathString()) - } - - val srcDir = spigotServerDir.path.resolve("src/main/java") - - // Remap sources - queue.submit(RemapAction::class) { - classpath.from(vanillaRemappedSpigotJar.path) - classpath.from(mojangMappedVanillaJar.path) - classpath.from(vanillaJar.path) - classpath.from(spigotApiDir.dir("src/main/java").path) - classpath.from(spigotDeps.files.filter { it.toPath().isLibraryJar }) - additionalAts.set(this@RemapSources.additionalAts.pathOrNull) - - mappings.set(this@RemapSources.mappings.path) - inputDir.set(srcDir) - - cacheDir.set(this@RemapSources.layout.cache) - - outputDir.set(srcOut) - generatedAtOutput.set(generatedAt.path) - - sourceCompat.set(sourceCompatibility.orNull) - } - - val testSrc = spigotServerDir.path.resolve("src/test/java") - - // Remap tests - queue.submit(RemapAction::class) { - classpath.from(vanillaRemappedSpigotJar.path) - classpath.from(mojangMappedVanillaJar.path) - classpath.from(vanillaJar.path) - classpath.from(spigotApiDir.dir("src/main/java").path) - classpath.from(spigotDeps.files.filter { it.toPath().isLibraryJar }) - classpath.from(srcDir) - additionalAts.set(this@RemapSources.additionalAts.pathOrNull) - - mappings.set(this@RemapSources.mappings.path) - inputDir.set(testSrc) - - cacheDir.set(this@RemapSources.layout.cache) - - outputDir.set(testOut) - - sourceCompat.set(sourceCompatibility.orNull) - } - - queue.await() - - zip(srcOut, sourcesOutputZip) - zip(testOut, testsOutputZip) - - writeSpigotRecompiledFiles(srcOut) - } finally { - srcOut.deleteRecursive() - testOut.deleteRecursive() - } - } - - private fun writeSpigotRecompiledFiles(srcOut: Path) { - // Write list of java files spigot recompiles - val spigotRecompiled = Files.walk(srcOut).use { stream -> - stream.asSequence().mapNotNull { - if (!it.isRegularFile()) { - return@mapNotNull null - } - if (!it.fileName.pathString.endsWith(".java")) { - return@mapNotNull null - } - val path = srcOut.relativize(it).pathString - if (!path.startsWith("net/minecraft")) { - return@mapNotNull null - } - path.replace(".java", "") - }.sorted().joinToString("\n") - } - spigotRecompiledClasses.path.parent.createDirectories() - spigotRecompiledClasses.path.writeText(spigotRecompiled) - } - - abstract class RemapAction : WorkAction { - override fun execute() { - val mappingSet = MappingFormats.TINY.read( - parameters.mappings.path, - SPIGOT_NAMESPACE, - DEOBF_NAMESPACE - ) - - val additionalAt = parameters.additionalAts.pathOrNull?.let { AccessTransformFormats.FML.read(it) } - - val processAt = AccessTransformSet.create() - val generatedAtOutPath = parameters.generatedAtOutput.pathOrNull - - // Remap any references Spigot maps to mojmap+yarn - Mercury().let { merc -> - merc.sourceCompatibility = parameters.sourceCompat.map { it.toString() }.orNull ?: JavaCore.VERSION_17 - merc.isGracefulClasspathChecks = true - merc.classPath.addAll(parameters.classpath.map { it.toPath() }) - - if (generatedAtOutPath != null) { - merc.processors += AccessAnalyzerProcessor.create(processAt, mappingSet) - } - - merc.process(parameters.inputDir.path) - - val tempOut = Files.createTempDirectory(parameters.cacheDir.path, "remap") - try { - merc.processors.clear() - merc.processors.addAll( - listOf( - ExplicitThisAdder, - MercuryRemapper.create(mappingSet), - AccessTransformerRewriter.create(processAt) - ) - ) - - if (generatedAtOutPath != null) { - merc.processors.add(AccessTransformerRewriter.create(processAt)) - } - - merc.rewrite(parameters.inputDir.path, tempOut) - - if (additionalAt != null) { - merc.processors.clear() - merc.processors += AccessTransformerRewriter.create(additionalAt) - - merc.rewrite(tempOut, parameters.outputDir.path) - } else { - tempOut.copyRecursivelyTo(parameters.outputDir.path) - } - } finally { - tempOut.deleteRecursive() - } - } - - if (generatedAtOutPath != null) { - AccessTransformFormats.FML.writeLF(generatedAtOutPath, processAt) - } - } - } - - interface RemapParams : WorkParameters { - val classpath: ConfigurableFileCollection - val mappings: RegularFileProperty - val inputDir: RegularFileProperty - val additionalAts: RegularFileProperty - - val cacheDir: RegularFileProperty - val generatedAtOutput: RegularFileProperty - val outputDir: RegularFileProperty - - val sourceCompat: Property - } - - object ExplicitThisAdder : SourceRewriter { - - override fun getFlags(): Int = SourceProcessor.FLAG_RESOLVE_BINDINGS - - override fun rewrite(context: RewriteContext) { - context.compilationUnit.accept(ExplicitThisAdderVisitor(context)) - } - } - - class ExplicitThisAdderVisitor(private val context: RewriteContext) : ASTVisitor() { - - override fun visit(node: SimpleName): Boolean { - val binding = node.resolveBinding() ?: return false - - val name = when (val declaringNode = context.compilationUnit.findDeclaringNode(binding)) { - is VariableDeclarationFragment -> declaringNode.name - is MethodDeclaration -> declaringNode.name - null -> null - else -> return false - } - if (name != null && name === node) { - // this is the actual declaration - return false - } - - visit(node, binding) - return false - } - - private fun visit(node: SimpleName, binding: IBinding) { - if (binding.kind != IBinding.VARIABLE && binding.kind != IBinding.METHOD) { - return - } - - val referringClass = when (binding) { - is IVariableBinding -> { - if (!binding.isField || binding.isEnumConstant) { - return - } - binding.declaringClass - } - is IMethodBinding -> { - if (binding.isConstructor || binding.isSynthetic) { - return - } - binding.declaringClass - } - else -> return - } - val modifiers = when (binding) { - is IVariableBinding -> binding.modifiers - is IMethodBinding -> binding.modifiers - else -> return - } - - when (val p = node.parent) { - is FieldAccess, is SuperFieldAccess, is ThisExpression, is MethodReference, is SuperMethodInvocation, is MemberValuePair -> return - is MethodInvocation -> { - if (!p.arguments().contains(node)) { - if (p.expression != null && p.expression !== node) { - return - } - } - } - is QualifiedName -> { - if (p.qualifier !== node) { - return - } - } - is ClassInstanceCreation -> { - if (!p.arguments().contains(node)) { - return - } - } - } - - val rewrite = context.createASTRewrite() - val fieldAccess = rewrite.ast.newFieldAccess() - - val expr: Expression = if (!Modifier.isStatic(modifiers)) { - val accessible = mutableListOf() - var curr: ASTNode = node - while (true) { - if (curr is TypeDeclaration) { - accessible += curr.resolveBinding() ?: break - } else if (curr is AnonymousClassDeclaration) { - accessible += curr.resolveBinding() ?: break - } - val m = when (curr) { - is MethodDeclaration -> curr.modifiers - is FieldDeclaration -> curr.modifiers - is Initializer -> curr.modifiers - is TypeDeclaration -> curr.modifiers - else -> null - } - if (m != null && Modifier.isStatic(m)) { - break - } - curr = curr.parent ?: break - } - - rewrite.ast.newThisExpression().also { thisExpr -> - if (accessible.size == 1) { - return@also - } - val accessibleTargetCls = accessible.find { referringClass.isCastCompatible(it) } - ?: return@also - if (accessibleTargetCls.isAnonymous) { - if (accessible.indexOf(accessibleTargetCls) == 0) { - return@also - } - return - } - - if (!accessibleTargetCls.isCastCompatible(accessible[0])) { - val name = getNameNode(accessibleTargetCls) - ?: throw PaperweightException("Could not find name node for ${accessibleTargetCls.qualifiedName}") - thisExpr.qualifier = rewrite.createCopyTarget(name) as Name - } - } - } else { - // find declaring method - var parentNode: ASTNode? = node - loop@ while (parentNode != null) { - when (parentNode) { - is MethodDeclaration, is AnonymousClassDeclaration, is LambdaExpression, is Initializer -> break@loop - } - parentNode = parentNode.parent - } - - if (parentNode is Initializer && Modifier.isStatic(parentNode.modifiers)) { - // Can't provide explicit static receiver here - return - } - val name = getNameNode(referringClass) ?: return - rewrite.createCopyTarget(name) as Name - } - - fieldAccess.expression = expr - fieldAccess.name = rewrite.createMoveTarget(node) as SimpleName - - rewrite.replace(node, fieldAccess, null) - } - - private fun getNameNode(dec: ITypeBinding): Name? { - val typeDec = context.compilationUnit.findDeclaringNode(dec) as? TypeDeclaration ?: return null - return typeDec.name - } - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/PatchSourceRemapWorker.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/PatchSourceRemapWorker.kt deleted file mode 100644 index 3839966c0..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/PatchSourceRemapWorker.kt +++ /dev/null @@ -1,78 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks.patchremap - -import io.papermc.paperweight.util.* -import io.papermc.paperweight.util.constants.* -import java.nio.file.Path -import kotlin.io.path.* -import org.cadixdev.at.AccessTransformSet -import org.cadixdev.lorenz.MappingSet -import org.cadixdev.mercury.Mercury -import org.cadixdev.mercury.at.AccessTransformerRewriter -import org.cadixdev.mercury.remapper.MercuryRemapper - -class PatchSourceRemapWorker( - mappings: MappingSet, - ats: AccessTransformSet, - classpath: Collection, - private val inputDir: Path, - private val outputDir: Path -) { - - private val merc: Mercury = Mercury() - - init { - merc.classPath.addAll(classpath) - - merc.processors.addAll( - listOf( - MercuryRemapper.create(mappings), - AccessTransformerRewriter.create(ats) - ) - ) - - merc.isGracefulClasspathChecks = true - } - - fun remap() { - setup() - - println("mapping to $DEOBF_NAMESPACE") - - merc.rewrite(inputDir, outputDir) - - cleanup() - } - - private fun setup() { - outputDir.deleteRecursive() - outputDir.createDirectories() - } - - private fun cleanup() { - inputDir.deleteRecursive() - outputDir.moveTo(inputDir) - outputDir.deleteRecursive() - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/RemapPatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/RemapPatches.kt deleted file mode 100644 index 2fbad8254..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/RemapPatches.kt +++ /dev/null @@ -1,296 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks.patchremap - -import io.papermc.paperweight.tasks.* -import io.papermc.paperweight.util.* -import io.papermc.paperweight.util.constants.* -import java.nio.file.Path -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.DirectoryProperty -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.Property -import org.gradle.api.provider.ProviderFactory -import org.gradle.api.tasks.Classpath -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction -import org.gradle.api.tasks.options.Option -import org.gradle.kotlin.dsl.* - -abstract class RemapPatches : BaseTask() { - - @get:InputDirectory - abstract val inputPatchDir: DirectoryProperty - - @get:InputDirectory - abstract val apiPatchDir: DirectoryProperty - - @get:InputFile - abstract val mappingsFile: RegularFileProperty - - @get:InputFile - abstract val ats: RegularFileProperty - - @get:Classpath - abstract val classpathJars: ConfigurableFileCollection - - @get:InputDirectory - abstract val spigotApiDir: DirectoryProperty - - @get:InputDirectory - abstract val spigotServerDir: DirectoryProperty - - @get:InputFile - abstract val spigotDecompJar: RegularFileProperty - - @get:InputDirectory - abstract val mcLibrarySourcesDir: DirectoryProperty - - @get:InputFile - abstract val devImports: RegularFileProperty - - @get:Input - abstract val ignoreGitIgnore: Property - - @get:OutputDirectory - abstract val outputPatchDir: DirectoryProperty - - @get:Internal - @get:Option( - option = "continue-remap", - description = "For resuming, don't recreate remap dir and pick up where last run left off" - ) - abstract val continueRemapping: Property - - @get:Internal - @get:Option( - option = "limit-patches", - description = "For testing, you can limit the # of patches (e.g. --limit-patches=10)" - ) - abstract val limitPatches: Property - - @get:Inject - abstract val providers: ProviderFactory - - override fun init() { - continueRemapping.convention(false) - ignoreGitIgnore.convention(Git.ignoreProperty(providers)).finalizeValueOnRead() - } - - @TaskAction - fun run() { - val metaFile = layout.cache / "paperweight" / "remap-meta" - val meta = if (metaFile.exists()) { - if (continueRemapping.get()) { - gson.fromJson(metaFile) - } else { - metaFile.deleteForcefully() - null - } - } else { - null - } - - // Check patches - val inputElements = inputPatchDir.path.listDirectoryEntries().sorted() - if (inputElements.any { it.isRegularFile() }) { - println("Remap patch input directory must only contain directories or patch files, not both") - return - } - if (inputElements.size == 1) { - println("No patches to remap, only 1 patch set found") - return - } - - val patchesToSkip = inputElements.dropLast(1).flatMap { it.listDirectoryEntries("*.patch").sorted() } - val patchesToRemap = inputElements.last().listDirectoryEntries("*.patch").sorted() - - if (patchesToRemap.isEmpty()) { - println("No input patches to remap found") - return - } - - val limit = limitPatches.map { it.toInt() }.orElse(patchesToRemap.size).get() - - val mappings = MappingFormats.TINY.read(mappingsFile.path, SPIGOT_NAMESPACE, DEOBF_NAMESPACE) - - // This should pull in any libraries needed for type bindings - val configFiles = project.project(":Paper-Server").configurations["runtimeClasspath"].resolve().map { it.toPath() } - val classpathFiles = classpathJars.map { it.toPath() } + configFiles - - // Remap output directory, after each output this directory will be re-named to the input directory below for - // the next remap operation - println("setting up repo") - val tempApiDir = createWorkDir("patch-remap-api", source = spigotApiDir.path, recreate = !continueRemapping.get()) - val tempInputDir = createWorkDirByCloning( - "patch-remap-input", - source = spigotServerDir.path, - recreate = !continueRemapping.get() - ) - val tempOutputDir = createWorkDir("patch-remap-output") - - val sourceInputDir = tempInputDir.resolve("src/main/java") - - PatchSourceRemapWorker( - mappings, - AccessTransformFormats.FML.read(ats.path), - listOf(*classpathFiles.toTypedArray(), tempApiDir.resolve("src/main/java")), - sourceInputDir, - tempOutputDir - ).let { remapper -> - val patchApplier = PatchApplier("remapped", "old", ignoreGitIgnore.get(), tempInputDir) - - if (!continueRemapping.get()) { - // first run - patchApplier.createBranches() - - // We need to include any missing classes for the patches later on - McDev.importMcDev( - patches = patchesToSkip + patchesToRemap, - decompJar = spigotDecompJar.path, - importsFile = devImports.path, - targetDir = tempInputDir.resolve("src/main/java"), - librariesDirs = listOf(mcLibrarySourcesDir.path) - ) - - patchApplier.commitPlain("McDev imports") - } - - if (meta == null || meta.stage == RemapStage.PRE_REMAP) { - var foundResume = false - val patchesToApply = patchesToSkip.dropWhile { patch -> - when { - meta == null -> false - meta.patchSet == patch.parent.name && meta.patchName == patch.name -> { - foundResume = true - true - } - else -> !foundResume - } - } - println("Applying ${patchesToApply.size} patches before remapping") - for (patch in patchesToApply) { - metaFile.deleteForcefully() - metaFile.bufferedWriter().use { writer -> - gson.toJson(RemapMeta(RemapStage.PRE_REMAP, patch.parent.name, patch.name), writer) - } - patchApplier.applyPatch(patch) - } - - patchApplier.checkoutRemapped() // Switch to remapped branch without checking out files - - remapper.remap() // Remap to new mappings - patchApplier.commitInitialRemappedSource() // Initial commit of pre-remap sources mapped to new mappings - patchApplier.checkoutOld() // Normal checkout back to pre-remap mappings branch - } else if (patchApplier.isUnfinishedPatch()) { - println("===========================") - println("Finishing current patch") - println("===========================") - patchApplier.recordCommit() - patchApplier.checkoutRemapped() - remapper.remap() - patchApplier.commitChanges() - patchApplier.checkoutOld() - println("===========================") - println("done with current patch") - println("===========================") - } - - // Repo setup is done, we can begin the patch loop now - var counter = 0 - var remapSkip = meta != null && meta.stage == RemapStage.REMAP - for (patch in patchesToRemap) { - if (remapSkip && meta != null) { - if (meta.patchSet == patch.parent.name && meta.patchName == patch.name) { - remapSkip = false - continue - } - continue - } - - metaFile.deleteForcefully() - metaFile.bufferedWriter().use { writer -> - gson.toJson(RemapMeta(RemapStage.REMAP, patch.parent.name, patch.name), writer) - } - - println("===========================") - println("attempting to remap $patch") - println("===========================") - patchApplier.applyPatch(patch) // Apply patch on Spigot mappings - patchApplier.recordCommit() // Keep track of commit author, message, and time - patchApplier.checkoutRemapped() // Switch to remapped branch without checkout out files - remapper.remap() // Remap to new mappings - patchApplier.commitChanges() // Commit the changes - patchApplier.checkoutOld() // Normal checkout back to Spigot mappings branch - println("===========================") - println("done remapping patch $patch") - println("===========================") - - counter++ - if (counter >= limit) { - break - } - } - patchApplier.generatePatches(outputPatchDir.path) - } - } - - private fun createWorkDir(name: String, source: Path? = null, recreate: Boolean = true): Path { - return layout.cache.resolve("paperweight").resolve(name).apply { - if (recreate) { - deleteRecursive() - createDirectories() - source?.copyRecursivelyTo(this) - } - } - } - - private fun createWorkDirByCloning(name: String, source: Path, recreate: Boolean = true): Path { - val workDir = layout.cache.resolve("paperweight") - return workDir.resolve(name).apply { - if (recreate) { - deleteRecursive() - createDirectories() - Git(workDir)("clone", source.absolutePathString(), this.absolutePathString()).executeSilently() - } - } - } - - data class RemapMeta( - val stage: RemapStage, - val patchSet: String, - val patchName: String - ) - - enum class RemapStage { - PRE_REMAP, - REMAP - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/PaperAt.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/PaperAt.kt deleted file mode 100644 index 6ea4008ab..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/PaperAt.kt +++ /dev/null @@ -1,88 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.util - -import java.nio.file.Path -import org.cadixdev.at.io.AccessTransformFormats -import org.cadixdev.mercury.Mercury -import org.cadixdev.mercury.at.AccessTransformerRewriter -import org.gradle.api.file.ConfigurableFileCollection -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.file.RegularFileProperty -import org.gradle.kotlin.dsl.* -import org.gradle.workers.WorkAction -import org.gradle.workers.WorkParameters -import org.gradle.workers.WorkerExecutor - -object PaperAt { - - fun apply(workerExecutor: WorkerExecutor, apiDir: Path, serverDir: Path, atFile: Path?) { - if (atFile == null) { - return - } - - val queue = workerExecutor.processIsolation { - forkOptions.jvmArgs("-Xmx2G") - } - - val srcDir = serverDir.resolve("src/main/java") - - // Remap sources - queue.submit(AtAction::class) { - classpath.from(apiDir.resolve("src/main/java")) - - inputDir.set(srcDir) - outputDir.set(srcDir) - ats.set(atFile) - } - - queue.await() - } - - interface AtParams : WorkParameters { - val classpath: ConfigurableFileCollection - val inputDir: DirectoryProperty - val outputDir: DirectoryProperty - val ats: RegularFileProperty - } - - abstract class AtAction : WorkAction { - override fun execute() { - Mercury().let { merc -> - merc.classPath.addAll(parameters.classpath.map { it.toPath() }) - merc.isGracefulClasspathChecks = true - - merc.process(parameters.inputDir.path) - - merc.processors.clear() - merc.processors.addAll( - listOf( - AccessTransformerRewriter.create(AccessTransformFormats.FML.read(parameters.ats.path)) - ) - ) - - merc.rewrite(parameters.inputDir.path, parameters.outputDir.path) - } - } - } -} From 61eab47803ef62b14bc605c4430215893d68ea4d Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sat, 7 Dec 2024 18:55:28 -0700 Subject: [PATCH 21/38] Remove more legacy code --- .../paperweight/core/PaperweightCore.kt | 19 +- .../core/extension/CraftBukkitExtension.kt | 60 ---- .../extension/PaperweightCoreExtension.kt | 9 +- .../core/extension/SpigotExtension.kt | 11 +- .../core/taskcontainers/GeneralTasks.kt | 5 - .../core/taskcontainers/SpigotTasks.kt | 88 ----- .../taskcontainers/DevBundleTasks.kt | 3 - .../tasks/AddAdditionalSpigotMappings.kt | 70 ---- .../tasks/ApplyCraftBukkitPatches.kt | 157 -------- .../paperweight/tasks/ApplyPaperPatches.kt | 181 ---------- .../paperweight/tasks/ApplyRawDiffPatches.kt | 69 ---- .../tasks/CleanupSourceMappings.kt | 336 ------------------ .../paperweight/tasks/FilterPatchedFiles.kt | 161 --------- .../paperweight/tasks/FilterSpigotExcludes.kt | 55 --- .../papermc/paperweight/tasks/LineMapJar.kt | 225 ------------ .../io/papermc/paperweight/tasks/MacheTask.kt | 83 ----- .../paperweight/tasks/RemapAccessTransform.kt | 62 ---- .../paperweight/tasks/RemapJarAtlas.kt | 113 ------ .../paperweight/tasks/SetupMcLibraries.kt | 59 --- .../paperweight/tasks/SpigotDecompileJar.kt | 99 ------ .../paperweight/tasks/download-task.kt | 235 ------------ .../tasks/patchremap/PatchApplier.kt | 124 ------- .../paperweight/util/ClassNameChange.kt | 25 -- .../papermc/paperweight/util/MakeMcDevSrc.kt | 63 ---- .../papermc/paperweight/util/project-util.kt | 134 ------- .../paperweight/patcher/PaperweightPatcher.kt | 7 +- .../patcher/tasks/PatcherApplyGitPatches.kt | 2 +- 27 files changed, 6 insertions(+), 2449 deletions(-) delete mode 100644 paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/CraftBukkitExtension.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/AddAdditionalSpigotMappings.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyCraftBukkitPatches.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyPaperPatches.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyRawDiffPatches.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CleanupSourceMappings.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/FilterPatchedFiles.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/FilterSpigotExcludes.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/LineMapJar.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MacheTask.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapAccessTransform.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapJarAtlas.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/SetupMcLibraries.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/SpigotDecompileJar.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/PatchApplier.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/ClassNameChange.kt delete mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/MakeMcDevSrc.kt diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt index 55a11769d..e6d07585a 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt @@ -36,7 +36,6 @@ import org.gradle.api.Project import org.gradle.api.logging.Logging import org.gradle.api.tasks.Delete import org.gradle.api.tasks.bundling.AbstractArchiveTask -import org.gradle.api.tasks.bundling.Zip import org.gradle.kotlin.dsl.* class PaperweightCore : Plugin { @@ -61,15 +60,7 @@ class PaperweightCore : Plugin { delete(target.layout.cache) } - if (!ext.softSpoon.get()) { - // Make sure the submodules are initialized, since there are files there - // which are required for configuration - target.layout.maybeInitSubmodules(target.offlineMode(), logger) - } - - target.configurations.create(PARAM_MAPPINGS_CONFIG) target.configurations.create(REMAPPER_CONFIG) - target.configurations.create(DECOMPILER_CONFIG) target.configurations.create(PAPERCLIP_CONFIG) target.configurations.create(MACHE_CONFIG) { attributes.attribute(MacheOutput.ATTRIBUTE, target.objects.named(MacheOutput.ZIP)) @@ -156,18 +147,10 @@ class PaperweightCore : Plugin { target.repositories { if (!ext.softSpoon.get()) { - maven(ext.paramMappingsRepo) { - name = PARAM_MAPPINGS_REPO_NAME - content { onlyForConfigurations(PARAM_MAPPINGS_CONFIG) } - } maven(ext.remapRepo) { name = REMAPPER_REPO_NAME content { onlyForConfigurations(REMAPPER_CONFIG) } } - maven(ext.decompileRepo) { - name = DECOMPILER_REPO_NAME - content { onlyForConfigurations(DECOMPILER_CONFIG) } - } } else { maven(ext.macheRepo) { name = MACHE_REPO_NAME @@ -181,6 +164,7 @@ class PaperweightCore : Plugin { return@afterEvaluate } + /* // Setup the server jar val cache = target.layout.cache @@ -194,7 +178,6 @@ class PaperweightCore : Plugin { inputJar.set(serverJar.flatMap { it.archiveFile }) } - /* val (includeMappings, reobfJar) = serverProj.setupServerProject( target, tasks.lineMapJar.flatMap { it.outputJar }, diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/CraftBukkitExtension.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/CraftBukkitExtension.kt deleted file mode 100644 index 7e93fc067..000000000 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/CraftBukkitExtension.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.core.extension - -import io.papermc.paperweight.util.* -import kotlin.io.path.* -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.model.ObjectFactory - -open class CraftBukkitExtension(objects: ObjectFactory, workDir: DirectoryProperty) { - - val bukkitDir: DirectoryProperty = objects.dirFrom(workDir, "Bukkit") - val craftBukkitDir: DirectoryProperty = objects.dirFrom(workDir, "CraftBukkit") - val patchDir: DirectoryProperty = objects.dirFrom(craftBukkitDir, "nms-patches") - - @Suppress("MemberVisibilityCanBePrivate") - val buildDataDir: DirectoryProperty = objects.dirFrom(workDir, "BuildData") - val buildDataInfo: RegularFileProperty = objects.fileFrom(buildDataDir, "info.json") - val mappingsDir: DirectoryProperty = objects.dirFrom(buildDataDir, "mappings") - val excludesFile: RegularFileProperty = objects.bukkitFileFrom(mappingsDir, "exclude") - val atFile: RegularFileProperty = objects.bukkitFileFrom(mappingsDir, "at") - - @Suppress("MemberVisibilityCanBePrivate") - val buildDataBinDir: DirectoryProperty = objects.dirFrom(buildDataDir, "bin") - val fernFlowerJar: RegularFileProperty = objects.fileFrom(buildDataBinDir, "fernflower.jar") - val specialSourceJar: RegularFileProperty = objects.fileFrom(buildDataBinDir, "SpecialSource.jar") - val specialSource2Jar: RegularFileProperty = objects.fileFrom(buildDataBinDir, "SpecialSource-2.jar") - - private fun ObjectFactory.bukkitFileFrom(base: DirectoryProperty, extension: String): RegularFileProperty = fileProperty().convention( - base.flatMap { dir -> - val file = dir.path.useDirectoryEntries { it.filter { f -> f.name.endsWith(extension) }.singleOrNull() } - if (file != null) { - mappingsDir.file(file.name) - } else { - fileProperty() - } - } - ) -} diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt index 0a005cfb3..35af2691b 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt @@ -62,16 +62,9 @@ open class PaperweightCoreExtension(project: Project, objects: ObjectFactory, la listOf("/*.class", "/net/minecraft/**", "/com/mojang/math/**") ) - @Suppress("MemberVisibilityCanBePrivate") - val craftBukkit = CraftBukkitExtension(objects, workDir) - val spigot = SpigotExtension(objects, workDir) + val spigot = SpigotExtension(objects) val paper = PaperExtension(objects, layout) - @Suppress("unused") - fun craftBukkit(action: Action) { - action.execute(craftBukkit) - } - @Suppress("unused") fun spigot(action: Action) { action.execute(spigot) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/SpigotExtension.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/SpigotExtension.kt index c0bcfd77f..84b9f693e 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/SpigotExtension.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/SpigotExtension.kt @@ -22,21 +22,12 @@ package io.papermc.paperweight.core.extension -import io.papermc.paperweight.util.* -import org.gradle.api.file.DirectoryProperty import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Property import org.gradle.kotlin.dsl.* -open class SpigotExtension(objects: ObjectFactory, workDir: DirectoryProperty) { +open class SpigotExtension(objects: ObjectFactory) { val buildDataRef: Property = objects.property() val packageVersion: Property = objects.property() - - @Suppress("MemberVisibilityCanBePrivate") - val spigotDir: DirectoryProperty = objects.dirFrom(workDir, "Spigot") - val spigotApiDir: DirectoryProperty = objects.dirFrom(spigotDir, "Spigot-API") - val spigotServerDir: DirectoryProperty = objects.dirFrom(spigotDir, "Spigot-Server") - val bukkitPatchDir: DirectoryProperty = objects.dirFrom(spigotDir, "Bukkit-Patches") - val craftBukkitPatchDir: DirectoryProperty = objects.dirFrom(spigotDir, "CraftBukkit-Patches") } diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt index 6c7d19ec4..0f2370b5d 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt @@ -37,11 +37,6 @@ open class GeneralTasks( extension: PaperweightCoreExtension = project.ext, ) : InitialTasks(project) { - // Configuration won't necessarily always run, so do it as the first task when it's needed as well - val initSubmodules by tasks.registering { - offlineMode.set(project.offlineMode()) - } - val filterVanillaJar by tasks.registering { inputJar.set(extractFromBundler.flatMap { it.serverJar }) includes.set(extension.vanillaJarIncludes) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt index 05f5ecf54..88f986331 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt @@ -22,8 +22,6 @@ package io.papermc.paperweight.core.taskcontainers -import com.github.salomonbrys.kotson.fromJson -import io.papermc.paperweight.DownloadService import io.papermc.paperweight.core.ext import io.papermc.paperweight.core.extension.PaperweightCoreExtension import io.papermc.paperweight.tasks.* @@ -31,7 +29,6 @@ import io.papermc.paperweight.util.* import io.papermc.paperweight.util.constants.* import java.nio.file.Path import org.gradle.api.Project -import org.gradle.api.Task import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskContainer import org.gradle.kotlin.dsl.* @@ -42,7 +39,6 @@ open class SpigotTasks( tasks: TaskContainer = project.tasks, cache: Path = project.layout.cache, extension: PaperweightCoreExtension = project.ext, - downloadService: Provider = project.download, ) : VanillaTasks(project) { val cloneSpigotBuildData by tasks.registering { @@ -58,12 +54,6 @@ open class SpigotTasks( .flatMap { it.buildDataInfoFile } .map { gson.fromJson(it.path) } - val addAdditionalSpigotMappings by tasks.registering { - dependsOn(initSubmodules) - classSrg.set(extension.craftBukkit.mappingsDir.file(buildDataInfo.map { it.classMappings })) - additionalClassEntriesSrg.set(extension.paper.additionalSpigotClassMappings.fileExists(project)) - } - val generateSpigotMappings by tasks.registering { classMappings.set(unpackSpigotBuildData.flatMap { it.classMappings }) @@ -113,84 +103,6 @@ open class SpigotTasks( outputMappings.set(cache.resolve(PATCHED_SPIGOT_MOJANG_YARN_MAPPINGS)) } - val cleanupSourceMappings by tasks.registering { - sourceJar.set(spigotRemapJar.flatMap { it.outputJar }) - libraries.from(extractFromBundler.map { it.serverLibraryJars.asFileTree }) - inputMappings.set(patchMappings.flatMap { it.outputMappings }) - - outputMappings.set(cache.resolve(PATCHED_SPIGOT_MOJANG_YARN_SOURCE_MAPPINGS)) - } - - val filterSpigotExcludes by tasks.registering { - inputZip.set(spigotRemapJar.flatMap { it.outputJar }) - excludesFile.set(unpackSpigotBuildData.flatMap { it.excludesFile }) - } - - val spigotDecompileJar by tasks.registering { - inputJar.set(filterSpigotExcludes.flatMap { it.outputZip }) - fernFlowerJar.set(extension.craftBukkit.fernFlowerJar) - decompileCommand.set(buildDataInfo.map { it.decompileCommand }) - } - - val patchCraftBukkitPatches by tasks.registering { - dependsOn(initSubmodules) - inputDir.set(extension.craftBukkit.patchDir) - patchDir.set(extension.paper.craftBukkitPatchPatchesDir.fileExists(project)) - } - - val patchCraftBukkit by tasks.registering { - sourceJar.set(spigotDecompileJar.flatMap { it.outputJar }) - cleanDirPath.set("net/minecraft") - branch.set("patched") - patchZip.set(patchCraftBukkitPatches.flatMap { it.outputZip }) - craftBukkitDir.set(extension.craftBukkit.craftBukkitDir) - } - - val patchSpigotApiPatches by tasks.registering { - dependsOn(initSubmodules) - inputDir.set(extension.spigot.bukkitPatchDir) - patchDir.set(extension.paper.spigotApiPatchPatchesDir.fileExists(project)) - } - - val patchSpigotServerPatches by tasks.registering { - dependsOn(initSubmodules) - inputDir.set(extension.spigot.craftBukkitPatchDir) - patchDir.set(extension.paper.spigotServerPatchPatchesDir.fileExists(project)) - } - - val patchSpigotApi by tasks.registering { - branch.set("HEAD") - upstreamBranch.set("upstream") - upstream.set(extension.craftBukkit.bukkitDir) - patchZip.set(patchSpigotApiPatches.flatMap { it.outputZip }) - - outputDir.set(extension.spigot.spigotApiDir) - } - - val patchSpigotServer by tasks.registering { - branch.set("HEAD") - upstreamBranch.set("upstream") - upstream.set(patchCraftBukkit.flatMap { it.outputDir }) - patchZip.set(patchSpigotServerPatches.flatMap { it.outputZip }) - - outputDir.set(extension.spigot.spigotServerDir) - } - - val patchSpigot by tasks.registering { - dependsOn(patchSpigotApi, patchSpigotServer) - } - - val downloadSpigotDependencies by tasks.registering { - dependsOn(patchSpigot) - apiPom.set(patchSpigotApi.flatMap { it.outputDir.file("pom.xml") }) - serverPom.set(patchSpigotServer.flatMap { it.outputDir.file("pom.xml") }) - mcLibrariesFile.set(extractFromBundler.flatMap { it.serverLibrariesTxt }) - outputDir.set(cache.resolve(SPIGOT_JARS_PATH)) - outputSourcesDir.set(cache.resolve(SPIGOT_SOURCES_JARS_PATH)) - - downloader.set(downloadService) - } - val remapSpigotAt by tasks.registering { inputJar.set(spigotRemapJar.flatMap { it.outputJar }) mapping.set(patchMappings.flatMap { it.outputMappings }) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt index 48f60a911..4c10273ad 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt @@ -53,9 +53,6 @@ class DevBundleTasks( val generateDevelopmentBundle by tasks.registering { group = "paperweight" - remapperConfig.set(project.configurations.named(REMAPPER_CONFIG)) - decompilerConfig.set(project.configurations.named(DECOMPILER_CONFIG)) - devBundleFile.set(project.layout.buildDirectory.file("libs/paperweight-development-bundle-${project.version}.zip")) ignoreUnsupportedEnvironment.set(project.providers.gradleProperty(GenerateDevBundle.unsupportedEnvironmentPropName).map { it.toBoolean() }) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/AddAdditionalSpigotMappings.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/AddAdditionalSpigotMappings.kt deleted file mode 100644 index 87c7b53b9..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/AddAdditionalSpigotMappings.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks - -import io.papermc.paperweight.util.* -import java.nio.file.Path -import kotlin.io.path.* -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.tasks.CacheableTask -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.Optional -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.PathSensitive -import org.gradle.api.tasks.PathSensitivity -import org.gradle.api.tasks.TaskAction - -@CacheableTask -abstract class AddAdditionalSpigotMappings : BaseTask() { - - @get:InputFile - @get:PathSensitive(PathSensitivity.NONE) - abstract val classSrg: RegularFileProperty - - @get:Optional - @get:InputFile - @get:PathSensitive(PathSensitivity.NONE) - abstract val additionalClassEntriesSrg: RegularFileProperty - - @get:OutputFile - abstract val outputClassSrg: RegularFileProperty - - override fun init() { - outputClassSrg.convention(defaultOutput("class.csrg")) - } - - @TaskAction - fun run() { - addLines(classSrg.path, additionalClassEntriesSrg.pathOrNull, outputClassSrg.path) - } - - private fun addLines(inFile: Path, appendFile: Path?, outputFile: Path) { - val lines = mutableListOf() - inFile.useLines { seq -> seq.forEach { line -> lines += line } } - appendFile?.useLines { seq -> seq.forEach { lines.add(it) } } - lines.sort() - outputFile.bufferedWriter().use { writer -> - lines.forEach { writer.appendLine(it) } - } - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyCraftBukkitPatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyCraftBukkitPatches.kt deleted file mode 100644 index 08a31ea95..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyCraftBukkitPatches.kt +++ /dev/null @@ -1,157 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks - -import io.papermc.paperweight.PaperweightException -import io.papermc.paperweight.util.* -import java.nio.file.Files -import java.nio.file.Path -import java.util.Date -import javax.inject.Inject -import kotlin.io.path.* -import kotlin.streams.asSequence -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.Property -import org.gradle.api.provider.ProviderFactory -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.Optional -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction - -abstract class ApplyCraftBukkitPatches : ControllableOutputTask() { - - @get:InputFile - abstract val sourceJar: RegularFileProperty - - @get:Input - abstract val cleanDirPath: Property - - @get:Optional - @get:InputDirectory - abstract val patchDir: DirectoryProperty - - @get:Optional - @get:InputFile - abstract val patchZip: RegularFileProperty - - @get:Input - abstract val branch: Property - - @get:Input - abstract val ignoreGitIgnore: Property - - @get:InputDirectory - abstract val craftBukkitDir: DirectoryProperty - - @get:OutputDirectory - abstract val outputDir: DirectoryProperty - - @get:Inject - abstract val providers: ProviderFactory - - override fun init() { - printOutput.convention(false) - ignoreGitIgnore.convention(Git.ignoreProperty(providers)).finalizeValueOnRead() - outputDir.convention(project, defaultOutput("repo").path) - } - - @TaskAction - fun run() { - Git.checkForGit() - - outputDir.path.deleteRecursive() - outputDir.path.parent.let { - it.createDirectories() - val git = Git(it) - git("clone", "--no-hardlinks", craftBukkitDir.path.absolutePathString(), outputDir.path.absolutePathString()).setupOut().execute() - } - - val git = Git(outputDir.path) - - val basePatchDirFile = outputDir.path.resolve("src/main/java") - basePatchDirFile.resolve(cleanDirPath.get()).deleteRecursive() - - val patchSource = patchDir.pathOrNull ?: patchZip.path // used for error messages - val rootPatchDir = patchDir.pathOrNull ?: patchZip.path.let { unzip(it, findOutputDir(it)) } - - try { - if (!rootPatchDir.isDirectory()) { - throw PaperweightException("Patch directory does not exist $patchSource") - } - - val patchList = Files.walk(rootPatchDir).use { it.asSequence().filter { file -> file.isRegularFile() }.toSet() } - if (patchList.isEmpty()) { - throw PaperweightException("No patch files found in $patchSource") - } - - // Copy in patch targets - sourceJar.path.openZip().use { fs -> - for (file in patchList) { - val javaName = javaFileName(rootPatchDir, file) - val out = basePatchDirFile.resolve(javaName) - val sourcePath = fs.getPath(javaName) - - out.parent.createDirectories() - sourcePath.copyTo(out) - } - } - - git(*Git.add(ignoreGitIgnore, "src")).setupOut().execute() - git("commit", "-m", "Vanilla $ ${Date()}", "--author=Vanilla ").setupOut().execute() - - // Apply patches - for (file in patchList) { - val javaName = javaFileName(rootPatchDir, file) - - if (printOutput.get()) { - println("Patching ${javaName.removeSuffix(".java")}") - } - - val dirPrefix = basePatchDirFile.relativeTo(outputDir.path).invariantSeparatorsPathString - git("apply", "--ignore-whitespace", "--directory=$dirPrefix", file.absolutePathString()).setupOut().execute() - } - - git(*Git.add(ignoreGitIgnore, "src")).setupOut().execute() - git("commit", "-m", "CraftBukkit $ ${Date()}", "--author=CraftBukkit ").setupOut().execute() - } finally { - if (rootPatchDir != patchDir.pathOrNull) { - rootPatchDir.deleteRecursive() - } - } - } - - private fun javaFileName(rootDir: Path, file: Path): String { - return file.relativeTo(rootDir).toString().replaceAfterLast('.', "java") - } - - private fun Command.setupOut() = apply { - if (printOutput.get()) { - setup(System.out, System.err) - } else { - setup(UselessOutputStream, UselessOutputStream) - } - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyPaperPatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyPaperPatches.kt deleted file mode 100644 index 6f1904e67..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyPaperPatches.kt +++ /dev/null @@ -1,181 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks - -import com.github.salomonbrys.kotson.fromJson -import io.papermc.paperweight.util.* -import io.papermc.paperweight.util.constants.* -import java.nio.file.Path -import javax.inject.Inject -import kotlin.io.path.* -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.ListProperty -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.InputFile -import org.gradle.api.tasks.Optional -import org.gradle.api.tasks.OutputDirectory -import org.gradle.api.tasks.TaskAction - -abstract class ApplyPaperPatches : ControllableOutputTask() { - - @get:InputDirectory - abstract val patchDir: DirectoryProperty - - @get:InputFile - abstract val remappedSource: RegularFileProperty - - @get:InputFile - abstract val remappedTests: RegularFileProperty - - @get:InputFile - abstract val caseOnlyClassNameChanges: RegularFileProperty - - @get:InputDirectory - abstract val upstreamDir: DirectoryProperty - - @get:Input - abstract val upstreamBranch: Property - - @get:InputFile - abstract val sourceMcDevJar: RegularFileProperty - - @get:InputDirectory - abstract val mcLibrariesDir: DirectoryProperty - - @get:InputDirectory - abstract val spigotLibrariesDir: DirectoryProperty - - @get:Optional - @get:InputFile - abstract val devImports: RegularFileProperty - - @get:Optional - @get:Input - abstract val unneededFiles: ListProperty - - @get:Input - abstract val ignoreGitIgnore: Property - - @get:OutputDirectory - abstract val outputDir: DirectoryProperty - - @get:Inject - abstract val providers: ProviderFactory - - @get:OutputDirectory - abstract val mcDevSources: DirectoryProperty - - @get:Input - abstract val verbose: Property - - override fun init() { - upstreamBranch.convention("master") - ignoreGitIgnore.convention(Git.ignoreProperty(providers)).finalizeValueOnRead() - verbose.convention(providers.verboseApplyPatches()) - } - - @TaskAction - fun runLocking() { - val lockFile = layout.cache.resolve(applyPatchesLock(outputDir.path)) - acquireProcessLockWaiting(lockFile) - try { - run() - } finally { - lockFile.deleteForcefully() - } - } - - private fun run() { - Git.checkForGit() - - val outputFile = outputDir.path - recreateCloneDirectory(outputFile) - - val target = outputFile.name - - if (printOutput.get()) { - logger.lifecycle("Creating $target from remapped source...") - } - - Git(outputFile).let { git -> - checkoutRepoFromUpstream(git, upstreamDir.path, upstreamBranch.get()) - - val sourceDir = createDir(outputDir.path.resolve("src/main/java")) - val mcDataDir = outputDir.path.resolve("src/main/resources") - val testDir = createDir(outputDir.path.resolve("src/test/java")) - - fs.copy { - from(archives.zipTree(remappedSource.path)) - into(sourceDir) - } - fs.copy { - from(archives.zipTree(remappedTests.path)) - into(testDir) - } - - val patches = patchDir.path.listDirectoryEntries("*.patch") - McDev.importMcDev( - patches = patches, - decompJar = sourceMcDevJar.path, - importsFile = devImports.pathOrNull, - targetDir = sourceDir, - dataTargetDir = mcDataDir, - librariesDirs = listOf(spigotLibrariesDir.path, mcLibrariesDir.path), - printOutput = printOutput.get() - ) - - val caseOnlyChanges = caseOnlyClassNameChanges.path.bufferedReader(Charsets.UTF_8).use { reader -> - gson.fromJson>(reader) - } - - for (caseOnlyChange in caseOnlyChanges) { - val obfFile = sourceDir.resolve(caseOnlyChange.obfName + ".java").relativeTo(outputFile) - val deobfFile = sourceDir.resolve(caseOnlyChange.deobfName + ".java").relativeTo(outputFile) - git("mv", "-f", obfFile.toString(), deobfFile.toString()).runSilently(silenceErr = true) - } - - unneededFiles.orNull?.forEach { path -> outputFile.resolve(path).deleteRecursive() } - - git(*Git.add(ignoreGitIgnore, ".")).executeSilently() - git("commit", "-m", "Initial", "--author=Initial Source ").executeSilently() - git("tag", "-d", "base").runSilently(silenceErr = true) - git("tag", "base").executeSilently() - - try { - applyGitPatches(git, target, outputFile, patchDir.path, printOutput.get(), verbose.get()) - } finally { - makeMcDevSrc(layout.cache, sourceMcDevJar.path, mcDevSources.path, outputDir.path, sourceDir, mcDataDir) - } - } - } - - private fun createDir(dir: Path): Path { - dir.deleteRecursive() - dir.createDirectories() - return dir - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyRawDiffPatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyRawDiffPatches.kt deleted file mode 100644 index 6ee9f7ef4..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/ApplyRawDiffPatches.kt +++ /dev/null @@ -1,69 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks - -import io.papermc.paperweight.util.* -import java.nio.file.Path -import kotlin.io.path.* -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.tasks.CacheableTask -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.Optional -import org.gradle.api.tasks.PathSensitive -import org.gradle.api.tasks.PathSensitivity - -@CacheableTask -abstract class ApplyRawDiffPatches : ZippedTask() { - - @get:InputDirectory - @get:PathSensitive(PathSensitivity.RELATIVE) - abstract val inputDir: DirectoryProperty - - @get:Optional - @get:InputDirectory - @get:PathSensitive(PathSensitivity.RELATIVE) - abstract val patchDir: DirectoryProperty - - override fun init() { - super.init() - outputZip.convention(defaultOutput("zip")) - } - - override fun run(rootDir: Path) { - Git.checkForGit() - - val input = inputDir.path - input.copyRecursivelyTo(rootDir) - - val patches = patchDir.pathOrNull ?: return - val patchSet = patches.useDirectoryEntries("*.patch") { it.toMutableList() } - - patchSet.sort() - - val git = Git(rootDir) - - for (patch in patchSet) { - git("apply", patch.absolutePathString()).executeOut() - } - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CleanupSourceMappings.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CleanupSourceMappings.kt deleted file mode 100644 index b784d3e3c..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CleanupSourceMappings.kt +++ /dev/null @@ -1,336 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks - -import dev.denwav.hypo.asm.AsmClassDataProvider -import dev.denwav.hypo.asm.hydrate.BridgeMethodHydrator -import dev.denwav.hypo.asm.hydrate.SuperConstructorHydrator -import dev.denwav.hypo.core.HypoContext -import dev.denwav.hypo.hydrate.HydrationManager -import dev.denwav.hypo.mappings.ChangeChain -import dev.denwav.hypo.mappings.ChangeRegistry -import dev.denwav.hypo.mappings.ClassMappingsChange -import dev.denwav.hypo.mappings.LorenzUtil -import dev.denwav.hypo.mappings.MappingsCompletionManager -import dev.denwav.hypo.mappings.MergeResult -import dev.denwav.hypo.mappings.MergeableMappingsChange -import dev.denwav.hypo.mappings.changes.AbstractMappingsChange -import dev.denwav.hypo.mappings.changes.MemberReference -import dev.denwav.hypo.mappings.changes.RemoveMappingChange -import dev.denwav.hypo.mappings.contributors.ChangeContributor -import dev.denwav.hypo.model.ClassProviderRoot -import dev.denwav.hypo.model.data.ClassData -import dev.denwav.hypo.model.data.types.PrimitiveType -import io.papermc.paperweight.util.* -import io.papermc.paperweight.util.constants.* -import java.util.Collections -import javax.inject.Inject -import kotlin.io.path.* -import org.cadixdev.lorenz.MappingSet -import org.cadixdev.lorenz.model.ClassMapping -import org.cadixdev.lorenz.model.TopLevelClassMapping -import org.gradle.api.file.ConfigurableFileCollection -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.ListProperty -import org.gradle.api.tasks.* -import org.gradle.kotlin.dsl.* -import org.gradle.workers.WorkAction -import org.gradle.workers.WorkParameters -import org.gradle.workers.WorkerExecutor - -@CacheableTask -abstract class CleanupSourceMappings : JavaLauncherTask() { - - @get:Classpath - abstract val sourceJar: RegularFileProperty - - @get:CompileClasspath - abstract val libraries: ConfigurableFileCollection - - @get:InputFile - @get:PathSensitive(PathSensitivity.NONE) - abstract val inputMappings: RegularFileProperty - - @get:OutputFile - abstract val outputMappings: RegularFileProperty - - @get:OutputFile - abstract val caseOnlyNameChanges: RegularFileProperty - - @get:Internal - abstract val jvmargs: ListProperty - - @get:Inject - abstract val workerExecutor: WorkerExecutor - - override fun init() { - super.init() - - jvmargs.convention(listOf("-Xmx1G")) - caseOnlyNameChanges.convention(defaultOutput("caseOnlyClassNameChanges", "json")) - } - - @TaskAction - fun run() { - val queue = workerExecutor.processIsolation { - forkOptions.jvmArgs(jvmargs.get()) - forkOptions.executable(launcher.get().executablePath.path.absolutePathString()) - } - - queue.submit(CleanupSourceMappingsAction::class) { - inputMappings.set(this@CleanupSourceMappings.inputMappings.path) - libraries.from(this@CleanupSourceMappings.libraries.files) - sourceJar.set(this@CleanupSourceMappings.sourceJar.path) - - outputMappings.set(this@CleanupSourceMappings.outputMappings.path) - caseOnlyNameChanges.set(this@CleanupSourceMappings.caseOnlyNameChanges.path) - } - } - - object ParamIndexesForSource : ChangeContributor { - - override fun contribute(currentClass: ClassData?, classMapping: ClassMapping<*, *>?, context: HypoContext, registry: ChangeRegistry) { - if (currentClass == null || classMapping == null) { - return - } - - for (methodMapping in classMapping.methodMappings) { - val method = LorenzUtil.findMethod(currentClass, methodMapping) ?: continue - - var methodRef: MemberReference? = null - - var lvtIndex = if (method.isStatic) 0 else 1 - if (method.isConstructor && currentClass.outerClass() != null && !currentClass.isStaticInnerClass) { - lvtIndex += 1 - } - for ((sourceIndex, param) in method.params().withIndex()) { - if (methodMapping.hasParameterMapping(lvtIndex)) { - if (methodRef == null) { - methodRef = MemberReference.of(methodMapping) - } - registry.submitChange(ParamIndexChange(methodRef, lvtIndex, sourceIndex)) - } - lvtIndex++ - if (param === PrimitiveType.LONG || param === PrimitiveType.DOUBLE) { - lvtIndex++ - } - } - } - } - - override fun name(): String = "ParamIndexesForSource" - - class ParamIndexChange( - target: MemberReference, - fromIndex: Int, - toIndex: Int - ) : AbstractMappingsChange(target), MergeableMappingsChange { - - private val indexMap: MutableMap = HashMap() - - init { - indexMap[fromIndex] = toIndex - } - - override fun applyChange(input: MappingSet, ref: MemberReference) { - val classMapping = input.getOrCreateClassMapping(ref.className()) - val methodMapping = classMapping.getOrCreateMethodMapping(ref.name(), ref.desc()) - - val paramsMap = LorenzUtil.getParamsMap(methodMapping) - val params = paramsMap.values.toList() - paramsMap.clear() - - for (param in params) { - methodMapping.createParameterMapping(indexMap[param.index] ?: param.index, param.deobfuscatedName) - } - } - - override fun mergeWith(that: ParamIndexChange): MergeResult { - for (fromIndex in this.indexMap.keys) { - if (that.indexMap.containsKey(fromIndex)) { - return MergeResult.failure("Cannot merge 2 param mappings changes with matching fromIndexes") - } - } - for (toIndex in this.indexMap.values) { - if (that.indexMap.containsValue(toIndex)) { - return MergeResult.failure("Cannot merge 2 param mappings changes with matching toIndex") - } - } - - this.indexMap += that.indexMap - return MergeResult.success(this) - } - - override fun toString(): String { - return "Move param mappings for ${target()} for index pairs [${indexMap.entries.joinToString(", ") { "${it.key}:${it.value}" }}]" - } - } - } - - object RemoveLambdaMappings : ChangeContributor { - - override fun contribute(currentClass: ClassData?, classMapping: ClassMapping<*, *>?, context: HypoContext, registry: ChangeRegistry) { - if (currentClass == null || classMapping == null) { - return - } - - for (methodMapping in classMapping.methodMappings) { - if (methodMapping.deobfuscatedName.startsWith("lambda$")) { - registry.submitChange(RemoveMappingChange.of(MemberReference.of(methodMapping))) - } - } - } - - override fun name(): String = "RemoveLambdaMappings" - } - - class FindCaseOnlyClassNameChanges(private val changes: MutableList) : ChangeContributor { - override fun contribute(currentClass: ClassData?, classMapping: ClassMapping<*, *>?, context: HypoContext, registry: ChangeRegistry) { - if (classMapping !is TopLevelClassMapping) { - return - } - val obfName = classMapping.obfuscatedName - val deobfName = classMapping.deobfuscatedName - - if (obfName != deobfName && obfName.equals(deobfName, ignoreCase = true)) { - changes += ClassNameChange(obfName, deobfName) - } - } - - override fun name(): String = "FindCaseOnlyClassNameChanges" - } - - class ChangeObfClassName( - private val targetClass: String, - private val newFullObfuscatedName: String - ) : ClassMappingsChange { - override fun targetClass(): String = targetClass - - override fun applyChange(input: MappingSet) { - val classMapping = LorenzUtil.getClassMapping(input, targetClass) ?: return - LorenzUtil.removeClassMapping(classMapping) - - val newMap = input.getOrCreateClassMapping(newFullObfuscatedName) - copyMapping(classMapping, newMap) - } - - private fun copyMapping(from: ClassMapping<*, *>, to: ClassMapping<*, *>) { - to.deobfuscatedName = from.deobfuscatedName - - for (methodMapping in from.methodMappings) { - methodMapping.copy(to) - } - for (fieldMapping in from.fieldMappings) { - fieldMapping.copy(to) - } - for (innerClassMapping in from.innerClassMappings) { - innerClassMapping.copy(to) - } - } - } - - companion object { - const val TEMP_SUFFIX = "paperweight-remove-anon-renames-temp-suffix" - } - - object RemoveAnonymousClassRenames : ChangeContributor { - override fun contribute(currentClass: ClassData?, classMapping: ClassMapping<*, *>?, context: HypoContext, registry: ChangeRegistry) { - if (classMapping == null) return - - val obf = classMapping.obfuscatedName.toIntOrNull() - val deobf = classMapping.deobfuscatedName.toIntOrNull() - - if (obf != null && deobf != null && obf != deobf) { - val newName = classMapping.fullObfuscatedName.substringBeforeLast('$') + '$' + classMapping.deobfuscatedName + TEMP_SUFFIX - registry.submitChange(ChangeObfClassName(classMapping.fullObfuscatedName, newName)) - } - } - - override fun name(): String = "RemoveAnonymousClassRenames" - } - - object CleanupAfterRemoveAnonymousClassRenames : ChangeContributor { - override fun contribute(currentClass: ClassData?, classMapping: ClassMapping<*, *>?, context: HypoContext, registry: ChangeRegistry) { - if (classMapping == null) return - - if (classMapping.fullObfuscatedName.endsWith(TEMP_SUFFIX)) { - val newName = classMapping.fullObfuscatedName.substringBefore(TEMP_SUFFIX) - registry.submitChange(ChangeObfClassName(classMapping.fullObfuscatedName, newName)) - } - } - - override fun name(): String = "CleanupAfterRemoveAnonymousClassRenames" - } - - abstract class CleanupSourceMappingsAction : WorkAction { - - interface Parameters : WorkParameters { - val inputMappings: RegularFileProperty - val libraries: ConfigurableFileCollection - val sourceJar: RegularFileProperty - - val outputMappings: RegularFileProperty - val caseOnlyNameChanges: RegularFileProperty - } - - override fun execute() { - val mappings = MappingFormats.TINY.read( - parameters.inputMappings.path, - SPIGOT_NAMESPACE, - DEOBF_NAMESPACE - ) - - val caseOnlyChanges = Collections.synchronizedList(mutableListOf()) - - val cleanedMappings = HypoContext.builder() - .withProvider(AsmClassDataProvider.of(ClassProviderRoot.fromJar(parameters.sourceJar.path))) - .withContextProvider(AsmClassDataProvider.of(parameters.libraries.toJarClassProviderRoots())) - .withContextProvider(AsmClassDataProvider.of(ClassProviderRoot.ofJdk())) - .build().use { hypoContext -> - HydrationManager.createDefault() - .register(BridgeMethodHydrator.create()) - .register(SuperConstructorHydrator.create()) - .hydrate(hypoContext) - - ChangeChain.create() - .addLink(RemoveLambdaMappings) - .addLink(ParamIndexesForSource) - .addLink(FindCaseOnlyClassNameChanges(caseOnlyChanges)) - .addLink(RemoveAnonymousClassRenames) - .addLink(CleanupAfterRemoveAnonymousClassRenames) - .applyChain(mappings, MappingsCompletionManager.create(hypoContext)) - } - - MappingFormats.TINY.write( - cleanedMappings, - parameters.outputMappings.path, - SPIGOT_NAMESPACE, - DEOBF_NAMESPACE - ) - - parameters.caseOnlyNameChanges.path.bufferedWriter(Charsets.UTF_8).use { writer -> - gson.toJson(caseOnlyChanges, writer) - } - } - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/FilterPatchedFiles.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/FilterPatchedFiles.kt deleted file mode 100644 index 6f2789544..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/FilterPatchedFiles.kt +++ /dev/null @@ -1,161 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks - -import io.papermc.paperweight.util.* -import java.nio.file.Files -import java.nio.file.Path -import java.util.stream.Collectors -import kotlin.io.path.* -import org.gradle.api.file.DirectoryProperty -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.tasks.InputDirectory -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.TaskAction -import org.gradle.work.ChangeType -import org.gradle.work.Incremental -import org.gradle.work.InputChanges - -abstract class FilterPatchedFiles : BaseTask() { - - @get:InputDirectory - @get:Incremental - abstract val inputSrcDir: DirectoryProperty - - @get:InputDirectory - @get:Incremental - abstract val inputResourcesDir: DirectoryProperty - - @get:InputFile - abstract val vanillaJar: RegularFileProperty - - @get:OutputFile - abstract val outputJar: RegularFileProperty - - override fun init() { - outputJar.convention(defaultOutput()) - } - - @TaskAction - fun run(changes: InputChanges) { - if (!changes.isIncremental) { - return runFull() - } - val srcAdded = changes.added(inputSrcDir) - val srcRemoved = changes.removed(inputSrcDir) - val resourceAdded = changes.added(inputResourcesDir) - val resourceRemoved = changes.removed(inputResourcesDir) - if (srcAdded.isEmpty() && srcRemoved.isEmpty() && resourceAdded.isEmpty() && resourceRemoved.isEmpty()) { - logger.info("No adds or removes, not doing work.") - didWork = false - return - } - vanillaJar.path.openZip().use { vanillaFs -> - val vanillaRoot = vanillaFs.rootDirectories.single() - outputJar.path.openZip().use { outputFs -> - val outputRoot = outputFs.rootDirectories.single() - - for (add in resourceAdded) { - if (vanillaRoot.resolve(add).exists()) { - outputRoot.resolve(add).deleteIfExists() - } - } - for (del in resourceRemoved) { - val vanilla = vanillaRoot.resolve(del) - if (vanilla.exists()) { - val out = outputRoot.resolve(del) - out.parent.createDirectories() - out.deleteIfExists() - vanilla.copyTo(out) - } - } - - for (add in srcAdded) { - val p = add.removeSuffix(".java") + ".class" - val vanilla = vanillaRoot.resolve(p) - if (vanilla.exists()) { - val outFile = outputRoot.resolve(p) - val outDir = outFile.parent - val paths = outDir.listDirectoryEntries("${vanilla.name.removeSuffix(".class")}$*.class").toMutableList() - paths.add(outFile) - paths.forEach { it.deleteIfExists() } - } - } - for (del in srcRemoved) { - val p = del.removeSuffix(".java") + ".class" - val vanillaFile = vanillaRoot.resolve(p) - if (vanillaFile.exists()) { - val paths = vanillaFile.parent.listDirectoryEntries("${vanillaFile.name.removeSuffix(".class")}$*.class").toMutableList() - paths.add(vanillaFile) - paths.forEach { - val out = outputRoot.resolve(it.relativeTo(vanillaRoot)) - out.parent.createDirectories() - out.deleteIfExists() - it.copyTo(out) - } - } - } - } - } - } - - private fun runFull() { - val srcFiles = collectFiles(inputSrcDir.path) - val resourceFiles = collectFiles(inputResourcesDir.path) - filterJar( - vanillaJar.path, - outputJar.path, - listOf() - ) { - if (!it.isRegularFile()) { - false - } else if (it.nameCount > 1) { - val path = it.subpath(0, it.nameCount - 1).resolve(it.fileName.toString().split("$")[0].removeSuffix(".class")).toString() - !srcFiles.contains("$path.java") && !resourceFiles.contains(path) - } else { - true - } - } - } - - private fun collectFiles(dir: Path): Set { - return Files.walk(dir).use { stream -> - stream.filter { it.isRegularFile() } - .map { it.relativeTo(dir).invariantSeparatorsPathString } - .collect(Collectors.toUnmodifiableSet()) - } - } - - private fun InputChanges.added(baseDir: DirectoryProperty): Set { - return getFileChanges(baseDir).filter { it.changeType == ChangeType.ADDED } - .map { it.file.toPath().relativeTo(baseDir.path).invariantSeparatorsPathString } - .toSet() - } - - private fun InputChanges.removed(baseDir: DirectoryProperty): Set { - return getFileChanges(baseDir).filter { it.changeType == ChangeType.REMOVED } - .map { it.file.toPath().relativeTo(baseDir.path).invariantSeparatorsPathString } - .toSet() - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/FilterSpigotExcludes.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/FilterSpigotExcludes.kt deleted file mode 100644 index 8cfec0e28..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/FilterSpigotExcludes.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks - -import io.papermc.paperweight.util.* -import java.nio.file.Path -import kotlin.io.path.* -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.tasks.CacheableTask -import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.PathSensitive -import org.gradle.api.tasks.PathSensitivity - -/** - * Because Spigot doesn't remap all classes, there are class and package name clashes if we don't do this in the source - * remap step. Other than that, we don't need this jar - */ -@CacheableTask -abstract class FilterSpigotExcludes : ZippedTask() { - - @get:InputFile - @get:PathSensitive(PathSensitivity.NONE) - abstract val excludesFile: RegularFileProperty - - override fun run(rootDir: Path) { - excludesFile.path.useLines { lines -> - for (line in lines) { - if (line.startsWith('#') || line.isBlank()) { - continue - } - rootDir.resolve("$line.class").deleteForcefully() - } - } - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/LineMapJar.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/LineMapJar.kt deleted file mode 100644 index 3a3bdc030..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/LineMapJar.kt +++ /dev/null @@ -1,225 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks - -import io.papermc.paperweight.PaperweightException -import io.papermc.paperweight.util.* -import java.nio.ByteBuffer -import java.nio.ByteOrder -import java.nio.file.Path -import java.util.NavigableMap -import java.util.TreeMap -import java.util.zip.ZipEntry -import java.util.zip.ZipInputStream -import javax.inject.Inject -import kotlin.collections.set -import kotlin.io.path.* -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.Internal -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.TaskAction -import org.gradle.jvm.toolchain.JavaLauncher -import org.gradle.kotlin.dsl.* -import org.gradle.workers.WorkAction -import org.gradle.workers.WorkParameters -import org.gradle.workers.WorkQueue -import org.gradle.workers.WorkerExecutor -import org.objectweb.asm.ClassVisitor -import org.objectweb.asm.Label -import org.objectweb.asm.MethodVisitor -import org.objectweb.asm.Opcodes -import org.objectweb.asm.tree.ClassNode - -@CacheableTask -abstract class LineMapJar : JavaLauncherTask() { - @get:Classpath - abstract val inputJar: RegularFileProperty - - @get:OutputFile - abstract val outputJar: RegularFileProperty - - @get:Classpath - abstract val decompiledJar: RegularFileProperty - - @get:Internal - abstract val jvmArgs: ListProperty - - @get:Inject - abstract val workerExecutor: WorkerExecutor - - override fun init() { - super.init() - - jvmArgs.convention(listOf("-Xmx512m")) - outputJar.convention(defaultOutput()) - } - - @TaskAction - fun run() { - lineMapJar( - workerExecutor = workerExecutor, - jvmArgs = jvmArgs.get(), - launcher = launcher.get(), - inputJarPath = inputJar.path, - outputJarPath = outputJar.path, - decompileJarPath = decompiledJar.path - ) - } -} - -fun lineMapJar( - workerExecutor: WorkerExecutor, - jvmArgs: List = arrayListOf("-Xmx512m"), - launcher: JavaLauncher, - inputJarPath: Path, - outputJarPath: Path, - decompileJarPath: Path, -): WorkQueue { - ensureParentExists(outputJarPath) - ensureDeleted(outputJarPath) - - val queue = workerExecutor.processIsolation { - forkOptions.jvmArgs(jvmArgs) - forkOptions.executable(launcher.executablePath.path.absolutePathString()) - } - - queue.submit(LineMapJarAction::class) { - inputJar.set(inputJarPath) - outputJar.set(outputJarPath) - decompileJar.set(decompileJarPath) - } - - return queue -} - -private abstract class LineMapJarAction : WorkAction { - interface Parameters : WorkParameters { - val inputJar: RegularFileProperty - val outputJar: RegularFileProperty - val decompileJar: RegularFileProperty - } - - override fun execute() { - val lineMap = readLineMap(parameters.decompileJar.path) - parameters.outputJar.path.writeZip().use { out -> - parameters.inputJar.path.openZip().use { jarFile -> - JarProcessing.processJar(jarFile, out, LineMappingClassProcessor(lineMap)) - } - } - } - - class LineMappingClassProcessor(private val lineMap: Map>) : JarProcessing.ClassProcessor.VisitorBased { - override fun processClass(node: ClassNode, parent: ClassVisitor, classNodeCache: ClassNodeCache): ClassVisitor? { - val map = lineMap[node.name.substringBefore('$')] - ?: return null // No line maps for class? - return LineMappingVisitor(parent, map) - } - - override fun shouldProcess(file: Path): Boolean { - val name = file.toString() - .substring(1) // remove leading / - .substringBefore(".class") - .substringBefore('$') - return name in lineMap - } - } -} - -private class LineMappingVisitor( - parent: ClassVisitor?, - private val lineMapping: NavigableMap -) : ClassVisitor(Opcodes.ASM9, parent) { - override fun visitMethod( - access: Int, - name: String, - descriptor: String, - signature: String?, - exceptions: Array? - ): MethodVisitor = - MethodLineFixer(super.visitMethod(access, name, descriptor, signature, exceptions), lineMapping) - - private class MethodLineFixer( - parent: MethodVisitor?, - private val lineMapping: NavigableMap - ) : MethodVisitor(Opcodes.ASM9, parent) { - override fun visitLineNumber(line: Int, start: Label?) { - var mapped = lineMapping[line] - if (mapped == null) { - val entry = lineMapping.ceilingEntry(line) - if (entry != null) { - mapped = entry.value - } - } - super.visitLineNumber(mapped ?: line, start) - } - } -} - -private fun readLineMap(decompileJar: Path): Map> { - val classes: MutableMap> = HashMap() - try { - decompileJar.inputStream().use { fis -> - ZipInputStream(fis).use { zip -> - var entry: ZipEntry? = zip.nextEntry - while (entry != null) { - val extra: ByteArray? = entry.extra - if (extra == null || !entry.name.endsWith(".java")) { - entry = zip.nextEntry - continue - } - val buf: ByteBuffer = ByteBuffer.wrap(extra) - buf.order(ByteOrder.LITTLE_ENDIAN) - while (buf.hasRemaining()) { - val id: Short = buf.short - val len: Short = buf.short - if (id.toInt() == 0x4646) { // FF - val cls: String = entry.name.substring(0, entry.name.length - 5) - val ver: Byte = buf.get() - if (ver != 1.toByte()) { - throw PaperweightException("Wrong FF code line version for " + entry.name + " (got $ver, expected 1)") - } - val count = (len - 1) / 4 - val lines: NavigableMap = TreeMap() - for (x in 0 until count) { - val oldLine: Int = buf.short.toInt() - val newLine: Int = buf.short.toInt() - lines[oldLine] = newLine - } - classes[cls] = lines - } else { - buf.position(buf.position() + len) - } - } - - entry = zip.nextEntry - } - } - } - } catch (ex: Exception) { - throw PaperweightException("Could not read line maps from decompiled jar: $decompileJar", ex) - } - return classes -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MacheTask.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MacheTask.kt deleted file mode 100644 index d00a9a702..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/MacheTask.kt +++ /dev/null @@ -1,83 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks - -import io.papermc.paperweight.util.* -import 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(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) - // } - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapAccessTransform.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapAccessTransform.kt deleted file mode 100644 index dd9e70e9a..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapAccessTransform.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks - -import io.papermc.paperweight.util.* -import io.papermc.paperweight.util.constants.* -import org.cadixdev.at.io.AccessTransformFormats -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.tasks.CacheableTask -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 - -@CacheableTask -abstract class RemapAccessTransform : BaseTask() { - - @get:InputFile - @get:PathSensitive(PathSensitivity.NONE) - abstract val inputFile: RegularFileProperty - - @get:InputFile - @get:PathSensitive(PathSensitivity.NONE) - abstract val mappings: RegularFileProperty - - @get:OutputFile - abstract val outputFile: RegularFileProperty - - override fun init() { - outputFile.convention(defaultOutput("at")) - } - - @TaskAction - fun run() { - val at = AccessTransformFormats.FML.read(inputFile.path) - val mappingSet = MappingFormats.TINY.read(mappings.path, SPIGOT_NAMESPACE, DEOBF_NAMESPACE) - - val resultAt = at.remap(mappingSet) - AccessTransformFormats.FML.writeLF(outputFile.path, resultAt) - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapJarAtlas.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapJarAtlas.kt deleted file mode 100644 index 7dab79bda..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/RemapJarAtlas.kt +++ /dev/null @@ -1,113 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks - -import io.papermc.paperweight.util.* -import javax.inject.Inject -import kotlin.io.path.* -import org.cadixdev.atlas.Atlas -import org.cadixdev.bombe.asm.jar.JarEntryRemappingTransformer -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.ListProperty -import org.gradle.api.provider.Property -import org.gradle.api.tasks.CacheableTask -import org.gradle.api.tasks.Classpath -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.Internal -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.TaskAction -import org.gradle.kotlin.dsl.* -import org.gradle.workers.WorkAction -import org.gradle.workers.WorkParameters -import org.gradle.workers.WorkerExecutor -import org.objectweb.asm.commons.Remapper - -@CacheableTask -abstract class RemapJarAtlas : JavaLauncherTask() { - - @get:Classpath - abstract val inputJar: RegularFileProperty - - @get:Input - abstract val packageVersion: Property - - @get:OutputFile - abstract val outputJar: RegularFileProperty - - @get:Internal - abstract val jvmargs: ListProperty - - @get:Inject - abstract val workerExecutor: WorkerExecutor - - override fun init() { - super.init() - - jvmargs.convention(listOf("-Xmx1G")) - } - - @TaskAction - fun run() { - ensureParentExists(outputJar) - ensureDeleted(outputJar) - - val queue = workerExecutor.processIsolation { - forkOptions.jvmArgs(jvmargs.get()) - forkOptions.executable(launcher.get().executablePath.path.absolutePathString()) - } - - queue.submit(AtlasAction::class) { - inputJar.set(this@RemapJarAtlas.inputJar.get()) - outputJar.set(this@RemapJarAtlas.outputJar.get()) - packageVersion.set(this@RemapJarAtlas.packageVersion.get()) - } - } - - abstract class AtlasAction : WorkAction { - override fun execute() { - val oldPack = "net/minecraft" - val newPack = "$oldPack/server/v${parameters.packageVersion.get()}" - Atlas().let { atlas -> - atlas.install { JarEntryRemappingTransformer(PackageRemapper(oldPack, newPack)) } - atlas.run(parameters.inputJar.path, parameters.outputJar.path) - } - } - } - - interface AtlasParameters : WorkParameters { - val inputJar: RegularFileProperty - val outputJar: RegularFileProperty - val packageVersion: Property - } -} - -class PackageRemapper(private val oldPackage: String, private val newPackage: String) : Remapper() { - - override fun map(internalName: String): String { - return if (internalName.startsWith(oldPackage)) { - internalName.replaceBeforeLast('/', newPackage) - } else { - internalName - } - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/SetupMcLibraries.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/SetupMcLibraries.kt deleted file mode 100644 index 931b61200..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/SetupMcLibraries.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks - -import io.papermc.paperweight.util.* -import java.nio.file.Path -import kotlin.io.path.* -import org.gradle.api.DefaultTask -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.ListProperty -import org.gradle.api.tasks.CacheableTask -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.TaskAction - -@CacheableTask -abstract class SetupMcLibraries : DefaultTask() { - - @get:Input - abstract val dependencies: ListProperty - - @get:OutputFile - abstract val outputFile: RegularFileProperty - - @TaskAction - fun run() { - setupMinecraftLibraries(dependencies.get(), outputFile.path) - } -} - -fun setupMinecraftLibraries(dependencies: List, outputFile: Path) { - val list = dependencies.sorted() - - outputFile.bufferedWriter().use { writer -> - for (line in list) { - writer.appendLine(line) - } - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/SpigotDecompileJar.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/SpigotDecompileJar.kt deleted file mode 100644 index df06e05f8..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/SpigotDecompileJar.kt +++ /dev/null @@ -1,99 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks - -import io.papermc.paperweight.PaperweightException -import io.papermc.paperweight.util.* -import io.papermc.paperweight.util.constants.* -import java.util.concurrent.ThreadLocalRandom -import kotlin.io.path.* -import org.gradle.api.file.RegularFileProperty -import org.gradle.api.provider.Property -import org.gradle.api.tasks.CacheableTask -import org.gradle.api.tasks.Classpath -import org.gradle.api.tasks.Input -import org.gradle.api.tasks.OutputFile -import org.gradle.api.tasks.TaskAction - -@CacheableTask -abstract class SpigotDecompileJar : JavaLauncherTask() { - - @get:Classpath - abstract val inputJar: RegularFileProperty - - @get:Classpath - abstract val fernFlowerJar: RegularFileProperty - - @get:Input - abstract val decompileCommand: Property - - @get:OutputFile - abstract val outputJar: RegularFileProperty - - @get:Input - abstract val memory: Property - - override fun init() { - super.init() - - memory.convention("4G") - outputJar.convention(defaultOutput()) - } - - @TaskAction - fun run() { - val inputJarFile = inputJar.path - val inputJarPath = inputJarFile.absolutePathString() - - val outputJarFile = outputJar.path - val decomp = outputJarFile.resolveSibling("decomp" + ThreadLocalRandom.current().nextInt()) - - try { - try { - decomp.createDirectories() - } catch (e: Exception) { - throw PaperweightException("Failed to create output directory: $decomp", e) - } - - val cmd = decompileCommand.get().split(" ").let { it.subList(3, it.size - 2) }.toMutableList() - cmd += inputJarPath - cmd += decomp.absolutePathString() - - val logFile = layout.cache.resolve(paperTaskOutput("log")) - logFile.deleteForcefully() - - launcher.runJar( - objects.fileCollection().from(fernFlowerJar), - workingDir = layout.cache, - logFile = logFile, - jvmArgs = listOf("-Xmx${memory.get()}"), - args = cmd.toTypedArray() - ) - - ensureDeleted(outputJarFile) - decomp.resolve(inputJarFile.name).moveTo(outputJarFile) - } finally { - decomp.deleteRecursive() - } - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/download-task.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/download-task.kt index d3e02b4bb..9affe4b15 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/download-task.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/download-task.kt @@ -24,33 +24,22 @@ package io.papermc.paperweight.tasks import io.papermc.paperweight.DownloadService import io.papermc.paperweight.util.* -import io.papermc.paperweight.util.constants.* import io.papermc.paperweight.util.data.* import java.nio.file.Path import javax.inject.Inject -import javax.xml.parsers.DocumentBuilderFactory import kotlin.io.path.* import org.gradle.api.DefaultTask -import org.gradle.api.artifacts.Dependency -import org.gradle.api.artifacts.component.ComponentIdentifier -import org.gradle.api.artifacts.dsl.DependencyFactory -import org.gradle.api.attributes.java.TargetJvmEnvironment import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty -import org.gradle.api.internal.project.ProjectInternal -import org.gradle.api.internal.project.ProjectInternal.DetachedResolver import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property import org.gradle.api.provider.Provider import org.gradle.api.tasks.* import org.gradle.kotlin.dsl.* -import org.gradle.work.DisableCachingByDefault import org.gradle.workers.WorkAction import org.gradle.workers.WorkParameters import org.gradle.workers.WorkQueue import org.gradle.workers.WorkerExecutor -import org.w3c.dom.Document -import org.w3c.dom.Element // Not cached since these are Mojang's files abstract class DownloadTask : DefaultTask() { @@ -192,230 +181,6 @@ fun downloadLibraries( return queue } -@DisableCachingByDefault(because = "Gradle handles caching") -abstract class DownloadSpigotDependencies : BaseTask() { - - @get:InputFile - @get:PathSensitive(PathSensitivity.NONE) - abstract val apiPom: RegularFileProperty - - @get:InputFile - @get:PathSensitive(PathSensitivity.NONE) - abstract val serverPom: RegularFileProperty - - @get:InputFile - @get:PathSensitive(PathSensitivity.NONE) - abstract val mcLibrariesFile: RegularFileProperty - - @get:OutputDirectory - abstract val outputDir: DirectoryProperty - - @get:OutputDirectory - abstract val outputSourcesDir: DirectoryProperty - - @get:Internal - abstract val downloader: Property - - @get:Inject - abstract val workerExecutor: WorkerExecutor - - @get:Inject - abstract val dependencyFactory: DependencyFactory - - private val detachedResolver: DetachedResolver = (project as ProjectInternal).newDetachedResolver() - - @TaskAction - fun run() { - val apiSetup = parsePom(apiPom.path) - val serverSetup = parsePom(serverPom.path) - val mcLibraries = mcLibrariesFile.path.readLines() - - val out = outputDir.path - out.deleteRecursive() - - val outSources = outputSourcesDir.path - outSources.deleteRecursive() - - val spigotRepos = mutableSetOf() - spigotRepos += apiSetup.repos - spigotRepos += serverSetup.repos - - val artifacts = mutableSetOf() - artifacts += apiSetup.artifacts - artifacts += serverSetup.artifacts - - val resolver = detachedResolver - for (repo in spigotRepos) { - resolver.repositories.maven(repo) - } - val deps = mutableListOf() - for (artifact in artifacts) { - val gav = artifact.gav.let { - if (it == "com.google.guava:guava:32.1.2-jre") { - // https://github.com/google/guava/issues/6657 - "com.google.guava:guava:32.1.3-jre" - } else { - it - } - } - deps.add( - dependencyFactory.create(gav).also { - it.artifact { - artifact.classifier?.let { s -> classifier = s } - artifact.extension?.let { s -> extension = s } - } - } - ) - } - - val config = resolver.configurations.detachedConfiguration(*deps.toTypedArray()) - config.attributes { - attribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, objects.named(TargetJvmEnvironment.STANDARD_JVM)) - } - - // The source variants don't have transitives - val flatComponents = mutableSetOf() - - for (artifact in config.incoming.artifacts.artifacts) { - artifact.file.toPath().copyTo(outputDir.path.resolve(artifact.file.name).also { it.parent.createDirectories() }, true) - flatComponents += artifact.id.componentIdentifier - } - - val sourcesDeps = mutableListOf() - for (component in flatComponents) { - sourcesDeps.add( - dependencyFactory.create(component.displayName).also { - it.artifact { - classifier = "sources" - } - } - ) - } - val sourcesConfig = resolver.configurations.detachedConfiguration(*sourcesDeps.toTypedArray()) - sourcesConfig.attributes { - // Mojang libs & Guava don't resolve metadata correctly, so we set the classifier below instead... - - // attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME)) - // attribute(DocsType.DOCS_TYPE_ATTRIBUTE, objects.named(DocsType.SOURCES)) - // attribute(Bundling.BUNDLING_ATTRIBUTE, objects.named(Bundling.EXTERNAL)) - // attribute(Category.CATEGORY_ATTRIBUTE, objects.named(Category.DOCUMENTATION)) - - // Needed since we set the classifier instead of using above attributes - attribute(TargetJvmEnvironment.TARGET_JVM_ENVIRONMENT_ATTRIBUTE, objects.named(TargetJvmEnvironment.STANDARD_JVM)) - } - val sourcesView = sourcesConfig.incoming.artifactView { - componentFilter { - mcLibraries.none { l -> l == it.displayName } && - // This is only needed since we don't use variant-aware resolution properly - it.displayName != "com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava" - } - } - - for (artifact in sourcesView.artifacts.artifacts) { - artifact.file.toPath().copyTo(outputSourcesDir.path.resolve(artifact.file.name).also { it.parent.createDirectories() }, true) - } - } - - private fun parsePom(pomFile: Path): MavenSetup { - val depList = arrayListOf() - // todo dum - depList += MavenArtifact( - "com.google.code.findbugs", - "jsr305", - "3.0.2" - ) - depList += MavenArtifact( - "org.apache.logging.log4j", - "log4j-api", - "2.17.0" - ) - depList += MavenArtifact( - "org.jetbrains", - "annotations", - "23.0.0" - ) - val repoList = arrayListOf() - // Maven Central is implicit - repoList += MAVEN_CENTRAL_URL - - val builder = DocumentBuilderFactory.newInstance().newDocumentBuilder() - val doc = pomFile.inputStream().buffered().use { stream -> - stream.buffered().use { buffered -> - builder.parse(buffered) - } - } - - doc.documentElement.normalize() - - depList += doc.extractDependencies() - repoList += doc.extractRepos() - - return MavenSetup(repos = repoList, artifacts = depList) - } - - private fun Document.extractDependencies(): List { - val depList = arrayListOf() - val list = getElementsByTagName("dependencies") - val node = list.item(0) as Element // Only want the first dependencies element - val depNode = node.getElementsByTagName("dependency") - for (j in 0 until depNode.length) { - val dependency = depNode.item(j) as? Element ?: continue - val artifact = getDependency(dependency) ?: continue - depList += artifact - } - return depList - } - - private fun Document.extractRepos(): List { - val repoList = arrayListOf() - val repos = getElementsByTagName("repositories") - for (i in 0 until repos.length) { - val node = repos.item(i) as? Element ?: continue - val depNode = node.getElementsByTagName("repository") - for (j in 0 until depNode.length) { - val repo = depNode.item(j) as? Element ?: continue - val repoUrl = repo.getElementsByTagName("url").item(0).textContent - repoList += repoUrl - } - } - return repoList - } - - private fun getDependency(node: Element): MavenArtifact? { - val scopeNode = node.getElementsByTagName("scope") - val scope = if (scopeNode.length == 0) { - "compile" - } else { - scopeNode.item(0).textContent - } - - if (scope != "compile") { - return null - } - - val group = node.getElementsByTagName("groupId").item(0).textContent - val artifact = node.getElementsByTagName("artifactId").item(0).textContent - val version = node.getElementsByTagName("version").item(0).textContent - - if (version.contains("\${")) { - // Don't handle complicated things - // We don't need to (for now anyways) - return null - } - - return MavenArtifact( - group = group, - artifact = artifact, - version = version - ) - } -} - -data class MavenSetup( - val repos: List, - val artifacts: List -) - interface DownloadParams : WorkParameters { val repos: ListProperty val artifact: Property diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/PatchApplier.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/PatchApplier.kt deleted file mode 100644 index 24ddb18f0..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/patchremap/PatchApplier.kt +++ /dev/null @@ -1,124 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.tasks.patchremap - -import io.papermc.paperweight.PaperweightException -import io.papermc.paperweight.util.* -import java.nio.file.Path -import kotlin.io.path.* - -class PatchApplier( - private val remappedBranch: String, - private val unmappedBranch: String, - private val ignoreGitIgnore: Boolean, - targetDir: Path -) { - - private val git = Git(targetDir) - - private var commitMessage: String? = null - private var commitAuthor: String? = null - private var commitTime: String? = null - - private val remappedBaseTag: String = "remapped-base" - - fun checkoutRemapped() { - println("Switching to $remappedBranch without losing changes") - git("symbolic-ref", "HEAD", "refs/heads/$remappedBranch").executeSilently() - } - - fun checkoutOld() { - println("Resetting back to $unmappedBranch branch") - git("checkout", unmappedBranch).executeSilently() - } - - fun commitPlain(message: String) { - git(*Git.add(ignoreGitIgnore, ".")).executeSilently() - git("commit", "-m", message, "--author=Initial ").executeSilently() - } - - fun createBranches() { - git("checkout", "-b", unmappedBranch).executeSilently() - git("branch", remappedBranch).executeSilently() - } - - fun commitInitialRemappedSource() { - git(*Git.add(ignoreGitIgnore, ".")).executeSilently() - git("commit", "-m", "Initial Remapped Source", "--author=Initial ").executeSilently() - git("tag", remappedBaseTag).executeSilently() - } - - fun recordCommit() { - commitMessage = git("log", "--format=%B", "-n", "1", "HEAD").getText() - commitAuthor = git("log", "--format=%an <%ae>", "-n", "1", "HEAD").getText() - commitTime = git("log", "--format=%aD", "-n", "1", "HEAD").getText() - } - - private fun clearCommit() { - commitMessage = null - commitAuthor = null - commitTime = null - } - - fun commitChanges() { - println("Committing remapped changes to $remappedBranch") - val message = commitMessage ?: throw PaperweightException("commitMessage not set") - val author = commitAuthor ?: throw PaperweightException("commitAuthor not set") - val time = commitTime ?: throw PaperweightException("commitTime not set") - clearCommit() - - git(*Git.add(ignoreGitIgnore, ".")).executeSilently() - git("commit", "-m", message, "--author=$author", "--date=$time").execute() - } - - fun applyPatch(patch: Path) { - val result = git("am", "--3way", "--ignore-whitespace", patch.absolutePathString()).runOut() - if (result != 0) { - throw RuntimeException("Patch failed to apply: $patch") - } - } - - fun generatePatches(target: Path) { - target.deleteRecursive() - target.createDirectories() - git("checkout", remappedBranch).executeSilently() - git( - "format-patch", "--diff-algorith=myers", "--zero-commit", "--full-index", "--no-signature", "--no-stat", "-N", "-o", - target.absolutePathString(), remappedBaseTag - ).executeOut() - } - - fun isUnfinishedPatch(): Boolean { - if (git("branch", "--show-current").getText().trim() != unmappedBranch) { - return false - } - - git("update-index", "--refresh").executeSilently() - if (git("diff-index", "--diff-algorithm=myers", "--quiet", "HEAD", "--").runSilently() == 0) { - return git("log", unmappedBranch, "-1", "--pretty=%B").getText().trim() != - git("log", remappedBranch, "-1", "--pretty=%B").getText().trim() - } - - throw PaperweightException("Unknown state: repo has uncommitted changes") - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/ClassNameChange.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/ClassNameChange.kt deleted file mode 100644 index 76d3093bc..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/ClassNameChange.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.util - -data class ClassNameChange(val obfName: String, val deobfName: String) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/MakeMcDevSrc.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/MakeMcDevSrc.kt deleted file mode 100644 index 646fedf5a..000000000 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/MakeMcDevSrc.kt +++ /dev/null @@ -1,63 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.util - -import io.papermc.paperweight.util.constants.* -import java.nio.file.Path -import kotlin.io.path.* - -fun makeMcDevSrc( - cache: Path, - decompileJar: Path, - target: Path, - paperProject: Path, - paperSource: Path = paperProject.resolve("src/main/java"), - dataSource: Path = paperProject.resolve("src/main/resources") -) { - val lockFile = cache.resolve(applyPatchesLock(paperProject)) - val alreadyHave = acquireProcessLockWaiting(lockFile) - try { - ensureDeleted(target) - - decompileJar.openZip().use { fs -> - val root = fs.getPath("/") - fs.walk().use { stream -> - stream.forEach { sourceFile -> - if (sourceFile.isRegularFile()) { - val sourceFilePath = sourceFile.relativeTo(root).invariantSeparatorsPathString - - if (!paperSource.resolve(sourceFilePath).isRegularFile() && !dataSource.resolve(sourceFilePath).isRegularFile()) { - val targetFile = target.resolve(sourceFilePath) - targetFile.parent.createDirectories() - sourceFile.copyTo(targetFile) - } - } - } - } - } - } finally { - if (!alreadyHave) { - lockFile.deleteForcefully() - } - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt index f2d7e15f0..ccf3aeeca 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/project-util.kt @@ -22,125 +22,13 @@ package io.papermc.paperweight.util -import io.papermc.paperweight.extension.PaperweightServerExtension import io.papermc.paperweight.tasks.* import io.papermc.paperweight.util.constants.* -import java.nio.file.Path -import kotlin.io.path.* import org.gradle.api.Project -import org.gradle.api.artifacts.Configuration -import org.gradle.api.artifacts.repositories.MavenArtifactRepository -import org.gradle.api.attributes.Usage -import org.gradle.api.plugins.JavaPlugin -import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.provider.Provider -import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.bundling.AbstractArchiveTask -import org.gradle.api.tasks.bundling.Zip import org.gradle.kotlin.dsl.* -import org.gradle.plugins.ide.idea.model.IdeaModel - -fun Project.setupServerProject( - parent: Project, - remappedJar: Provider<*>, - remappedJarSources: Any, - mcDevSourceDir: Path, - libsFile: Any, - packagesToFix: Provider?>, - relocatedReobfMappings: TaskProvider, - serverJar: TaskProvider -): ServerTasks? { - if (!projectDir.exists()) { - return null - } - - plugins.apply("java") - - val serverExt = extensions.create(PAPERWEIGHT_EXTENSION, objects) - relocatedReobfMappings { - craftBukkitPackageVersion.set(serverExt.craftBukkitPackageVersion) - } - - exportRuntimeClasspathTo(parent) - - @Suppress("UNUSED_VARIABLE", "KotlinRedundantDiagnosticSuppress") - val filterPatchedFiles by tasks.registering { - inputSrcDir.set(file("src/main/java")) - inputResourcesDir.set(file("src/main/resources")) - vanillaJar.set( - // unlink dependency on upstream clone task for patcher (hack); it's implicitly handled when we get upstream data - parent.layout.file(parent.files(remappedJar).elements.map { it.single().asFile }) - ) - outputJar.set(parent.layout.cache.resolve(FINAL_FILTERED_REMAPPED_JAR)) - } - - val vanillaServer: Configuration by configurations.creating { - withDependencies { - dependencies { - // update mc-dev sources on dependency resolution - makeMcDevSrc( - parent.layout.cache, - remappedJarSources.convertToPath(), - mcDevSourceDir, - layout.projectDirectory.path - ) - - add(create(parent.files(filterPatchedFiles.flatMap { it.outputJar }))) - } - } - } - - configurations.named(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME) { - extendsFrom(vanillaServer) - withDependencies { - dependencies { - val libs = libsFile.convertToPathOrNull() - if (libs != null && libs.exists()) { - libs.forEachLine { line -> - add( - create(line) { - isTransitive = false - } - ) - } - } - } - } - } - - addMcDevSourcesRoot(mcDevSourceDir) - - error("No longer implemented") -} - -private fun Project.exportRuntimeClasspathTo(parent: Project) { - configurations.create(CONSUMABLE_RUNTIME_CLASSPATH) { - isCanBeConsumed = true - isCanBeResolved = false - attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME)) - extendsFrom(configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)) - } - parent.configurations.create(SERVER_RUNTIME_CLASSPATH) { - isCanBeConsumed = false - isCanBeResolved = true - attributes.attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME)) - } - parent.dependencies { - add(SERVER_RUNTIME_CLASSPATH, parent.dependencies.project(path, configuration = CONSUMABLE_RUNTIME_CLASSPATH)) - } - afterEvaluate { - val old = parent.repositories.toList() - parent.repositories.clear() - repositories.filterIsInstance().forEach { - parent.repositories.maven(it.url) { - name = "serverRuntimeClasspath repo ${it.url}" - content { onlyForConfigurations(SERVER_RUNTIME_CLASSPATH) } - } - } - parent.repositories.addAll(old) - } -} fun Project.createBuildTasks( craftBukkitPackageVersion: Provider, @@ -195,25 +83,3 @@ data class ServerTasks( val includeMappings: TaskProvider, val reobfJar: TaskProvider, ) - -private fun Project.addMcDevSourcesRoot(mcDevSourceDir: Path) { - plugins.apply("idea") - - val dir = mcDevSourceDir.toFile() - - extensions.getByType().sourceSets.named(SourceSet.MAIN_SOURCE_SET_NAME) { - java { - srcDirs(dir) - val pathString = dir.invariantSeparatorsPath - exclude { - it.file.absoluteFile.invariantSeparatorsPath.contains(pathString) - } - } - } - - extensions.configure { - module { - generatedSourceDirs.add(dir) - } - } -} diff --git a/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/PaperweightPatcher.kt b/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/PaperweightPatcher.kt index c48995506..49f808c6d 100644 --- a/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/PaperweightPatcher.kt +++ b/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/PaperweightPatcher.kt @@ -62,7 +62,6 @@ class PaperweightPatcher : Plugin { delete(target.layout.cache) } - target.configurations.create(DECOMPILER_CONFIG) target.configurations.create(REMAPPER_CONFIG) target.configurations.create(PAPERCLIP_CONFIG) @@ -128,10 +127,6 @@ class PaperweightPatcher : Plugin { name = REMAPPER_REPO_NAME content { onlyForConfigurations(REMAPPER_CONFIG) } } - maven(patcher.decompileRepo) { - name = DECOMPILER_REPO_NAME - content { onlyForConfigurations(DECOMPILER_CONFIG) } - } } val upstreamDataTask = upstreamDataTaskRef.get() ?: return@afterEvaluate @@ -175,6 +170,7 @@ class PaperweightPatcher : Plugin { inputJar.set(serverJar.flatMap { it.archiveFile }) } + /* val (includeMappings, reobfJar) = serverProj.setupServerProject( target, upstreamData.map { it.remappedJar }, @@ -214,6 +210,7 @@ class PaperweightPatcher : Plugin { reobfJar, upstreamData.map { it.mcVersion } ) + */ } } diff --git a/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/tasks/PatcherApplyGitPatches.kt b/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/tasks/PatcherApplyGitPatches.kt index 1aa08bcc5..49ead371d 100644 --- a/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/tasks/PatcherApplyGitPatches.kt +++ b/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/tasks/PatcherApplyGitPatches.kt @@ -164,7 +164,7 @@ abstract class PatcherApplyGitPatches : ControllableOutputTask() { try { applyGitPatches(git, target, output, patchDir.pathOrNull, printOutput.get(), verbose.get()) } finally { - makeMcDevSrc(layout.cache, sourceMcDevJar.path, mcDevSources.path, outputDir.path, srcDir, dataDir) + // makeMcDevSrc(layout.cache, sourceMcDevJar.path, mcDevSources.path, outputDir.path, srcDir, dataDir) } } } From f361b18292fea8bb9dccbf48dffb60a19828f393 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sat, 7 Dec 2024 19:06:27 -0700 Subject: [PATCH 22/38] Use java toolchain to run codebook --- .../paperweight/tasks/mache/RemapJar.kt | 60 +++++++------------ 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt index b48a98d87..7a40fc49b 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt @@ -22,19 +22,16 @@ package io.papermc.paperweight.tasks.mache +import io.papermc.paperweight.tasks.* 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() { +abstract class RemapJar : JavaLauncherTask() { @get:PathSensitive(PathSensitivity.NONE) @get:InputFile @@ -66,45 +63,32 @@ abstract class RemapJar : DefaultTask() { @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") - try { - logFile.outputStream().buffered().use { log -> - exec.javaexec { - classpath(codebookClasspath.singleFile) - - maxHeapSize = "2G" - - remapperArgs.get().forEach { arg -> - args( - arg - .replace(Regex("\\{tempDir}")) { temporaryDir.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 - } - } - } catch (e: Exception) { - throw RuntimeException("Error while running codebook, see ${logFile.pathString} for details", e) + val args = mutableListOf() + + remapperArgs.get().forEach { arg -> + args += arg + .replace(Regex("\\{tempDir}")) { temporaryDir.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 } } } + + launcher.runJar( + codebookClasspath, + temporaryDir.toPath(), + logFile, + jvmArgs = listOf("-Xmx2G"), + args = args.toTypedArray() + ) } } From 88bd5330711641f62412f218783034ca7c83338f Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sat, 7 Dec 2024 19:47:23 -0700 Subject: [PATCH 23/38] More cleanup, update source generator helper --- .../paperweight/core/PaperweightCore.kt | 26 +++----- .../core/extension/PaperExtension.kt | 14 +--- .../extension/PaperweightCoreExtension.kt | 13 +--- .../core/taskcontainers/GeneralTasks.kt | 15 +++-- .../core/taskcontainers/SoftSpoonTasks.kt | 42 +++++++----- .../core/taskcontainers/SpigotTasks.kt | 6 +- .../core/taskcontainers/VanillaTasks.kt | 65 ------------------- .../PaperweightSourceGeneratorHelper.kt | 27 ++------ ...mc.paperweight.source-generator.properties | 1 + 9 files changed, 54 insertions(+), 155 deletions(-) delete mode 100644 paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/VanillaTasks.kt create mode 100644 paperweight-lib/src/main/resources/META-INF/gradle-plugins/io.papermc.paperweight.source-generator.properties diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt index e6d07585a..c56916224 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt @@ -143,26 +143,20 @@ class PaperweightCore : Plugin { */ target.afterEvaluate { - println("SoftSpoon: ${ext.softSpoon.get()}") - target.repositories { - if (!ext.softSpoon.get()) { - maven(ext.remapRepo) { - name = REMAPPER_REPO_NAME - content { onlyForConfigurations(REMAPPER_CONFIG) } - } - } else { - maven(ext.macheRepo) { - name = MACHE_REPO_NAME - content { onlyForConfigurations(MACHE_CONFIG) } - } + /* TODO + maven(ext.remapRepo) { + name = REMAPPER_REPO_NAME + content { onlyForConfigurations(REMAPPER_CONFIG) } + } + */ + maven(ext.macheRepo) { + name = MACHE_REPO_NAME + content { onlyForConfigurations(MACHE_CONFIG) } } } - if (ext.softSpoon.get()) { - softSpoonTasks.afterEvaluate() - return@afterEvaluate - } + softSpoonTasks.afterEvaluate() /* // Setup the server jar diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperExtension.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperExtension.kt index 22ddeeba5..04bed9916 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperExtension.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperExtension.kt @@ -32,14 +32,7 @@ import org.gradle.kotlin.dsl.* open class PaperExtension(objects: ObjectFactory, layout: ProjectLayout) { - @Suppress("MemberVisibilityCanBePrivate") - val baseTargetDir: DirectoryProperty = objects.dirWithDefault(layout, ".") - val spigotApiPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "patches/api") - val spigotServerPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "patches/server") - val remappedSpigotServerPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "patches/server-remapped") - val unmappedSpigotServerPatchDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "patches/server-unmapped") - val paperApiDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "paper-api") - val paperServerDir: DirectoryProperty = objects.dirFrom(baseTargetDir, "paper-server") + val paperServerDir: DirectoryProperty = objects.directoryProperty().convention(layout.projectDirectory) val rejectsDir: DirectoryProperty = objects.dirFrom(paperServerDir, "patches/rejected") val sourcePatchDir: DirectoryProperty = objects.dirFrom(paperServerDir, "patches/sources") val resourcePatchDir: DirectoryProperty = objects.dirFrom(paperServerDir, "patches/resources") @@ -47,15 +40,10 @@ open class PaperExtension(objects: ObjectFactory, layout: ProjectLayout) { @Suppress("MemberVisibilityCanBePrivate") val buildDataDir: DirectoryProperty = objects.dirWithDefault(layout, "../build-data") - val additionalSpigotClassMappings: RegularFileProperty = objects.fileProperty() val devImports: RegularFileProperty = objects.fileFrom(buildDataDir, "dev-imports.txt") val additionalAts: RegularFileProperty = objects.fileFrom(buildDataDir, "paper.at") val reobfMappingsPatch: RegularFileProperty = objects.fileProperty() val mappingsPatch: RegularFileProperty = objects.fileProperty() - val craftBukkitPatchPatchesDir: DirectoryProperty = objects.directoryProperty() - val spigotServerPatchPatchesDir: DirectoryProperty = objects.directoryProperty() - val spigotApiPatchPatchesDir: DirectoryProperty = objects.directoryProperty() - val reobfPackagesToFix: ListProperty = objects.listProperty() } diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt index 35af2691b..62d5f152d 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt @@ -22,7 +22,6 @@ package io.papermc.paperweight.core.extension -import io.papermc.paperweight.util.* import io.papermc.paperweight.util.constants.* import java.util.Locale import org.gradle.api.Action @@ -36,23 +35,13 @@ import org.gradle.kotlin.dsl.* open class PaperweightCoreExtension(project: Project, objects: ObjectFactory, layout: ProjectLayout) { - val softSpoon: Property = objects.property().convention(false) - - @Suppress("MemberVisibilityCanBePrivate") - val workDir: DirectoryProperty = objects.dirWithDefault(layout, "work") - val minecraftVersion: Property = objects.property() val minecraftManifestUrl: Property = objects.property().convention(MC_MANIFEST_URL) - val serverProject: Property = objects.property() val mainClass: Property = objects.property().convention("org.bukkit.craftbukkit.Main") val bundlerJarName: Property = objects.property().convention(project.name.lowercase(Locale.ENGLISH)) - val mcDevSourceDir: DirectoryProperty = objects.directoryProperty().convention(serverProject.map { it.layout.cacheDir(MC_DEV_SOURCES_DIR) }) - - val paramMappingsRepo: Property = objects.property() - val decompileRepo: Property = objects.property() - val remapRepo: Property = objects.property() + val remapRepo: Property = objects.property().convention(PAPER_MAVEN_REPO_URL) val macheRepo: Property = objects.property().convention(PAPER_MAVEN_REPO_URL) val macheOldPath: DirectoryProperty = objects.directoryProperty() diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt index 0f2370b5d..fc46ed9c7 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/GeneralTasks.kt @@ -26,6 +26,8 @@ import io.papermc.paperweight.core.ext import io.papermc.paperweight.core.extension.PaperweightCoreExtension import io.papermc.paperweight.tasks.* import io.papermc.paperweight.util.* +import io.papermc.paperweight.util.constants.* +import java.nio.file.Path import org.gradle.api.Project import org.gradle.api.tasks.TaskContainer import org.gradle.kotlin.dsl.* @@ -34,6 +36,7 @@ import org.gradle.kotlin.dsl.* open class GeneralTasks( project: Project, tasks: TaskContainer = project.tasks, + cache: Path = project.layout.cache, extension: PaperweightCoreExtension = project.ext, ) : InitialTasks(project) { @@ -42,12 +45,12 @@ open class GeneralTasks( includes.set(extension.vanillaJarIncludes) } - val collectAtsFromPatches by tasks.registering { - patchDir.set(extension.paper.spigotServerPatchDir) - } + val generateMappings by tasks.registering { + vanillaJar.set(filterVanillaJar.flatMap { it.outputJar }) + libraries.from(extractFromBundler.map { it.serverLibraryJars.asFileTree }) + + vanillaMappings.set(downloadMappings.flatMap { it.outputFile }) - val mergePaperAts by tasks.registering { - firstFile.set(extension.paper.additionalAts.fileExists(project)) - secondFile.set(collectAtsFromPatches.flatMap { it.outputFile }) + outputMappings.set(cache.resolve(MOJANG_YARN_MAPPINGS)) } } diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt index 2d5be21d5..3aac713d2 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt @@ -25,8 +25,9 @@ package io.papermc.paperweight.core.taskcontainers import io.papermc.paperweight.core.ext import io.papermc.paperweight.restamp.RestampVersion import io.papermc.paperweight.tasks.* -import io.papermc.paperweight.tasks.mache.* +import io.papermc.paperweight.tasks.mache.DecompileJar import io.papermc.paperweight.tasks.mache.RemapJar +import io.papermc.paperweight.tasks.mache.SetupVanilla import io.papermc.paperweight.tasks.softspoon.ApplyFeaturePatches import io.papermc.paperweight.tasks.softspoon.ApplyFilePatches import io.papermc.paperweight.tasks.softspoon.ApplyFilePatchesFuzzy @@ -42,6 +43,7 @@ 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.provider.Property import org.gradle.api.tasks.SourceSet import org.gradle.api.tasks.TaskContainer import org.gradle.kotlin.dsl.* @@ -52,7 +54,7 @@ open class SoftSpoonTasks( tasks: TaskContainer = project.tasks ) { - lateinit var mache: MacheMeta + private val mache: Property = project.objects.property() val macheCodebook by project.configurations.registering { isTransitive = false @@ -69,8 +71,9 @@ open class SoftSpoonTasks( val macheConstants by project.configurations.registering { isTransitive = false } + val macheMinecraftLibraries by project.configurations.registering + val mappedJarOutgoing = project.configurations.consumable("mappedJarOutgoing") // For source generator modules val macheMinecraft by project.configurations.registering - val macheMinecraftExtended by project.configurations.registering val restampConfig = project.configurations.register(RESTAMP_CONFIG) { defaultDependencies { add(project.dependencies.create("io.papermc.restamp:restamp:${RestampVersion.VERSION}")) @@ -82,9 +85,9 @@ open class SoftSpoonTasks( serverJar.set(allTasks.extractFromBundler.flatMap { it.serverJar }) serverMappings.set(allTasks.downloadMappings.flatMap { it.outputFile }) - remapperArgs.set(mache.remapperArgs) + remapperArgs.set(mache.map { it.remapperArgs }) codebookClasspath.from(macheCodebook) - minecraftClasspath.from(macheMinecraft) + minecraftClasspath.from(macheMinecraftLibraries) remapperClasspath.from(macheRemapper) paramMappings.from(macheParamMappings) constants.from(macheConstants) @@ -95,9 +98,9 @@ open class SoftSpoonTasks( val macheDecompileJar by tasks.registering(DecompileJar::class) { group = "mache" inputJar.set(macheRemapJar.flatMap { it.outputJar }) - decompilerArgs.set(mache.decompilerArgs) + decompilerArgs.set(mache.map { it.decompilerArgs }) - minecraftClasspath.from(macheMinecraft) + minecraftClasspath.from(macheMinecraftLibraries) decompiler.from(macheDecompiler) outputJar.set(layout.cache.resolve(FINAL_DECOMPILE_JAR)) @@ -122,7 +125,7 @@ open class SoftSpoonTasks( macheOld.set(project.ext.macheOldPath) machePatches.set(layout.cache.resolve(PATCHES_FOLDER)) ats.set(mergeCollectedAts.flatMap { it.outputFile }) - minecraftClasspath.from(macheMinecraft) + minecraftClasspath.from(macheMinecraftLibraries) libraries.from( allTasks.downloadPaperLibrariesSources.flatMap { it.outputDir }, @@ -203,7 +206,7 @@ open class SoftSpoonTasks( group = "softspoon" description = "Rebuilds patches to the vanilla sources" - minecraftClasspath.from(macheMinecraftExtended) + minecraftClasspath.from(macheMinecraft) atFile.set(project.ext.paper.additionalAts.fileExists(project)) atFileOut.set(project.ext.paper.additionalAts.fileExists(project)) @@ -269,11 +272,18 @@ open class SoftSpoonTasks( fun afterEvaluate() { // load mache - mache = this.project.configurations.named(MACHE_CONFIG).get().singleFile.toPath().openZip().use { zip -> - return@use gson.fromJson(zip.getPath("/mache.json").readLines().joinToString("\n")) - } + mache.set( + project.configurations.getByName(MACHE_CONFIG).singleFile.toPath().openZip().use { zip -> + gson.fromJson(zip.getPath("/mache.json").readLines().joinToString("\n")) + } + ) + val mache = mache.get() println("Loaded mache ${mache.macheVersion} for minecraft ${mache.minecraftVersion}") + mappedJarOutgoing { + outgoing.artifact(macheRemapJar) + } + // setup repos this.project.repositories { println("setup repos for ${project.name}") @@ -290,11 +300,11 @@ open class SoftSpoonTasks( } // setup mc deps - macheMinecraft { + macheMinecraftLibraries { extendsFrom(project.configurations.getByName(MACHE_CONFIG)) } - macheMinecraftExtended { - extendsFrom(macheMinecraft.get()) + macheMinecraft { + extendsFrom(macheMinecraftLibraries.get()) withDependencies { add( project.dependencies.create( @@ -325,7 +335,7 @@ open class SoftSpoonTasks( // impl extends minecraft project.configurations.named(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME) { - extendsFrom(macheMinecraft.get()) + extendsFrom(macheMinecraftLibraries.get()) } // add vanilla source set diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt index 88f986331..8059d5319 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SpigotTasks.kt @@ -39,7 +39,7 @@ open class SpigotTasks( tasks: TaskContainer = project.tasks, cache: Path = project.layout.cache, extension: PaperweightCoreExtension = project.ext, -) : VanillaTasks(project) { +) : GeneralTasks(project) { val cloneSpigotBuildData by tasks.registering { url.set("https://hub.spigotmc.org/stash/scm/spigot/builddata.git") @@ -57,8 +57,6 @@ open class SpigotTasks( val generateSpigotMappings by tasks.registering { classMappings.set(unpackSpigotBuildData.flatMap { it.classMappings }) - // todo hypo update breaks generate mappings, hardcode for now - // sourceMappings.set(Path.of("D:\\IntellijProjects\\PaperClean\\.gradle\\caches\\paperweight\\mappings\\official-mojang+yarn.tiny")) sourceMappings.set(generateMappings.flatMap { it.outputMappings }) outputMappings.set(cache.resolve(SPIGOT_MOJANG_YARN_MAPPINGS)) @@ -75,8 +73,6 @@ open class SpigotTasks( mcVersion.set(extension.minecraftVersion) - // workDirName.set(extension.craftBukkit.buildDataInfo.asFile.map { it.parentFile.parentFile.name }) - specialSourceJar.set(unpackSpigotBuildData.flatMap { it.specialSourceJar }) specialSource2Jar.set(unpackSpigotBuildData.flatMap { it.specialSource2Jar }) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/VanillaTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/VanillaTasks.kt deleted file mode 100644 index bb195ec73..000000000 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/VanillaTasks.kt +++ /dev/null @@ -1,65 +0,0 @@ -/* - * paperweight is a Gradle plugin for the PaperMC project. - * - * Copyright (c) 2023 Kyle Wood (DenWav) - * Contributors - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 only, no later versions. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 - * USA - */ - -package io.papermc.paperweight.core.taskcontainers - -import io.papermc.paperweight.tasks.* -import io.papermc.paperweight.util.* -import io.papermc.paperweight.util.constants.* -import java.nio.file.Path -import org.gradle.api.Project -import org.gradle.api.tasks.TaskContainer -import org.gradle.kotlin.dsl.* - -@Suppress("MemberVisibilityCanBePrivate") -open class VanillaTasks( - project: Project, - tasks: TaskContainer = project.tasks, - cache: Path = project.layout.cache, -) : GeneralTasks(project) { - - val generateMappings by tasks.registering { - vanillaJar.set(filterVanillaJar.flatMap { it.outputJar }) - libraries.from(extractFromBundler.map { it.serverLibraryJars.asFileTree }) - - vanillaMappings.set(downloadMappings.flatMap { it.outputFile }) - // paramMappings.fileProvider(project.configurations.named(PARAM_MAPPINGS_CONFIG).map { it.singleFile }) - - outputMappings.set(cache.resolve(MOJANG_YARN_MAPPINGS)) - } - - val remapJar by tasks.registering { - inputJar.set(filterVanillaJar.flatMap { it.outputJar }) - // TODO fix hypo for v1 stuff - // 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) - toNamespace.set(DEOBF_NAMESPACE) - remapper.from(project.configurations.named(REMAPPER_CONFIG)) - remapperArgs.set(TinyRemapper.minecraftRemapArgs) - } - - val fixJar by tasks.registering { - inputJar.set(remapJar.flatMap { it.outputJar }) - vanillaJar.set(extractFromBundler.flatMap { it.serverJar }) - } -} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/PaperweightSourceGeneratorHelper.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/PaperweightSourceGeneratorHelper.kt index ff3e78712..c01388f81 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/PaperweightSourceGeneratorHelper.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/PaperweightSourceGeneratorHelper.kt @@ -25,8 +25,6 @@ package io.papermc.paperweight import io.papermc.paperweight.extension.PaperweightSourceGeneratorExt import io.papermc.paperweight.tasks.* import io.papermc.paperweight.util.* -import io.papermc.paperweight.util.constants.* -import kotlin.io.path.* import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.kotlin.dsl.* @@ -35,32 +33,17 @@ abstract class PaperweightSourceGeneratorHelper : Plugin { override fun apply(target: Project) = with(target) { val ext = extensions.create("paperweight", PaperweightSourceGeneratorExt::class) + val minecraftJar by configurations.registering + val applyAts by tasks.registering { - inputJar.set(rootProject.tasks.named("fixJar").flatMap { it.outputJar }) + inputJar.set(layout.file(minecraftJar.flatMap { it.elements }.map { it.single().asFile })) atFile.set(ext.atFile) } - val copyResources by tasks.registering { - inputJar.set(applyAts.flatMap { it.outputJar }) - vanillaJar.set(rootProject.tasks.named("extractFromBundler").flatMap { it.serverJar }) - } - - val libsFile = rootProject.layout.cache.resolve(SERVER_LIBRARIES_TXT) - val vanilla = configurations.register("vanillaServer") { - withDependencies { - dependencies { - val libs = libsFile.convertToPathOrNull() - if (libs != null && libs.exists()) { - libs.forEachLine { line -> - add(create(line)) - } - } - } - } - } + val vanilla = configurations.register("vanillaServer") dependencies { - vanilla.name(files(copyResources.flatMap { it.outputJar })) + vanilla.name(files(applyAts.flatMap { it.outputJar })) } afterEvaluate { diff --git a/paperweight-lib/src/main/resources/META-INF/gradle-plugins/io.papermc.paperweight.source-generator.properties b/paperweight-lib/src/main/resources/META-INF/gradle-plugins/io.papermc.paperweight.source-generator.properties new file mode 100644 index 000000000..0a629d9ee --- /dev/null +++ b/paperweight-lib/src/main/resources/META-INF/gradle-plugins/io.papermc.paperweight.source-generator.properties @@ -0,0 +1 @@ +implementation-class=io.papermc.paperweight.PaperweightSourceGeneratorHelper From 28d3d9d5889cd27497303a18e5617401b3fe5697 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sat, 7 Dec 2024 19:54:18 -0700 Subject: [PATCH 24/38] Update functional test --- .../resources/functional_test/test-server/build.gradle | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/paperweight-core/src/test/resources/functional_test/test-server/build.gradle b/paperweight-core/src/test/resources/functional_test/test-server/build.gradle index 3ef965985..43965f04c 100644 --- a/paperweight-core/src/test/resources/functional_test/test-server/build.gradle +++ b/paperweight-core/src/test/resources/functional_test/test-server/build.gradle @@ -28,8 +28,6 @@ dependencies { } paperweight { - softSpoon = true - if (fake) { // use fake mojang data for testing minecraftVersion = 'fake' @@ -41,16 +39,8 @@ paperweight { featurePatchDir.set(file('../fake-patches/features')) additionalAts.set(file('../build-data/fake.at')) - - paperServerDir.set(file('./')) } } else { minecraftVersion = '1.21.4' - - paper { - paperServerDir.set(file('./')) - } } - - serverProject = project(':test-server') } From e194702bb271fb15d76a70c8fc608c94c79d091a Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sat, 7 Dec 2024 22:07:56 -0700 Subject: [PATCH 25/38] Update gradle, use attributes to declare java/gradle compatibility, other misc changes --- .../src/main/kotlin/config-kotlin.gradle.kts | 13 ++++--------- .../src/main/kotlin/config-publish.gradle.kts | 4 ++++ buildSrc/src/main/kotlin/utils.kt | 12 ++++++++++++ gradle/libs.versions.toml | 2 +- gradle/wrapper/gradle-wrapper.jar | Bin 43453 -> 43583 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 7 +++++-- gradlew.bat | 2 ++ paperweight-core/build.gradle.kts | 5 +++-- .../paperweight/core/PaperweightCore.kt | 18 ++++++------------ .../extension/PaperweightCoreExtension.kt | 6 ++---- .../taskcontainers/DevBundleTasks.kt | 3 ++- .../paperweight/util/constants/constants.kt | 13 ------------- .../io/papermc/paperweight/util/utils.kt | 14 -------------- paperweight-patcher/build.gradle.kts | 2 +- .../paperweight/patcher/PaperweightPatcher.kt | 1 - .../tasks/PaperweightPatcherUpstreamData.kt | 8 +++++++- paperweight-userdev/build.gradle.kts | 2 +- .../paperweight/userdev/PaperweightUser.kt | 2 -- 19 files changed, 51 insertions(+), 65 deletions(-) create mode 100644 buildSrc/src/main/kotlin/utils.kt diff --git a/buildSrc/src/main/kotlin/config-kotlin.gradle.kts b/buildSrc/src/main/kotlin/config-kotlin.gradle.kts index a96128eed..61a0409fd 100644 --- a/buildSrc/src/main/kotlin/config-kotlin.gradle.kts +++ b/buildSrc/src/main/kotlin/config-kotlin.gradle.kts @@ -2,6 +2,7 @@ import com.diffplug.gradle.spotless.SpotlessExtension import net.kyori.indra.licenser.spotless.IndraSpotlessLicenserExtension import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent +import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { idea @@ -20,13 +21,9 @@ kotlin { jvmToolchain { languageVersion = JavaLanguageVersion.of(17) } - target { - compilations.configureEach { - kotlinOptions { - jvmTarget = "17" - freeCompilerArgs = listOf("-Xjvm-default=all", "-Xjdk-release=17", "-opt-in=kotlin.io.path.ExperimentalPathApi") - } - } + compilerOptions { + jvmTarget = JvmTarget.JVM_17 + freeCompilerArgs = listOf("-Xjvm-default=all", "-Xjdk-release=17", "-opt-in=kotlin.io.path.ExperimentalPathApi") } } @@ -70,7 +67,6 @@ repositories { dependencies { compileOnly(gradleApi()) - compileOnly(kotlin("stdlib-jdk8")) } testing { @@ -99,7 +95,6 @@ configurations.all { return@all } dependencies.remove(project.dependencies.gradleApi()) - dependencies.removeIf { it.group == "org.jetbrains.kotlin" } } tasks.jar { diff --git a/buildSrc/src/main/kotlin/config-publish.gradle.kts b/buildSrc/src/main/kotlin/config-publish.gradle.kts index 02d6693d5..c44d8f7c1 100644 --- a/buildSrc/src/main/kotlin/config-publish.gradle.kts +++ b/buildSrc/src/main/kotlin/config-publish.gradle.kts @@ -21,6 +21,10 @@ configurations.implementation { extendsFrom(shade) } +configurations.shadowRuntimeElements { + compatibilityAttributes(objects) +} + fun ShadowJar.configureStandard() { configurations = listOf(shade) diff --git a/buildSrc/src/main/kotlin/utils.kt b/buildSrc/src/main/kotlin/utils.kt new file mode 100644 index 000000000..587787ff6 --- /dev/null +++ b/buildSrc/src/main/kotlin/utils.kt @@ -0,0 +1,12 @@ +import org.gradle.api.artifacts.Configuration +import org.gradle.api.attributes.java.TargetJvmVersion +import org.gradle.api.attributes.plugin.GradlePluginApiVersion +import org.gradle.api.model.ObjectFactory +import org.gradle.kotlin.dsl.* + +fun Configuration.compatibilityAttributes(objects: ObjectFactory) { + attributes { + attribute(TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 17) + attribute(GradlePluginApiVersion.GRADLE_PLUGIN_API_VERSION_ATTRIBUTE, objects.named("8.11.1")) + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f513ef092..480d03748 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -49,7 +49,7 @@ mockk = "io.mockk:mockk:1.13.8" gradle-licenser = "net.kyori:indra-licenser-spotless:3.1.3" gradle-spotless = "com.diffplug.spotless:spotless-plugin-gradle:6.23.1" gradle-shadow = "com.github.johnrengelman.shadow:com.github.johnrengelman.shadow.gradle.plugin:8.1.1" -gradle-kotlin-dsl = "org.gradle.kotlin.kotlin-dsl:org.gradle.kotlin.kotlin-dsl.gradle.plugin:4.5.0" +gradle-kotlin-dsl = "org.gradle.kotlin.kotlin-dsl:org.gradle.kotlin.kotlin-dsl.gradle.plugin:5.1.1" gradle-plugin-kotlin = { module = "org.jetbrains.kotlin.jvm:org.jetbrains.kotlin.jvm.gradle.plugin" } gradle-plugin-publish = "com.gradle.publish:plugin-publish-plugin:1.2.1" diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index e6441136f3d4ba8a0da8d277868979cfbc8ad796..a4b76b9530d66f5e68d973ea569d8e19de379189 100644 GIT binary patch delta 12612 zcmY+pRa6|n(lttO3GVLh?(Xh3xVuAe26uONcL=V5;I6?T_zdn2`Oi5I_gl9gx~lft zRjVKRp?B~8Wyrx5$mS3|py!Njy{0Wt4i%@s8v88pK z6fPNA45)|*9+*w5kcg$o)}2g}%JfXe6l9ig4T8ia3Hlw#3f^fAKW63%<~GZJd-0YA z9YjleCs~#Y?V+`#nr+49hhsr$K$k!lg}AZDw@>2j=f7t~5IW6#K|lAX7|^N}lJ)I!km`nrwx> z))1Es16__aXGVzQM0EC8xH+O!nqTFBg9Ci{NwRK*CP<6s`Gq(~#lqb(zOlh6ZDBK* zr$|NDj^s6VanrKa+QC;5>twePaexqRI%RO~OY075y?NN90I|f^(P# zF=b>fZ73b5JzD`#GC3lTQ_B3lMeBWgQUGYnFw*HQC}^z{$6G4j(n4y-pRxPT(d2Wgb%vCH(?+t&Pj z)QM`zc`U`+<~D+9E{4Uj2kc#*6eZMU$4Oj6QMfA^K!rbl`iBix=2sPrs7j@aqIrE zTaZJ2M09>rp$mgyUZ!r2$UK{+DGqgl`n;*qFF~M(r#eh`T{MO?2&j?xgr8FU$u3-` zhRDc_I23LL4)K&xg$^&l-W=!Jp-P(_Ie07q>Je;QLxi8LaEc%;WIacJD_T69egF?7 z;I_Sg_!+qrur8$Hq4grigaiVF>U7uWJ@Hkd&%kmFnQN-P^fq0gB1|uRt!U#X;DnlV zo?yHWTw7g5B;#xxY`adhi4yZn@f(7-Xa(J6S=#d@&rlFw!qfvholE>MEb|VWn^g}G zMSrK&zQ^vDId&ojL!{%{o7?s{7;{+u%L{|tar(gp?Uxq3p?xAysB>0E$eG#$tvkk9 z2Q2gEP17{U6@UD*v({5MP-CTZfvWMItVjb4c;i~WLq&{?Q1(koX&vt7+$z}10{^Id z{KDjGi0JpD7@;~odF__0m|p;5rIrHidOP9^mwKe#-&JX-X@acc)06G{LO1Wu)#gvZ za~y9(fhA%UwkDOVU1LBJ`0ROE z4&)dJKK%mG@+CIm?+wt9f~@xIMr8}UH*K1j| z0pppo{7gv3v{URwxVMeg>Ps!L5IKxm zjac2egjgb0vH5i75$s|sY_RYec#>faqJk|AGgV;v=^%BM(^p{p;(^SVt-88G9f!q; z>p}9E4^f0=01S2pQBE4}9YqE%TV)*hlU^8k9{&=K76+*Ax^r=AkBb%OCP^P2nm0Ri z;D-|Zk?gGeU<12ti2CnPVNA(Pb)02+r|&yTWW-OJO7 zNLb0pps6aN?A~NJp5kj{{IOlf!5KWMleV@-hYLift)D>-7K+tgs=7Ake}oBnIy-y1 z(Hn@Hjw=_(x>dO5ysQsrnE%A*bk0K<-j{1Yqz@#n#jOL^AzCr#wR|WYzqk6i7v)Lf zkXdKxzuu20aP{Tbg$(+9&oh7cd(Uoqqf<#ujb$q4sZ~gxFbQfS zS)kNklyL*{2AELgjZ(LBu*>S(oH5AaJ;YiB@;l@=O%F6B?oanzoYRM^fQ9-<~^=3$H0g^JPMLQo@SZ@QuNvy)tyJ)LSj`+()#fy?{aV4Yg^7dlQ7AQM^3GLCR2dAFR zJjtfKiVqF`l-H_fz0HD|9g>)pOxn}k!vdZ=DO!7Sikm{Z%P6BrRkBS6W?ZB5W&7rT z@uYpf@M@a!z7H&o@-yrcCL^Ff3e7p3T`R9p?@o-acXmbTSa0>ZANzCSgovsd%;i$| zVus`not!oL#(W`L-!9w0jdaECaG4hk{V7IOs676ZquZH~0TX5hDq|)x z6T497l|E?f4)LA>j=S8}b$0LS=I4h|hUFJYJODT8Li@#6kF$k0)@*l{RnM1HQ%?VT ze-Pqlc!~t(oumVC*?5fwR;P6u{tHaZ~*LlD;B)4f? z?lpWfa2P@)g57flVl83Ej%P`2)gGyaPjhvD(%i~{`2b>#3!+y&` z!2nuwHMFA-zUY}f1^0B8<`N)Gr=A4TS@b1qykmd0Pq{?r)+1^^+D(=xasb^Tf!oK9 zBLL+*p6M_#ufgLzgq1zcSwZsZnQWFLC3`Yxdg-2=*tT`J9nrfYt)RF)YryBf8_gW{ zvKbB+oZLehfT)S#<|y1)E0hW^?+AnqPXq9Hu;v3dsMGdr{SVyF63;K<8VcgI#~}1i zLYSBL0K;RTT(;>2x=*!1Di9w0mwr;`CN}kM65|Ay{~z}_^JKOsRaN<~#9O^iiW<5P zYN7r~HV!#Nz~IZU`P>1Xe%4f~K}KcF#X&5kO*G}-)74S*tQ8CietdPcA1Yl;S=Mr# z`#MYY!{s^uo=jn7;k6O%(}fN+*0cWMpt~#n9DR<3NyU?+3D^AgI}S)Cu-Tljg`VY} zX1=fq$?8$DtOeGxE6f8lbS_6Q3C4+LDTO$}_IpM$Xv<|QSC%+Oll^q$y`7o@jD{dp zNDl|&X)r7wETa-#h*d`KXntxI(Y{vLha{$0i7@G8xx^m=c<{lJ9?p-i!^W{%j7-oo z0W^SzZ^(Wkyz*We{lEn%Yhu-ycUOHtrRiVJL4~&S91*D0MrLu}Q>v-Mc?GcWfpyz% zX|UvcN@krFO#@v|CtYM}g|=L3%aMo$E5<@CM%c*;?u>LOTz00@+dt1{yg1y=$h+{|D17U}$*^fE^H&8b431EUE z<9tv0V_#%#&1N#j7AKCj!tTK@J%oFW*ESW<(#Gl#Xs%v<@AitI?s92nLzm<)w3Wkkom1f$gcdUi%g_*jofy&}N#luL<$GVIe{iQkQ)sIHVy zBgItnPBFamrv6Kb{eE($Q(f`ZPeW!Hm%Y@F*OF1sKB{Yy|C>WEv_mfvv-N-jh)B-5 z4a!1WcT@9a+hGaBrc~sz=>G?Q!*Zp^JFRUvBMyNR1;`)j$RhH$6gEyVKhd$&K-CFT zXaWC-Y=fyOnqT84iMn9o5oLEOI(_3fk!W^8-74|q1QhQ|CmT0i=b;6Z3u?E{p7V{? z;f#Q-33!L+4&QQcZ~GAqu$NS{M;u%`+#9=7^Oa5PKvCCCWNG_~l(CidS!+xr-*gg{ z$UQ`_1tLT_9jB=Hckkwu>G{s0b0F4bnR7GibmHo?>TR&<3?D;5Fb#gd8*wYa$$~ar z7epl1qM)L{kwiNjQk}?)CFpNTd?0wAOUZ|gC{Ub|c-7h~+Rm(JbdoRe!RNVBQi!M8 z+~U6E2X&KSA*T6KJvsqwqZl#1&==Dm(#b^&VAKQ>7ygv*Fyr;)q9*^F@dCTg2g!w~ z%hg)UXAUyIpIbLXJv1nZX+a_C)BOH2hUim|>=JHCRf(!dtTidb&*~I!JrfRe+PO>w z@ox$G2a3i9d_N9J=|2$y2m-P&#PTNwe!oLBZFs;z|F5kXvBDn<)WwE0E3$ow=zg3R zK(9;sf0t;VEV3@gAg7jRtnj%-6O@!Hvg*;XcUAw}!=2*aErvB(eQIm(-UGmq^J=XN zTqJo$Y|WKo^HlBF3BXJrA#}7ZLg=r*w`I*~Ix`o&2k8^(0mt8Rp=A>F`&gehhp@Jy z^e^#B2!~$LvNCKugg)8)-G%&THdk~kfextilegP9?#C#()F59U$&eo(h|5>ceo*Em z{PEE79T$YP|Kr7K`WBHbtQwyxFkCl6xX&+oUf90B5xoi3_5KHHCyEE*oPbOQkfMz& z6^hT8_NXd2iWk{q9IKae1{_7hMPH8I7_BMtVOM4 z6jm?E0QJOn$qrgsJ`9w##GB9?G})-GXSQo6(tYS(Q0-Ct$co?Zzl0?NHsDRron?;_ zZZgQg)%XW>P?8_&zoGuF(>Och2kEJXsu1_X&~w87x!b z>~h!a>e7{`p@+#hXF88wI*JeWRZ;J4ev4<}HWf|Z;(7$E!S5l9wzBHFe>^I{2`a;a)QnAwa2xv1e(bq$<}!8o^ofGvYpk7dBR+`*%iE;hUY5 zaHF}OjGO9r*{%lmcK^uFiTHgoUD`^9Nx@~;Bg!V* zuuJ&ti{DQiq7RyJAR94wem{}cPK1J(Yxnn_{=>?USqz-~&QXRStS^s-7TksZ$AEI! z#og36s3JGtGU{CnDHRFtipFqvrE*gw7_K@NN0h+ItTq@4fqN!HeQU1y7*X?9+IfZT4Vxebpt z%#VzgdDK~-&+=Z*#>=n#XUhNvBZp3=Cr41jMqwJkHLf3L7Vm~V#GgJ(Jpii~PmJ#s zA7Ft!{xD@z>9DUb4JbiUBdNEcU4BO$651iN*mp*f)HbRRM`Cx5cR?5IfEcU{IZWwf zz(M6CDv)>xa3x}K6%tP^i15P1&&DOLK=k~+jNR$UK3frSl+|PjSC-dBItvD~LL! z>_g(YYdO4k(5EbPOw+v+;G7~jYm>F@Ai|o`gs%F)F8tDz$dl7Q%aCe|v|$UkAul_R zNlA-beBX^IJU?kgS`E$it7nF4DaI!SJAGq)2P&Few(-|tp z?K+%D3e4{pfkayrcbm0ftu6Ol2ZzdKM+4i!hNP3NRL`EvvZJ3yvNr2MV%igZ4kj``Qrdb_OI$7jWP z;l0DYf&0(-*QcP5zrP`HVznW+SbH63Qx$7_9~NjRNg7eKqI!UJ=XH`g^=t8GiFTu( z?2L{JKEu%jJx&XjNzU(*!ZNmL1@RlJA0G$2_LrAb_7lmjil(GSlSM zwTes`m+3R;3#N~Xg#9owh3ycXV8@ZlaY_16kpPFA={721b~URO4HD3sp%fmkZM}k) zZB0#)kP=RkNB~R-MCk8aljG_bagt4vIb~8)BV%(b8_;)&Kf9GX+%O_cNG|(D$!3&D zL(I8}*LqN5NntipFlN13=`D>6!{D@CFMBH0kW3=HccJV+xW~|$qeFR5i-2{X+iWMu zI2$gepQ)H_B%ip_BlWOQ*|pErXs|4ir{IHccgaIJ84irE{?+$KDABXr&f`jB^V-c% z$$u`uU1YB^{<+UN2cNg#7&0bz@yF?5>j|;)5&IV3wIQp58X#OE-M^$HdyvL|Um5t? zhZlAG!Mz%XkUe3t471JM*Yur}o30vzu6RN7gJyNcf!IItsDO730mcJ*O!~V``y5=3 zNJGp34DZ}wd1H6V`Uuy%es>BiO_aE-S8jzir#$& zyk)@2a5tP$@g%jW^b^JGdo)X@Q%sE`^lDQmY9m%uDFpPX`w9%=yQ+nneMm#OaXcD` z9}{tn5A2b2z9783vL2_jSao?uxJhWJoq%47*RafM4o0@gY(p)F>qT4^XM5GLzV#6j zC+HoGhAne7o_w{WUo(B++z7lU3Y0k1rYv9|TSv0vR-Du(5=VakbbelgZTeDn+a_Wv zq_j-^+Qz1WAl;Zg>ahX|CERbX1V%B!hTKN?M}fGoA07M(WU&NfT&TmN`P@56U2 z^)vLDs|Ln~0iTtn-?KTeQl@T&bskJFuTUS!m+$CS9vnd}8(UMO|Kv6TCfGN9NUu&4 zL{)GTxPq>fwsJ~aU=4Qhuq8*RzDsP(LZh$BHezq&9gK$IS<|DYbm})$QTGCS6T;Dr zEkLct!b+#<1r9OKG@P!f1wm8>=Nz!7OzJm!g<+`?N3;YaA3(P@EL=(sTaRMDD!c8=-XN^4BXp(eVkj$NmEMYPP>YJ4bJ3yUud z<3BeJAJ$6z^TuywnfH5lv#$lgwraNw{IV=tIznPH1DT`v-5yS=!)J<}xxl}uZf9azA2A97Haf!;<3y01hlw?dWNEv@TLi1s-mO4vmIT%O_42nS z$VRWrs9NngqRRkWAnWkn%`Rw@?wH|)7XL`EL5EZu$qyJW31&CB^T_)qwIv!{;E_6 zo-9XAryQRlk-O0>o#-SZO>|6OYq;}<*>Wu1AsVRiXY4f8qb;+sItv3AyS!4Ry+q}) zA!pAB|BmC;=RIOk^^vlsEH(!Q!7_1FK~ZB2err*o!+b(r=m1b?$6d!%zmN+69LXnT z&gRmM+n_R-F@sT*IYv0_mGPvur!u`iWbQO7SqiGFLeY&yga zf`lM&B74FA2C?N@8_z652fjhBEoDUKbP8hL{0{HAF%qDo7)o3=3rg#6)T7%%5^wl% z9R0*S*<~>nzYOdQk2l`9h#t+gJy_xujw6xjV(8S<_DbVg61&pT%Hi42l%D73G?adn znB%UdNM0p}lEF-P2%TAMam2zpQev71e>a$$%i+r~b+D9G9pF|oY_*(-u*89oKsXLY+UIbqq)MQ%(GYS{(*n_S_*RN$*~`zUtab%0aKwhx znc)Yo?{xq1sJCgQD)TeTci1ucvbez9q=A72H(-SB18Kl&6^vHV8^i!p@>iF!DIw17 z+8Q)TNisB7>pwyww4y)yJx*wX6SJO78eLBC-ar1+k$Z9fy;wBD|3kzI{<+l*>PSY^ z_?nLOZaeWbU@C3hfK?X;Di*8CHCPkx2qco6(ZyJdqSzp^TJ_5Lpa0UP{Gy+!b0Lr% z@xYxSjUKoY6L#>$qx~KD$-0=|OF7zhVP~ntMgEALYPIfhj@+ z!;JJ7te>CcovruwHsJH6Lta$nm|%^C@=V-rmhU{+I~0(|XHQ9jt@L7pb{gx#{4r!) zg($FyFTslcgu(~6lYr$nW?)%*l#VJ=R-jxK(x=t1bWlu(nL66T#qj%3aZ@uVhy}Co zDU_q61DD5FqqJ*#c|(M5tV)XBN?Ac^12*q)VN4yKPJ|#==S_`_QD9|0ls!`2)SwuHDRA_OfXQDq3%qW&MZB}Z!=k-9xqev8jHz(H z{^D@cIB~QiK>~wa)A&^Ll^Wi6QgCzU;iv-BHsLBs zH7=jN%|>0S`SjP%M&AF1PNVDp_FZ?2Bm@7`DC&v(pYrw!!yD#4 z6+<=HS0Ln6MhoKxF<%~H`y20{vf#pxh=;j{zY381gvAFekgG|>G1zo8$&az{V=;JR zy_puF4$L$?EMhT?;TpQoR*j16ll`#AS4e96C}yp_aGKkBe?1H|k_;gG-~Xorc<;lI zkB}fB{$c-D2mGA&{rm<*@F5)c3X+6??g~XoEwuzSuch0D@W~P5(2I8v8F$c2$Vw51 zP#YLSBDqtWW^EYBl^QYHF+MA7am6f4DOhwnJM=W9$uvMOsZ%_~?)2C#wb?CkI$7{K zEi)=#|5pFvg^){zK5kpBLjB2kZ+$ZB|L=W|aNwyyb(gC2l7bcpx{E-H@)q6@D6N^xh`{1E%ItF2$eeB_SjI@b2WgTpS1thwg&n`jiIzw^TtXUyB{00($GIq>vbj|}bav}}Q_~wp3>k8!E@hVC;OMUTu|= zAy#vXH*GrUHu7^cNZWe1>y;2(51js9wbu+R3Aa*(wzH9+X0dIsf&gc_x|_LP z>~CF^?(~U}+l~ehe|i>?4eo!xkq&Lk+RR-1duNP#o~>@1x)s&i&u zRaYL@+D&_M|JLI6fHbEr_`U;HgPTh#E3?sB)A$*gqyBgg*ql|a-m*TX5rACbWKCE6 zdeQ`v8m6>g^ugv`p|HY^#1QZrGGUj0^HVDc@{?Q0yhalbBEV{+|HzC^-{&e{5K%z9 z6Bxtnfu1!@Mp+Q&*&~;FOg&*Vm<@4b;{FG0-!UUXX!|)1w}op!B_|7_s~d(+=9Gba zKp8`LaB4D(H=cGcspJ_TjYaOwMb=sGn^gtUVhK!UI~2KKYEE-NC}F>+BEY7IVvy%KRvm00tg!Q`y=er}wpEetX}K@;}(}{s9AzV#q2@ zBy7}->|N?13POrs`;U?(qAG(I$~Gt+Rgw%aNZ_0fs_utVvRJT-7z4!@x36v@=NBX=IqkK{#Kg0w48de@?#Yb4M(Svj5=T+<ONr8-oh7l?Cji@+erqur zFhZ=9|Lk=$`c}v4u`)-!!UI=!9Jo@h&7p4RlS#u! zZ7-prn75JkV?VjptX;@$#`U`{vB!=Z?V`T*FBF>J?vsML7e6@2GbUteMFfX-TUu{2 zLNIG*;dV)8GV8gAgEf#)X3A>p3^CRka1v?~8x^anBhQ=L=LsOl=&pcOYHo98m##ye z34MtGCDK!`ptl?taGMr5q{!zVc? zG00e){TV?`YA9eB;(lA3lXI?RrB4BYQGk?vOmTIUJED=(`_*gtn2DB-t4WW54as*W zb2kD-lWX>lb$+W!VFakki>B^Vc+u$?NLF>)!U%b@Y}gYJ>m2H=^x0=nsE0TF^Yu0h ztgH8-o1%+jCk(+&`|)tTfEVHq0cMeFa{Uz)X$;fCq%Y=SOWML6bYfeP8j5hktL`KK z(18`XrUn&WN9PtFxh&dX`y~YBsmdhi7Kw%tKzM%^VEhdD<_XkulW-x=JN6OPbFI4@ zzDDRN+f=@{0h*MswwOqG6gJ?{NuHx(y-|FUGsxyZ*x0~$MW(eY>vqq4Fh#t7uzw=- zKB?|!0N~!h^AMdLa)oR!Ca#HZ9&Zf)ghuO<^RN)4twRlygHnQG(BE{cDc5E}OF4;xss6gYyV~EcJvJkX)xNWb=@yw!uq0v-sf^rvkp-;?DPWK@*SEw|V;IH=7 zfQqEV_>DjOPT~8X*J|H8=&RnzK4~S7ML~nLX^%s-Vqc^aWy7N$y57qciZGcqy#=zU zs8hcHiI=D$+RB{|62{ohCTiaML6FI4Uhzo5D{Jik@poCs0w7F)*w}F4r0sJ~#u-72 z5bK=ANt=M$Dh5NKnxGsg9NRR?WD-x|FhTwBjd zD<-K>44DB~i%frJOfnzh1R>PRY34kw!6~p3M$JLaD1r@`=h)~Ngks-(gdXh^Q?BTP zZ^Zj5w1AwtuR2$~E7s9iZdF}z%pv1em^V2rM{1tLUY@-+Sc0(9jA|iZWml1;v13=U zHf?y@#mb--7z6$ue>`qjhE~brk$AY-RG90~5wcBbDReXR2)pKg{L>;H(DI`U!MLNQ zY9rFJP@ZQ}jlcMh%WSCo%vf+nd0Gmd*F%KMIe>slCUh)8Ma|;M_I+v#;|ueg9oLg; zq2HtZX%&#F7vdpNlkX?}(C7dGC^y#NB#m4%69RzTNrk%4ol~hSI%>2r6B|*ZkW(*P z;u#s;+faHo{tfy+1L^RzWDi*^JR0iY(zJDB36y_QJ+|E-2x+cY z!V8uLNktH~q>WQZuY!Ap66WP|E!0PA1jK~)^8oJVGbspJs6QL!!-5Qm7 zHYI|_`Actg?vDzdg5{86w@GS$G6ANzff7->6i5pB$T4O}`fZ_;{217Om0gN5zTr12 z5mW{hCzCE-QubjxN$TAE-XgI-8dTY@OZmq`y+y_>dk*(qXF0{nam|q@~i}Utp*k{yurq(DW54hkDT4bbg z=_etM?Nf5W^o-HEu9_?&xEqPg^P^mTxLH8n%u$!mWvFG|{&)jtnU&6|5-`~eaNz0%D1BDo`{ zS1N5(KW5v^2eLdd_%`uaRndF@h0Uo6=M|8?b~KbOLZk{HXEnGmtgZXf2inI*1r%n! zQ3&%RI4r{f&dwW~HwH0Ked9b!k6{>_19H z_Ai>5IChDMY(FfMyG%;30?SQ{iV9KyGru62+Y)~qSQ91}b~}w<&*}R&1c#$O`H@~c z5)2S_eXx}M#N{MuGeQS9@#UJB@;W_j50b}jIhxMPloEFQZdvwxiU^RYycTzgK)-vl3LT&$L8~@68$C8~5_U{cR$E#w*x65(qw&eoL@>%ZHvj zWnEMlSh*(o&oy|J7eJ5OD`ssy%F?*Vp?`Cq;FShyl{ZoKCG5g{y}>usznni#8ki(i zO{w@n{iAj1_ooX@+s*!uW60WcH~*bNOT6z%0jVML5};wVrQp~`Uss_{cO2oud_nNA8^B$?07fJ6?iI)Q zuo9G)O-z)DqstrBqf>B%S05hf-wep0@$BFHKSrkZ{za3D)yVzRz)2{wf8(Wp+xyAM z$rtyx$gi3A=V~V!`Q3;BM0$>*VVtxEM|xDL^gew7ydy3Q6YzD&THRz*q33Ms_D;M- zbCx1Ft#UNB)V3bf`~{ImI72OTp^|bF8?G8#FRj+Biy8ET5#rA3sd|0FR@U(LAJ%w8 zS1%n8Z=Amhw)92rIsof=YVWF4jw&F*j1LG@-`+cR0-~2LqXRH8(Ccne{y#MCPncF64U`0uO zWmi$dlii~1D0rLR{qc|_2M!C$t8^=G7xQY)9!#Y331A|>N)EhmyVdLWL9I3YLJ`7? zZmpqUJB>Ni9oiL)^1IK1UoMyhWE{$9M2M6Xi zPKk7GpMsA6vjZbU7~i+u|J6Nk|Ci!Y3UMUT2|`M;JsNQACdJ%ooo9Yt{?A+0hMpxi znEa~~sxC>rKrU6bd=WRb;%wsH>A#j4{({&1GYSNR57Gama(3)2A;SM>qop}l>Jk2* zn1+C$fIxuwzg3mCU#SOqb-wOCb6mBcYlA5+mt<&_J~sBxc(GQtBFINUO~Mr7<-uu($>P HJ4oML2Lo<@i8BwbL^1~GkG`E7C$SEa_ zF^}Ea+#Je`Xy6;#D0FPnSrR%Y!QGA~NA^{oWmW8C<3dr{x6wWQ{4+bzemqV5W$i5~ z=J0jXZ>uZb>DT@0Ks?4QJ{`z?8JWl3$y;2pj#$XP*pv$>$g(z43{YH9KmmR6<#sIn zA`#=0#sgycaBQ^&}Xba!|KaZ8~b30v~nLt z9%#gz_*=~KD{3t^X~l>480*}PhKN=??g`RV|4Ud{Gyyl187MJ}r(#e+H$GEdI+p1s zq_25h;fV)$EPK%Dw-(G=f`yHB-_tttsC!?k7*#!|4a>`Ahj8nm?&n>NRs%jkZW^3-0P_yMP5&*6a26{MRj1&TPF zyE#|c)5uUHzMWx=rMKpuPih*V=S;W3MzIZTw2uTbr}8`p2bm+Z6Sa%vvWAWSf4H)p(+ zSQ8;EvUa#wqWV+9vmIio(%7wukK2SwjUS8Yl%Rq%=~PU)2$Tvm6`1!r3H@U#_|bB0 zmlT1PS3wPB(b&^+@YY7Y$n4l3mV3-X0$>z|gZp6O*Lhzn&?Gad2ZCF;+#95-Y?#y+ z?*l@Yf=a4w{Px=o!N|3~_XKfk&G;fN>Ps&dp2FpA~qD=0~=!NOS@B#XAKKkND>Y{4>rqxrViKD7;?>j8`R` z&G)3FN|dfsxnaI^!d1G%=>AbTTxZWo;n-DLrQ!sj=f~VAOe5zhGS(dgx|!ls62fbX zV@<7Ck^!}R=`Swr?(7w1rY6Nmq~sfXJ?TiKJLn=&SQdEt9$@0 zA+h1Wbwbri0s-stc8yVq;mRa6@kEf8^KXUz&jcic!+avDvvJFa>k0ioWug=T3oPw; zyj4it&0@>_*uI@2=^+T7sL1_!^aJW@Xfo8aC#3^WtQC7fET8b9C} z*u^ue6Ojn z7@(eskJ2+cNnH9~VyfIh<-|7!je~vGy*odz(sk-u$~SrYF3glruZ*W`{sqnS+9=;Z zh{D@MSG91%lr&ua8%$sJF%y1I<|e;EdfJykY8#D$Hc_81n5`$7;1N|b0tvvPLzSg& zn7!5x?T*@rQUKcUhTIjV(rw*5oQYlm5DbEO?60#mohHfbR$3_x#+PZoYi@Vd4`#YgKyTd^!4n{fN~WZDY61sAOm6 zl!d^i*a01QxpWM9Pcl?&{RgO}uq%ErOk5WpECvnfEh!*YP&1Sl)uTN4hg??Vqs~i5 zYsfufz3?{TtwuBN=`0~Qg1PlWH#OGG$ zLLWU17$v``)CE1cds_7kj8mJ{-+l8{DS|zAQ&3|qpOY=!J|kXUhXue9|H>4gqk|n) z-i34GmxLFj8asb3D#D&=ya*a5`C<=o?G;Ev^LV%;l#nH#O=7Nh@z1Do>j6Q;I5S2P zhg|AZbC&|c7}uSJt57s2IK#rSWuararn-02dkptTjo*R{c5o(bWV}_k3BBnKcE|6l zrHl&ezUyw^DmaMdDFVn<8ZY=7_{u{uW&*F<7Al6};lD(u;SB=RpIwI)PTyL=e25h* zGi{lRT}snjbMK~IUx|EGonH+w;iC2Ws)x>=5_{5$m?K z5(*1jMn%u0V1Y%m@`YS3kskt~`1p(rA4uk;Cs!w^KL$w>MH)+cP6|XKr4FfHIATJH z!EGAK4N>1yFR`-zW|w%ByRe#=&kA&#WyUldDGpt!wf-8SFWiSi!5QZL+l7*CE?u!NW1T$<1rdLJ9y3u{_zvHaM?#Rm4 zFk}^1!ffcrB|XK3gsO-s=wr*sUe&^$yN|KxrA)uW00Gu60%pw_+DcUjW`oW<35OC8 zq2{j8SgC}W$?10pvFU83(SL$%C?Kctu3*cs0aa%q!fjn1%xD*Jrm!F3HGR9-C{b?- zHp(cL;ezXMpL@0-1v0DMWddSDNZ5h?q50cOZyVi#bU3&PWE=(hpVn|M4_KYG5h9LffKNRsfhr^=SYiKg?#r&HNMi2@cd4aYL9lw(5_IvQJ zcB*DD()hUSAD^PdA0y|QrVnqwgI@pUXZXjHq3lG2OU&7sPOxxU$Y3&ytj6Qb=2#cC z;{d-{k|xI*bu+Vy&N+}{i(+1me!M;nshY_*&ZQLTGG*xNw#{RpI`3^eGfHck+*38NRgiGahkFethtVY=czJs#)VVc{T65rhU#3Vf?X)8f0)X{w!J3J{z|Sq|%?)nA+zo?$>L9@o`Kc|*7sJo4UjIqu0Ir~S5k^vEH};6K?-dZ0h*m%-1L zf!VC%YbM1~sZOG5zu&Sh>R;(md*_)kGHP)<;OA44W?y53PI%{&@MEN}9TOiqu+1a3AGetBr$c)Ao3OX>iGxmA;^^_alwS818r4Pn&uYe^;z6dh z)68T|AN=hjNdGpF7n>y+RTAZc9&opTXf zqWfK_dUv=mW{p_vN>|(cIkd(+Jy}qnK{IW%X*3!l`^H~FbAHwof+vLZ0C2ZXN1$v7 zgN&R9c8IO`fkR{6U%ERq8FN<1DQYbAN0-pH7EfcA{A&nhT!Be>jj>J!bNRw4NF|}! z1c70_#fkk!VQ!q1h2ff@`yDyrI1`np>*e#D4-Z~*!T^8#o*$V~!8bWQaie?P@KGBb z8rXc!YDL!$3ZgZZ%;-%~0Kn<+d+{xJ$stQbtN8GWV?MCJvzPU|(E(1z;rFw{&6vy) z3*@y%7Tx8rH-p$boS>bLyod?OKRE8v`QSBvGfY6f}_{Zo1q85xoyOF16n~yHx2W ziydUoYLkJmzq|n&2S(O!ZmLdP1(o1Jsq88cX)x3V-BK5eF&0e_0G!5?U7&3KN0`mc zH&Lt)q8!d_VgzxyL^(@xrbp2y)Hmr^V48));RSfE=*Ly0uh9!$3dv-vMZr2URf@l5zdwLjGZB zugY>7_fd_vbV*Qv1?H~>Z%RD%nEeFSI$n$$Lrpc6g>i4+XdBB!%zM$Bhrz5Swzyg? z$~I~n@~-wTBY3-T&pr+|gC+OHDoR?I(eLWa{Z#Rsh>lc~%u0!&R|s0pA*w<7QZ}{i z*AFr~0F3y~f$MGh_HDL7J_1?SxKL}fWIk!$G}`^{)xh*dZ5kK>xGL9>V`WZZg_ z)^Vm)EQK`yfh5KiR(vb&aHvhich z_5o+{d~0+4BEBqYJXyXBIEb1UgVDs;a!N2$9WA>CbfrWryqT25)S4E4)QXBd*3jN} z?phkAt`1rKW?xoLzEm!*IfkH|P>BtECVr0l8-IGk_`UjE#IWkUGqvyS+dMrCnFl<7RCgSMX^qn|Ld_4iYRldO zY&cHhv)GDo8nKvKwAbfyLR%t?9gG?R7~PSD#4D-;?F&!kV59O}neYut5AGbKwy-(U zqyBi=&Mgj|VIo>$u!DHM`R7O?W8-idbePuxiJMH``6c_5L-chKd}=rGC5Gfrc{f!* zWFEBm?l@_b7kzY7%1RQQbG5V<4=ZlkZ%sF74Q|mKOc7Ak7dP2#quiGcZ0_J%7Q?j{ zv9{WFw;n5G-Mn%r#0R;{jLt{yy}9J6rQ(>X9pJ`7Xy?Zv z=lNit#qXaq?CnElK^zF~sG}U5oCpR0T>FH=ZX}Prju$);?;VOhFH8L3I><9P_A|C+ z{;>~dk%9rrq(snjsEm}oUz2FQ21MCG*e?g)?{!&|eg7PX@I+Q0!hL6C7ZVY|g2E>i zr!Ri2@OfEu$)d52+>+cpgh6Z;cLYCZ&EMR0i<^~4&wEu_bdo;y^6}+U2GIQgW$|Od z_jg{O=pU>0-H$P-EOlWyQy#W0r@@_uT}Lg+!d5NxMii7aT1=|qm6BRaWOf{Pws54v zTu=}LR!V(JzI07>QR;;px0+zq=(s+XH-0~rVbmGp8<)7G+Jf)UYs<$Dd>-K+4}CsD zS}KYLmkbRvjwBO3PB%2@j(vOpm)!JABH_E7X^f#V-bzifSaKtE)|QrczC1$sC<<*Y z$hY*3E10fYk`2W09gM_U<2>+r^+ro$Bqh-O7uSa)cfPE_<#^O) zF+5V;-8LaCLKdIh3UB@idQZL`0Vx8`OE#6*1<;8(zi&E7MWB1S%~HAm%axyIHN2vd zA(pJGm_PraB0Aat3~?obWBs?iSc*NhM!{-l_WNCx4@F7I?)5&oI|z{o@JKd1HZ}zf*#}JjK3$ z-;3V*WJZvUcKvSOBH4c7C{fl8oRw8-vfgKQjNiR|KhQ%k6hWNEke(k8w-Ro| z7Y3)FsY-?7%;VT64vRM)l0%&HI~BXkSAOV#F3Bf#|3QLZM%6C{paqLTb3MU-_)`{R zRdfVQ)uX90VCa3ja$8m;cdtxQ*(tNjIfVb%#TCJWeH?o4RY#LWpyZBJHR| z6G-!4W5O^Z8U}e5GfZ!_M{B``ve{r0Z#CXV0x@~X#Pc;}{{ClY_uw^=wWurj0RKnoFzeY` z;gS!PCLCo*c}-hLc?C&wv&>P1hH75=p#;D3{Q8UZ0ctX!b)_@Ur=WCMEuz>pTs$@s z#7bIutL9Pm2FDb~d+H}uBI#pu6R}T{nzpz9U0XLb9lu@=9bTY&PEyFwhHHtXFX~6C zrcg|qqTk(|MIM%KQ<@j=DOjt|V)+8K26wE_CBNnZTg+Z+s}AU|jp6CFoIptG1{J*# z7Ne~l;ba*=bSwAMQ|Vq#fW~+je4PXA91YFzBubNF?ovIOw-$C-8=Ehed{lGD0}(Id zRe4sh8L>&T%{>8o))he}eE;5_ zxoXk3wX?MyNl-xF!q1d$G?=wp^`@09(jU&X zOqZIBI#dN`2PJNdATR3ivtub|nO$dulSaP|e4)WXF1YAGN1pDQIbIjXFG!oC85Mt; zW$eteoL{y^5t4TMRwP$jNPjZFpGsWnGe=jMMqKtcZm9Y9PFZLi*1p@qoKKub^T@2+ zk$@*KYdQ?Z`}<%4ALwk*Yc{(WTf@#u;as(fvE^9{Gk)lWbJP*SjttWofV0s?AB({~l zZI1hZVWFT~W-T?nfMMcnCS4-#6H-MU7H$KxD;yaM46K4Kc@~Q>xzB+QnD_I`b_l3m zo9pRx46b!p?a^&zCDwygqqV3epjs(s0NQI6ARA1n!Yy-qduipxQ& zUAlqRpNjBS+y-ZheD(!R;F}&^V_}b_gqH%tVZ5%%ziO7k^w=es+wZtK^i*vmrWNLMs{oWu_CIov|s1raZiS)>38>pYu;i+-t zI_DiNe6aA4KTZ2P09qPj(0~K4nUq^0+f(2$g`229zkG4jLzRvJUWE0oF1XHL4t3UN zDH466G56sy9hTZoAJB!C3;@F;ONxEk5u6Mv%zdo}Rq`=* zw1n7MOhfNSV48TS989ArIcj`C%Gk8~93~u>)!Yt2b4ZriKj9x2d`H2HQNJ=I>hkDlcZn zqRj>!;oRMTIOu zx|Zfsu~v76T{z7AC(jxj^c@tnJHZtGPsq$DE!8kqvkDx5W?KUJPL+!Ffpwfa+|5z5 zKPCiOPqZZrAG;2%OH0T$W|`C@C*!Z`@Wkop{CTjB&Tk`+{XPnt`ND`Haz;xV`H^RS zyXYtw@WlqTvToi;=mq1<-|IQ(gcOpU%)b#_46|IuWL#4$oYLbqwuk6=Q@xZaJSKVF zZcHs~ZBl;&lF3=+nK; zF`4gSCeZXlwmC_t4I`#PUNQ*)Uv&oGxMALip|sxv^lyVV73tKI7)+QY5=tEMas{vTD-BaTJ^*Y6gq~PU;F5X!sxqiq$iFCo+Uv7m%1w((=e}Vf*=dtds|6 zbX}91!G?C*KG03eHoN}RZS9DJxa&8YwNCT8?JxMXyZqZr13NA|GB{+vG`08C{V(yy zf*Lw$+tYSU_+dI`3n{bMrPdDb`A=Mkg!O=k>1|*3MC8j~- zXL79J4E=U^H=iBLTeHE_OKzE&dws8RNynsSJ!d;`zK?P92U{f)xvD7VQVosrXZrL+ z6lMVdD1YgL;%(1cq{#bS6yXmp|DS@nax#AqqlZhtUQdh<^2vr5`EpAO

LGYq)sa(w9^3-f}NHy=GR4v%t2YZly3m1G@5y`xBh_HGrD%f z>;|Ty?9FiJAc&UVD(StT4I` zfVQwxhE9bXE6r2mKO8Ag7{L^jCyqQb0QqKDPE=RAgqn8q1O^>(z7h5kE(6va%QqRZ zkIOmp(})rLSS(2{=C12e&@!W2=Jel-^_R``0xHO^+t!(oXbcv5yhD4g*$t_F)_5Dl zSVCgesW%;DtYPCFs{G;GX_o?1J3;QQPPv)rWw;>} zJ&KwnUqwNXloNXlK_+pNDfI~hON#SokVJb&ilg8d7^NWo2ZQymCqQMnjfi>ePibjr z-Z@q!?RGN$Mj}Nk){X_vaj6?Mj$>ACR*z|6MsXy3VZ^PFn@yHkPo(>m(iWepn8SC@ z>D2;R4m+gDRZ=SIX!b+CP(qE=JDIUkn=D$aUu+Ihn9-+k1LS3PreQg0N5eWIG@x${nC3v^7caS>1!PKNAY9J z#}E}Q9w#SP>(GY7Hbj&z4$Li6o5taBO|4+F`yS9zq*LJ<38wy4I>HA9(&GYrk4dLajKGww))BWli6Ln1A^Lda@N~p+snkb9C z@OthI+<##vp8!HVQT4Wk(=@zQ{OvZ$EKWS73+JHb)eYLGD-cqi6^|vd$<+IHuc?Nq zW7JertT~3))4?J|28n$I@nAD0c1%9C&IVhEZX~mUsf{efyS(XNG%ch;!N~d7S(Ri7 zb&=BuON95aVA&kLn6&MVU|x}xPMp7xwWxNU1wS+F6#y}1@^wQZB*(&ecT?RnQcI}Y z2*z!^!D?gDUhc@;M^OpLs4mq>C&p{}OWVv<)S9KMars@0JQ{c_ScGsFo3BJ)Irg++ zAWwypJdTO-_{Uh8m(Z!3KL7K{ZZzKHj;{M8I$mV>k znTM?sa0);^=X^cglL`uC+^J)M7nEa$w=VwFULg~%DJllw+7dJAj3{qnP5i3@wr7%y zjXp?Wl2%Th=my&3u?Q$RV6N5tzKMSPTsc#J+-cDDp~qFB6bL2C8AS7Y3PKtVhdhl) zIaLqH5+OnWPWSt(lQCgkN8lczc-V%_iZ{>#1%Z$N*>lu#S;0MZ$T2Y8Kg!U;hAZj> z6S#%$DQ_`Ic%Zr@?}GgjRXg@qTj^17n`65oJ@Wj0u1X8&+UVd|Xs?J+i_^GZ94m6= zUc96~Q`OJvlKB_Lr15*Yw_PUPEr?f?H&00b^-W%26mD)(n(rGGNfK9~2h=C>p-7BZ zFd&*&Msdu{w~(eyFOglwCPH^Rb}O(N7LtS+nnEwDx*pGD?|&9Si~M43a+*L(b0$5A zv`T`(G3xO;I_sx;FwTP21ZlfDpz zOo?}Vlgf~fo{YWm@n_JyD*frOg{XsvBA~|Tn4V6hu>Gd>89-rblfVJUaGvj6X%NZ} z$tFF9sx=4_$*c~G`9iPLGh@=sV+O{D2-t*K@J7H=`V+oVt}8?04WwU3h1BgS!f%1P zFak-T#7`TtLcR=Yz>g0R!ZQrH!YiZOQN=_V-UyncN1Rc18?KY?#O`v#JK+pq0K$~H z3D@v9DZF42R)b9#BBX{^$DOMlJ!g)Gc za{o-1e%F6NvgKq9tC8pV+9S$;9*zNv{J*)n&dmf~anP1)4~N%~h#c(=B#3*KgzhCKhFdgDoWi2IDog{RVyzK|Y`rCUs3T~pJMmdZJy4?b z&s5G=zhf**(t7Y^oC_mcTsE-{^}wiaoUu&?kojLKs>SJPxjcP>{a5CbXCx92AcBE) zHtqP}LjZ{W>PH?Tu(E0X=%{PBMW@F_?#7b&#!^q`<-5$ur+-q6 z{dn=(^UZw6*3-XM_(=@<1_*i&XM4=0t5u!gm6 z{UlmNGPKgO_;e;q9|#esq~Sq`<}%d{+sRmhvsA{5i*91=tub>OZZ%)xUA#4q$dDyy z1`w4%?OPLg3JeZb#cqSMO?*Xn%|-FCcuH2i2fn_{IFusub6;NQdN|7TD1N?%E8*g? z$apAt@cEe!I%jB=*q$p_3=t_5R0ph%{qaq+QDg!c99Y!Xa!&oDZOeis_ot)gNXr{l zdY$|So2Qed2Y7KMNBrS^E169kG%h<+z{Z_p_;shB!uY)>yAVcK=&!bg`lVg)4T1|7 z0}7FpfydVH4F87K@c!nEG+WGKm{Ouo)Slpl;#qcEIQ0zdMfLA#;dBxYw;p;KoVv6| z3_D5&7rJdG12CnDSvZUW?$UC6^UVSW^|vw|o-_4bz)(w5(3AiVhpeT(|=f#x_}E?s#qHZF#xA6AF_ujl$G z-jHD%q(d2}v2PhXx&6YWps~m(^+RXl91Q#xRRJBhjKl$FG4bk);|ag;ieUZ&!Ii3$ z(iGz1+0m7#g5>ASldBbNZL=ZHh=tmmJt$!71; zIML2GhEz1pg@1rQN(M^_691wAGkJ@Pga_05WuQ6! zG5RkGY2^`@(H~pp7&Ga+Pwh3L!Njj!-rc;^bTIfo5hP@H##1X8xUZJckrx>id`bAd3QUx9GuomqBYZ!uN1-&o zvTxC?;p8vL67&fW8fw(YOqt>L@bdLrEF*3OgYe$4n4{ zEB40LiU#6-0@5jdN`0w}N0qi@c0~oT2FP z)LNk&a82my?jv(tQpiMi$TK_L@lub#lsM$R{Dk?Ya@%%%huZkct~tSWM714c!45k}-ZLVA-bVM`>|_ZBbW_m-7| z3U%xrAhi}n?T(2F{_n4EZ10inkIFl#y09?7$uwBoJgqY8vylwev)fDOn;>0R!aEnV zBz%j0Mqpx~EZU3q@%+oV7;}|vt7$~ou@faEIq{p?FY$XXg&6*K)b_LP=}gi9`Bij3 zN`zEo|B6*|-;>S`rNa^BKRDbDAk>X#MsR`EvL>6bqU@SaDDs z8>bu@3YdRaWs*Te@G-UHjU%F~kTHw5(0PVJ+pwh#ha2u;DB+UMo@A5UYIl#5rtBV- zGX_hIpw}3C@H*Us(Cc-d#-gNrG#w$(9+S=GxO>3SR`SE2fHZ2KrDc#_C^$jI>Y}#; zMwY=R6@+dWi~0RXw(c@3GZ&%~9K(q&ee0Zw;pwL`E_tZak-#8^_b)Dpyi73^he?xV zXJ08&wh5-M&}qy4f7!D&=E)puDD(Nmg1d_(j`4LvxM5x_huNg-pGG%9rYqO6mImyJ@}*3Y>^3OvcnTG%EV1) zq_Ap?Z!Iw__7#D=pOWnQN$gB!Mr0!9yx|g<4icJh{cFOu3B8}&RiYm+Mb;VEK``LK zL(NcpcTiGieOIssSjr?ob}^``nNf&UcJhXyncO9m{6gD$kqSD`S69(aF8dkWz5>!9 zBLe4Sib7Hs2x_L2Ls6Ish$MGVKrGt5+_2zCyP1byaCg3upo+-I}R4&$m)8 zQ7|jc1Z^VWggpuQj*cP;>Zo9LS!VSzrqmZczaf;u`d0J(f%Z9r%An@s!e>n9%y=n!IZ_tVGu{Jmsbp}Fk%HJIU?a+-~bjfLTuH|JExA8EROowzr zqW9{YyZhR0a4clRK>1I4Ncx&WER~{iE;F^$T7K%X@3PGOA%6#Z%p3TS^&M;Dnjw@i z^o!$9nhcsmcHcY4?4j9+ofL_CWsZ4Hcch(rjsGfGD(nsH>w}^ERqGnz%iGj0j{g}h z7wMkJ-2Z2~eS>2!i}0~B63i;>SyFJU2+>VCS^AxaDOx%g6-t0eM^P<3+*z`ztvOqrG3)&#$K?& z_Y0wbWID47@cU`E1A6A&!`aZk0ZE@z-h#l1NqX2#`$Uev2gepW`rf8*!=rD5&;Jb{ zl08rU>dPo=K%-1Ao1~G-@4ve~y5#9E8x;TE0k5d^TC(=Zc>mwjW^c=+U-<9}b0ku~}gj z3sbW>R2M6DR!g#NUP;nxo>)@7*=RP{U18SDop6b2&PHce^&h97@xx3t+VK+!keE#} z;(Uf&89as9k8{$nkLbuB!-d7TP`_VJpL^Xs8OKB~ri$YUbW8fch64}7|0EWoT(TRj{ z*GT<7Y<7DsrCi79ZsM)z#c(!nNOGySOCkY1fAuQOq12&iUVC!a`#O;dBLf=d?&4*B zI~LgAO7E0qxK(uRTM;IgJ}+z^gD+bi-6I!3x{r9`l~%8TRP%UE0V8E*Sz>Nl1NVG<<7(wDHZ+HcOkQm$O&k+vyx)y)x{Pz!U8hS$*m zByc0h6BUI*BOpuL==P+H|Hx%`>7!W+1H!l9vi&)`V zyn2o9{z=lc+VX*!Vh~SF=)L}Z40XeG>LF6cP^b+R$NxSeUqbK^Q*UTalKzP8X%{9@RSCXm_NhF>{=S2 zi}ezam_^P`S!!-cyEW9y7DBbK93roz@Raccy*v}?mKXScU9E_4g;hBU7}zSofAFda zKYEe?{{I54 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index df97d72b8..c1d5e0185 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 1aa94a426..f5feea6d6 100755 --- a/gradlew +++ b/gradlew @@ -15,6 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. # +# SPDX-License-Identifier: Apache-2.0 +# ############################################################################## # @@ -55,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -84,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum diff --git a/gradlew.bat b/gradlew.bat index 25da30dbd..9d21a2183 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,6 +13,8 @@ @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## diff --git a/paperweight-core/build.gradle.kts b/paperweight-core/build.gradle.kts index 3b2c1fc1c..41daa345b 100644 --- a/paperweight-core/build.gradle.kts +++ b/paperweight-core/build.gradle.kts @@ -10,8 +10,8 @@ configurations.implementation { dependencies { shade(projects.paperweightLib) - shade(project(projects.paperweightLib.dependencyProject.path, "sharedRuntime")) - restamp(project(projects.paperweightLib.dependencyProject.path, "restampRuntime")) + shade(project(projects.paperweightLib.path, "sharedRuntime")) + restamp(project(projects.paperweightLib.path, "restampRuntime")) implementation(libs.bundles.kotson) implementation(libs.coroutines) @@ -41,6 +41,7 @@ val finalRuntimeElements by configurations.registering { attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, objects.named(LibraryElements.JAR)) attribute(Usage.USAGE_ATTRIBUTE, objects.named(Usage.JAVA_RUNTIME)) } + compatibilityAttributes(objects) outgoing.artifact(finalJar) } val javaComponent = project.components.getByName("java") as AdhocComponentWithVariants diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt index c56916224..824a1d0ae 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt @@ -44,11 +44,10 @@ class PaperweightCore : Plugin { } override fun apply(target: Project) { - checkJavaVersion() Git.checkForGit() printId("paperweight-core", target.gradle) - val ext = target.extensions.create(PAPERWEIGHT_EXTENSION, PaperweightCoreExtension::class, target) + val ext = target.extensions.create(PAPERWEIGHT_EXTENSION, PaperweightCoreExtension::class) target.gradle.sharedServices.registerIfAbsent(DOWNLOAD_SERVICE_NAME, DownloadService::class) { parameters.projectPath.set(target.projectDir) @@ -77,15 +76,7 @@ class PaperweightCore : Plugin { } val tasks = AllTasks(target) - val devBundleTasks = DevBundleTasks(target) - - val bundlerJarTasks = BundlerJarTasks( - target, - ext.bundlerJarName, - ext.mainClass - ) - val softSpoonTasks = SoftSpoonTasks(target, tasks) val jar = target.tasks.named("jar", AbstractArchiveTask::class) @@ -100,6 +91,11 @@ class PaperweightCore : Plugin { ext.paper.reobfPackagesToFix, tasks.generateRelocatedReobfMappings ) + val bundlerJarTasks = BundlerJarTasks( + target, + ext.bundlerJarName, + ext.mainClass + ) bundlerJarTasks.configureBundlerTasks( tasks.extractFromBundler.flatMap { it.versionJson }, tasks.extractFromBundler.flatMap { it.serverLibrariesList }, @@ -144,12 +140,10 @@ class PaperweightCore : Plugin { target.afterEvaluate { target.repositories { - /* TODO maven(ext.remapRepo) { name = REMAPPER_REPO_NAME content { onlyForConfigurations(REMAPPER_CONFIG) } } - */ maven(ext.macheRepo) { name = MACHE_REPO_NAME content { onlyForConfigurations(MACHE_CONFIG) } diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt index 62d5f152d..4c1e83a68 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/extension/PaperweightCoreExtension.kt @@ -23,9 +23,7 @@ package io.papermc.paperweight.core.extension import io.papermc.paperweight.util.constants.* -import java.util.Locale import org.gradle.api.Action -import org.gradle.api.Project import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.ProjectLayout import org.gradle.api.model.ObjectFactory @@ -33,13 +31,13 @@ import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property import org.gradle.kotlin.dsl.* -open class PaperweightCoreExtension(project: Project, objects: ObjectFactory, layout: ProjectLayout) { +open class PaperweightCoreExtension(objects: ObjectFactory, layout: ProjectLayout) { val minecraftVersion: Property = objects.property() val minecraftManifestUrl: Property = objects.property().convention(MC_MANIFEST_URL) val mainClass: Property = objects.property().convention("org.bukkit.craftbukkit.Main") - val bundlerJarName: Property = objects.property().convention(project.name.lowercase(Locale.ENGLISH)) + val bundlerJarName: Property = objects.property().convention("paper") val remapRepo: Property = objects.property().convention(PAPER_MAVEN_REPO_URL) val macheRepo: Property = objects.property().convention(PAPER_MAVEN_REPO_URL) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt index 4c10273ad..6a6bbf7b3 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt @@ -31,6 +31,7 @@ import kotlin.io.path.* import org.gradle.api.Project import org.gradle.api.artifacts.repositories.MavenArtifactRepository import org.gradle.api.file.RegularFile +import org.gradle.api.plugins.JavaPlugin import org.gradle.api.provider.Property import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskContainer @@ -102,7 +103,7 @@ class DevBundleTasks( serverVersion.set(serverProj.version.toString()) serverCoordinates.set(GenerateDevBundle.createCoordinatesFor(serverProj)) serverProject.set(serverProj) - runtimeConfiguration.set(project.configurations.named(SERVER_RUNTIME_CLASSPATH)) + runtimeConfiguration.set(project.configurations.named(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)) decompiledJar.pathProvider(decompileJar) atFile.pathProvider(accessTransformFile) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt index 1ee5f179e..42428e23e 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt @@ -50,8 +50,6 @@ const val DEV_BUNDLE_CONFIG = "paperweightDevelopmentBundle" const val MOJANG_MAPPED_SERVER_CONFIG = "mojangMappedServer" const val MOJANG_MAPPED_SERVER_RUNTIME_CONFIG = "mojangMappedServerRuntime" const val REOBF_CONFIG = "reobf" -const val CONSUMABLE_RUNTIME_CLASSPATH = "consumableRuntimeClasspath" -const val SERVER_RUNTIME_CLASSPATH = "serverRuntimeClasspath" const val PARAM_MAPPINGS_REPO_NAME = "paperweightParamMappingsRepository" const val DECOMPILER_REPO_NAME = "paperweightDecompilerRepository" @@ -77,9 +75,6 @@ private const val JARS_PATH = "$PAPER_PATH/jars" const val MINECRAFT_JARS_PATH = "$JARS_PATH/minecraft" const val MINECRAFT_SOURCES_PATH = "$JARS_PATH/minecraft-sources" -const val SPIGOT_JARS_PATH = "$JARS_PATH/spigot" -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" @@ -92,11 +87,9 @@ const val OBF_SPIGOT_MAPPINGS = "$MAPPINGS_DIR/official-spigot.tiny" const val SPIGOT_MEMBER_MAPPINGS = "$MAPPINGS_DIR/spigot-members.csrg" const val CLEANED_SPIGOT_MOJANG_YARN_MAPPINGS = "$MAPPINGS_DIR/spigot-mojang+yarn-cleaned.tiny" const val PATCHED_SPIGOT_MOJANG_YARN_MAPPINGS = "$MAPPINGS_DIR/spigot-mojang+yarn-patched.tiny" -const val PATCHED_SPIGOT_MOJANG_YARN_SOURCE_MAPPINGS = "$MAPPINGS_DIR/spigot-mojang+yarn-patched-source.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 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 SPIGOT_NAMESPACE = "spigot" @@ -118,11 +111,8 @@ const val SERVER_JAR = "$BUNDLER_PATH/server.jar" private const val SETUP_CACHE = "$PAPER_PATH/setupCache" private const val TASK_CACHE = "$PAPER_PATH/taskCache" -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_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" @@ -132,11 +122,8 @@ const val IVY_REPOSITORY = "$PAPER_PATH/ivyRepository" 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 Task.paperTaskOutput(ext: String) = paperTaskOutput(name, ext) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt index 655b7c053..ffe5b78e3 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt @@ -32,7 +32,6 @@ import io.papermc.paperweight.util.constants.* import java.io.File import java.io.InputStream import java.io.OutputStream -import java.lang.management.ManagementFactory import java.lang.reflect.Type import java.net.URI import java.net.URL @@ -384,19 +383,6 @@ private fun javaVersion(): Int { } } -fun checkJavaVersion() { - val minimumJava = 11 - val ver = javaVersion() - if (ver < minimumJava) { - var msg = "paperweight requires Gradle to be run with a Java $minimumJava runtime or newer." - val runtimeMX = ManagementFactory.getRuntimeMXBean() - if (runtimeMX != null) { - msg += " Current runtime: Java ${runtimeMX.specVersion} (${runtimeMX.vmName} ${runtimeMX.vmVersion})" - } - throw PaperweightException(msg) - } -} - inline fun printId(pluginId: String, gradle: Gradle) { if (gradle.startParameter.logLevel == LogLevel.QUIET) { return diff --git a/paperweight-patcher/build.gradle.kts b/paperweight-patcher/build.gradle.kts index 3e4e1c4ec..372c332ed 100644 --- a/paperweight-patcher/build.gradle.kts +++ b/paperweight-patcher/build.gradle.kts @@ -5,7 +5,7 @@ plugins { dependencies { shade(projects.paperweightLib) - shade(project(projects.paperweightLib.dependencyProject.path, "sharedRuntime")) + shade(project(projects.paperweightLib.path, "sharedRuntime")) implementation(libs.bundles.kotson) } diff --git a/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/PaperweightPatcher.kt b/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/PaperweightPatcher.kt index 49f808c6d..bce303d6b 100644 --- a/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/PaperweightPatcher.kt +++ b/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/PaperweightPatcher.kt @@ -48,7 +48,6 @@ import org.gradle.kotlin.dsl.registering class PaperweightPatcher : Plugin { override fun apply(target: Project) { - checkJavaVersion() Git.checkForGit() printId("paperweight-patcher", target.gradle) diff --git a/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/tasks/PaperweightPatcherUpstreamData.kt b/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/tasks/PaperweightPatcherUpstreamData.kt index c18988a4f..f3a350402 100644 --- a/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/tasks/PaperweightPatcherUpstreamData.kt +++ b/paperweight-patcher/src/main/kotlin/io/papermc/paperweight/patcher/tasks/PaperweightPatcherUpstreamData.kt @@ -36,6 +36,7 @@ import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.UntrackedTask import org.gradle.internal.build.NestedRootBuildRunner +import org.gradle.internal.service.ServiceRegistry @UntrackedTask(because = "Nested build does it's own up-to-date checking") abstract class PaperweightPatcherUpstreamData : BaseTask() { @@ -64,6 +65,11 @@ abstract class PaperweightPatcherUpstreamData : BaseTask() { params.systemPropertiesArgs[PAPERWEIGHT_DEBUG] = System.getProperty(PAPERWEIGHT_DEBUG, "false") - NestedRootBuildRunner.runNestedRootBuild(null, params as StartParameterInternal, services) + NestedRootBuildRunner::class.java.getDeclaredMethod( + "runNestedRootBuild", + String::class.java, + StartParameterInternal::class.java, + ServiceRegistry::class.java + ).invoke(null, null, params, services) } } diff --git a/paperweight-userdev/build.gradle.kts b/paperweight-userdev/build.gradle.kts index 784dea566..114b3a081 100644 --- a/paperweight-userdev/build.gradle.kts +++ b/paperweight-userdev/build.gradle.kts @@ -5,7 +5,7 @@ plugins { dependencies { shade(projects.paperweightLib) - shade(project(projects.paperweightLib.dependencyProject.path, "sharedRuntime")) + shade(project(projects.paperweightLib.path, "sharedRuntime")) implementation(libs.bundles.kotson) implementation(variantOf(libs.diffpatch) { classifier("all") }) { isTransitive = false diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt index b2cca41cc..6124b8e2a 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt @@ -63,8 +63,6 @@ abstract class PaperweightUser : Plugin { abstract val javaToolchainService: JavaToolchainService override fun apply(target: Project) { - checkJavaVersion() - val sharedCacheRoot = target.gradle.gradleUserHomeDir.toPath().resolve("caches/paperweight-userdev") target.gradle.sharedServices.registerIfAbsent(DOWNLOAD_SERVICE_NAME, DownloadService::class) { From b23d0bda68169112cda70e0800be9f4f0e22f47b Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Sun, 8 Dec 2024 15:01:54 -0700 Subject: [PATCH 26/38] Initial work on updating userdev --- .../paperweight/core/PaperweightCore.kt | 16 +- .../core/taskcontainers/SoftSpoonTasks.kt | 74 ++--- .../paperweight/attribute/DevBundleOutput.kt | 38 +++ .../{util => attribute}/MacheOutput.kt | 2 +- .../taskcontainers/DevBundleTasks.kt | 34 +-- .../paperweight/tasks/GenerateDevBundle.kt | 204 +++---------- .../paperweight/tasks/mache/DecompileJar.kt | 80 +++-- .../paperweight/tasks/mache/RemapJar.kt | 75 +++-- .../paperweight/util/constants/constants.kt | 6 +- .../paperweight/util/data/mache/MacheMeta.kt | 62 +++- .../io/papermc/paperweight/util/utils.kt | 6 + .../paperweight/userdev/PaperweightUser.kt | 97 +++--- .../internal/setup/ExtractDevBundle.kt | 8 +- .../userdev/internal/setup/SetupHandler.kt | 18 +- .../internal/setup/SetupHandlerImpl.kt | 154 +++++----- .../userdev/internal/setup/UserdevSetup.kt | 11 +- .../setup/step/ApplyDevBundlePatches.kt | 20 ++ .../setup/step/MinecraftSourcesMache.kt | 105 +++++++ .../setup/step/RemapMinecraftMache.kt | 105 +++++++ .../internal/setup/v2/SetupHandlerImplV2.kt | 3 + .../userdev/internal/setup/v5/DevBundleV5.kt | 54 ++++ .../internal/setup/v5/SetupHandlerImplV5.kt | 289 ++++++++++++++++++ 22 files changed, 1037 insertions(+), 424 deletions(-) create mode 100644 paperweight-lib/src/main/kotlin/io/papermc/paperweight/attribute/DevBundleOutput.kt rename paperweight-lib/src/main/kotlin/io/papermc/paperweight/{util => attribute}/MacheOutput.kt (96%) create mode 100644 paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/MinecraftSourcesMache.kt create mode 100644 paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RemapMinecraftMache.kt create mode 100644 paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v5/DevBundleV5.kt create mode 100644 paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v5/SetupHandlerImplV5.kt diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt index 824a1d0ae..73d9df019 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt @@ -23,6 +23,7 @@ package io.papermc.paperweight.core import io.papermc.paperweight.DownloadService +import io.papermc.paperweight.attribute.MacheOutput import io.papermc.paperweight.core.extension.PaperweightCoreExtension import io.papermc.paperweight.core.taskcontainers.AllTasks import io.papermc.paperweight.core.taskcontainers.SoftSpoonTasks @@ -176,31 +177,22 @@ class PaperweightCore : Plugin { tasks.generateRelocatedReobfMappings, serverJar ) ?: return@afterEvaluate + */ devBundleTasks.configure( - ext.serverProject.get(), ext.bundlerJarName.get(), ext.mainClass, ext.minecraftVersion, - tasks.decompileJar.map { it.outputJar.path }, - tasks.extractFromBundler.map { it.serverLibrariesTxt.path }, + softSpoonTasks.setupMacheSourcesForDevBundle.flatMap { it.outputDir }, tasks.extractFromBundler.map { it.serverLibrariesList.path }, tasks.downloadServerJar.map { it.outputJar.path }, - tasks.mergeAdditionalAts.map { it.outputFile.path }, tasks.extractFromBundler.map { it.versionJson.path }.convertToFileProvider(layout, providers) ) { - vanillaJarIncludes.set(ext.vanillaJarIncludes) reobfMappingsFile.set(tasks.generateRelocatedReobfMappings.flatMap { it.outputMappings }) - - paramMappingsCoordinates.set( - target.provider { - determineArtifactCoordinates(target.configurations.getByName(PARAM_MAPPINGS_CONFIG)).single() - } - ) - paramMappingsUrl.set(ext.paramMappingsRepo) } devBundleTasks.configureAfterEvaluate() + /* bundlerJarTasks.configureBundlerTasks( tasks.extractFromBundler.flatMap { it.versionJson }, tasks.extractFromBundler.flatMap { it.serverLibrariesList }, diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt index 3aac713d2..5c8abd0c6 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt @@ -38,7 +38,6 @@ import io.papermc.paperweight.util.* import io.papermc.paperweight.util.constants.* import io.papermc.paperweight.util.data.mache.* import java.nio.file.Files -import kotlin.io.path.* import org.gradle.api.Project import org.gradle.api.Task import org.gradle.api.plugins.JavaPlugin @@ -56,19 +55,19 @@ open class SoftSpoonTasks( private val mache: Property = project.objects.property() - val macheCodebook by project.configurations.registering { + val macheCodebook = project.configurations.register(MACHE_CODEBOOK_CONFIG) { isTransitive = false } - val macheRemapper by project.configurations.registering { + val macheRemapper = project.configurations.register(MACHE_REMAPPER_CONFIG) { isTransitive = false } - val macheDecompiler by project.configurations.registering { + val macheDecompiler = project.configurations.register(MACHE_DECOMPILER_CONFIG) { isTransitive = false } - val macheParamMappings by project.configurations.registering { + val macheParamMappings = project.configurations.register(MACHE_PARAM_MAPPINGS_CONFIG) { isTransitive = false } - val macheConstants by project.configurations.registering { + val macheConstants = project.configurations.register(MACHE_CONSTANTS_CONFIG) { isTransitive = false } val macheMinecraftLibraries by project.configurations.registering @@ -117,30 +116,39 @@ open class SoftSpoonTasks( secondFile.set(collectAccessTransform.flatMap { it.outputFile }) } - val setupMacheSources by tasks.registering(SetupVanilla::class) { + private fun SetupVanilla.configureSetupMacheSources() { group = "mache" - description = "Setup vanilla source dir (applying mache patches and paper ATs)." mache.from(project.configurations.named(MACHE_CONFIG)) macheOld.set(project.ext.macheOldPath) machePatches.set(layout.cache.resolve(PATCHES_FOLDER)) - ats.set(mergeCollectedAts.flatMap { it.outputFile }) minecraftClasspath.from(macheMinecraftLibraries) - 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 setupMacheSources by tasks.registering(SetupVanilla::class) { + description = "Setup vanilla source dir (applying mache patches and paper ATs)." + configureSetupMacheSources() + libraries.from( + allTasks.downloadPaperLibrariesSources.flatMap { it.outputDir }, + allTasks.downloadMcLibrariesSources.flatMap { it.outputDir } + ) + ats.set(mergeCollectedAts.flatMap { it.outputFile }) + outputDir.set(layout.cache.resolve(BASE_PROJECT).resolve("sources")) restamp.from(restampConfig) } + val setupMacheSourcesForDevBundle by tasks.registering(SetupVanilla::class) { + description = "Setup vanilla source dir (applying mache patches)." + configureSetupMacheSources() + outputDir.set(layout.cache.resolve(BASE_PROJECT).resolve("sources_dev_bundle")) + } + val setupMacheResources by tasks.registering(SetupVanilla::class) { group = "mache" description = "Setup vanilla resources dir" @@ -272,11 +280,7 @@ open class SoftSpoonTasks( fun afterEvaluate() { // load mache - mache.set( - project.configurations.getByName(MACHE_CONFIG).singleFile.toPath().openZip().use { zip -> - gson.fromJson(zip.getPath("/mache.json").readLines().joinToString("\n")) - } - ) + mache.set(project.configurations.resolveMacheMeta()) val mache = mache.get() println("Loaded mache ${mache.macheVersion} for minecraft ${mache.minecraftVersion}") @@ -285,19 +289,7 @@ open class SoftSpoonTasks( } // 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 + ".*") - } - } - } - } - } + mache.addRepositories(project) // setup mc deps macheMinecraftLibraries { @@ -315,23 +307,7 @@ open class SoftSpoonTasks( } // 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()) - } - } + mache.addDependencies(project) // impl extends minecraft project.configurations.named(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME) { diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/attribute/DevBundleOutput.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/attribute/DevBundleOutput.kt new file mode 100644 index 000000000..e4c2d2db7 --- /dev/null +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/attribute/DevBundleOutput.kt @@ -0,0 +1,38 @@ +/* + * 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.attribute + +import org.gradle.api.Named +import org.gradle.api.attributes.Attribute + +interface DevBundleOutput : Named { + companion object { + val ATTRIBUTE = Attribute.of( + "io.papermc.paperweight.dev-bundle-output", + DevBundleOutput::class.java + ) + + const val ZIP = "zip" + const val SERVER_DEPENDENCIES = "serverDependencies" + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/MacheOutput.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/attribute/MacheOutput.kt similarity index 96% rename from paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/MacheOutput.kt rename to paperweight-lib/src/main/kotlin/io/papermc/paperweight/attribute/MacheOutput.kt index b433ca887..8c0717db5 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/MacheOutput.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/attribute/MacheOutput.kt @@ -20,7 +20,7 @@ * USA */ -package io.papermc.paperweight.util +package io.papermc.paperweight.attribute import org.gradle.api.Named import org.gradle.api.attributes.Attribute diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt index 6a6bbf7b3..ff85a3d82 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt @@ -27,11 +27,10 @@ import io.papermc.paperweight.tasks.* import io.papermc.paperweight.util.* import io.papermc.paperweight.util.constants.* import java.nio.file.Path -import kotlin.io.path.* import org.gradle.api.Project import org.gradle.api.artifacts.repositories.MavenArtifactRepository +import org.gradle.api.file.Directory import org.gradle.api.file.RegularFile -import org.gradle.api.plugins.JavaPlugin import org.gradle.api.provider.Property import org.gradle.api.provider.Provider import org.gradle.api.tasks.TaskContainer @@ -54,21 +53,20 @@ class DevBundleTasks( val generateDevelopmentBundle by tasks.registering { group = "paperweight" + macheConfig.set(project.configurations.named(MACHE_CONFIG)) + pluginRemapperConfig.set(project.configurations.named(REMAPPER_CONFIG)) devBundleFile.set(project.layout.buildDirectory.file("libs/paperweight-development-bundle-${project.version}.zip")) ignoreUnsupportedEnvironment.set(project.providers.gradleProperty(GenerateDevBundle.unsupportedEnvironmentPropName).map { it.toBoolean() }) } fun configure( - serverProj: Project, bundlerJarName: String, mainClassName: Property, minecraftVer: Provider, - decompileJar: Provider, - serverLibrariesTxt: Provider, + vanillaJava: Provider, serverLibrariesListFile: Provider, vanillaBundlerJarFile: Provider, - accessTransformFile: Provider, versionJsonFile: Provider, devBundleConfiguration: GenerateDevBundle.() -> Unit ) { @@ -80,7 +78,7 @@ class DevBundleTasks( registerVersionArtifact( bundlerJarName, versionJsonFile, - serverProj.tasks.named("includeMappings").flatMap { it.outputJar } + project.tasks.named("includeMappings").flatMap { it.outputJar } ) } } @@ -91,22 +89,12 @@ class DevBundleTasks( } generateDevelopmentBundle { - sourceDir.set(serverProj.layout.projectDirectory.dir("src/main/java")) + mainJavaDir.set(project.layout.projectDirectory.dir("src/main/java")) + vanillaJavaDir.set(vanillaJava) + patchedJavaDir.set(project.layout.projectDirectory.dir("src/vanilla/java")) + minecraftVersion.set(minecraftVer) mojangMappedPaperclipFile.set(paperclipForDevBundle.flatMap { it.outputZip }) - vanillaServerLibraries.set( - serverLibrariesTxt.map { txt -> - txt.readLines(Charsets.UTF_8).filter { it.isNotBlank() } - } - ) - - serverVersion.set(serverProj.version.toString()) - serverCoordinates.set(GenerateDevBundle.createCoordinatesFor(serverProj)) - serverProject.set(serverProj) - runtimeConfiguration.set(project.configurations.named(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)) - - decompiledJar.pathProvider(decompileJar) - atFile.pathProvider(accessTransformFile) devBundleConfiguration(this) } @@ -114,8 +102,8 @@ class DevBundleTasks( fun configureAfterEvaluate() { generateDevelopmentBundle { - remapperUrl.set(project.repositories.named(REMAPPER_REPO_NAME).map { it.url.toString() }) - decompilerUrl.set(project.repositories.named(DECOMPILER_REPO_NAME).map { it.url.toString() }) + pluginRemapperUrl.set(project.repositories.named(REMAPPER_REPO_NAME).map { it.url.toString() }) + macheUrl.set(project.repositories.named(MACHE_REPO_NAME).map { it.url.toString() }) } } } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateDevBundle.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateDevBundle.kt index 1d1f264dd..15aaf1b2e 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateDevBundle.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateDevBundle.kt @@ -25,44 +25,39 @@ package io.papermc.paperweight.tasks import io.papermc.paperweight.PaperweightException import io.papermc.paperweight.util.* import io.papermc.paperweight.util.constants.* -import io.papermc.paperweight.util.data.* import java.io.ByteArrayOutputStream import java.nio.charset.Charset import java.nio.file.Files import java.nio.file.Path -import java.util.Locale import java.util.concurrent.TimeUnit import java.util.regex.Pattern import javax.inject.Inject import kotlin.io.path.* import org.gradle.api.DefaultTask -import org.gradle.api.Project import org.gradle.api.artifacts.Configuration -import org.gradle.api.artifacts.ExternalModuleDependency -import org.gradle.api.artifacts.component.ModuleComponentIdentifier -import org.gradle.api.artifacts.result.ResolvedArtifactResult import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.ProjectLayout import org.gradle.api.file.RegularFileProperty -import org.gradle.api.plugins.JavaPlugin import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property import org.gradle.api.tasks.Classpath import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.InputFile -import org.gradle.api.tasks.Internal import org.gradle.api.tasks.Optional import org.gradle.api.tasks.OutputFile import org.gradle.api.tasks.TaskAction abstract class GenerateDevBundle : DefaultTask() { - @get:InputFile - abstract val decompiledJar: RegularFileProperty + @get:InputDirectory + abstract val mainJavaDir: DirectoryProperty + + @get:InputDirectory + abstract val vanillaJavaDir: DirectoryProperty @get:InputDirectory - abstract val sourceDir: DirectoryProperty + abstract val patchedJavaDir: DirectoryProperty @get:Input abstract val minecraftVersion: Property @@ -70,54 +65,24 @@ abstract class GenerateDevBundle : DefaultTask() { @get:InputFile abstract val mojangMappedPaperclipFile: RegularFileProperty - @get:Input - abstract val serverVersion: Property - - @get:Input - abstract val serverCoordinates: Property - - @get:Input - abstract val apiCoordinates: Property - - @get:Input - abstract val vanillaJarIncludes: ListProperty - - @get:Input - abstract val vanillaServerLibraries: ListProperty - @get:Input abstract val libraryRepositories: ListProperty - @get:Internal - abstract val serverProject: Property - - @get:Classpath - abstract val runtimeConfiguration: Property - - @get:Input - abstract val paramMappingsUrl: Property - @get:Input - abstract val paramMappingsCoordinates: Property - - @get:Input - abstract val decompilerUrl: Property + abstract val pluginRemapperUrl: Property @get:Classpath - abstract val decompilerConfig: Property + abstract val pluginRemapperConfig: Property @get:Input - abstract val remapperUrl: Property + abstract val macheUrl: Property @get:Classpath - abstract val remapperConfig: Property + abstract val macheConfig: Property @get:InputFile abstract val reobfMappingsFile: RegularFileProperty - @get:InputFile - abstract val atFile: RegularFileProperty - @get:OutputFile abstract val devBundleFile: RegularFileProperty @@ -154,7 +119,6 @@ abstract class GenerateDevBundle : DefaultTask() { dataZip.createDirectories() reobfMappingsFile.path.copyTo(dataZip.resolve(reobfMappingsFileName)) mojangMappedPaperclipFile.path.copyTo(dataZip.resolve(mojangMappedPaperclipFileName)) - atFile.path.copyTo(dataZip.resolve(atFileName)) val patchesZip = zip.getPath(patchesDir) tempPatchDir.copyRecursivelyTo(patchesZip) @@ -168,33 +132,32 @@ abstract class GenerateDevBundle : DefaultTask() { val workingDir = layout.cache.resolve(paperTaskOutput("tmpdir")) workingDir.deleteRecursive() workingDir.createDirectories() - sourceDir.path.copyRecursivelyTo(workingDir) + mainJavaDir.path.copyRecursivelyTo(workingDir) + patchedJavaDir.path.copyRecursivelyTo(workingDir) + workingDir.resolve(".git").deleteRecursive() Files.walk(workingDir).use { stream -> - decompiledJar.path.openZip().use { decompJar -> - val decompRoot = decompJar.rootDirectories.single() - - for (file in stream) { - if (file.isDirectory()) { - continue - } - val relativeFile = file.relativeTo(workingDir) - val relativeFilePath = relativeFile.invariantSeparatorsPathString - val decompFile = decompRoot.resolve(relativeFilePath) - - if (decompFile.notExists()) { - val outputFile = output.resolve(relativeFilePath) + val oldSrc = vanillaJavaDir.path + for (file in stream) { + if (file.isDirectory()) { + continue + } + val relativeFile = file.relativeTo(workingDir) + val relativeFilePath = relativeFile.invariantSeparatorsPathString + val decompFile = oldSrc.resolve(relativeFilePath) + + if (decompFile.exists()) { + val diffText = diffFiles(relativeFilePath, decompFile, file) + val patchName = relativeFile.name + ".patch" + val outputFile = output.resolve(relativeFilePath).resolveSibling(patchName) + if (diffText.isNotBlank()) { outputFile.parent.createDirectories() - file.copyTo(outputFile) - } else { - val diffText = diffFiles(relativeFilePath, decompFile, file) - val patchName = relativeFile.name + ".patch" - val outputFile = output.resolve(relativeFilePath).resolveSibling(patchName) - if (diffText.isNotBlank()) { - outputFile.parent.createDirectories() - outputFile.writeText(diffText) - } + outputFile.writeText(diffText) } + } else { + val outputFile = output.resolve(relativeFilePath) + outputFile.parent.createDirectories() + file.copyTo(outputFile) } } } @@ -260,118 +223,41 @@ abstract class GenerateDevBundle : DefaultTask() { private fun createBundleConfig(dataTargetDir: String, patchTargetDir: String): DevBundleConfig { return DevBundleConfig( minecraftVersion = minecraftVersion.get(), - mappedServerCoordinates = serverCoordinates.get(), - apiCoordinates = "${apiCoordinates.get()}:${serverVersion.get()}", - buildData = createBuildDataConfig(dataTargetDir), - decompile = createDecompileRunner(), - remapper = createRemapDep(), - patchDir = patchTargetDir - ) - } - - private fun createBuildDataConfig(targetDir: String): BuildData { - return BuildData( - paramMappings = MavenDep(paramMappingsUrl.get(), listOf(paramMappingsCoordinates.get())), - reobfMappingsFile = "$targetDir/$reobfMappingsFileName", - accessTransformFile = "$targetDir/$atFileName", - mojangMappedPaperclipFile = "$targetDir/$mojangMappedPaperclipFileName", - vanillaJarIncludes = vanillaJarIncludes.get(), - compileDependencies = determineLibraries(vanillaServerLibraries.get()).sorted(), - runtimeDependencies = collectRuntimeDependencies().map { it.coordinates }.sorted(), + mache = createMacheDep(), + pluginRemapper = createRemapDep(), + patchDir = patchTargetDir, + reobfMappingsFile = "$dataTargetDir/$reobfMappingsFileName", + mojangMappedPaperclipFile = "$dataTargetDir/$mojangMappedPaperclipFileName", libraryRepositories = libraryRepositories.get(), - relocations = emptyList(), // Nothing is relocated in the dev bundle as of 1.20.5 - minecraftRemapArgs = TinyRemapper.minecraftRemapArgs, pluginRemapArgs = TinyRemapper.pluginRemapArgs, ) } - private fun determineLibraries(vanillaServerLibraries: List): Set { - val new = arrayListOf() - - // yes this is not configuration cache compatible, but the task isn't even without this, - // and what we want here are the dependencies declared in the server build file, - // not the runtime classpath, which would flatten transitive deps of the api for example. - for (dependency in serverProject.get().configurations.getByName(JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME).dependencies) { - // don't want project dependencies - if (dependency !is ExternalModuleDependency) { - continue - } - val version = listOfNotNull( - dependency.versionConstraint.strictVersion, - dependency.versionConstraint.requiredVersion, - dependency.versionConstraint.preferredVersion, - dependency.version - ).first { it.isNotBlank() } - new += ModuleId(dependency.group ?: error("Missing group for $dependency"), dependency.name, version) - } - - for (vanillaLib in vanillaServerLibraries) { - val vanilla = ModuleId.parse(vanillaLib) - if (new.none { it.group == vanilla.group && it.name == vanilla.name && it.classifier == vanilla.classifier }) { - new += vanilla - } - } - - return new.map { it.toString() }.toSet() - } - - private val ResolvedArtifactResult.coordinates: String - get() = ModuleId.fromIdentifier(id).toString() - - private fun collectRuntimeDependencies(): Set = - runtimeConfiguration.get().incoming.artifacts.artifacts.filterTo(HashSet()) { - it.id.componentIdentifier is ModuleComponentIdentifier - } - - private fun createDecompileRunner(): Runner { - return Runner( - dep = determineMavenDep(decompilerUrl, decompilerConfig), - args = vineFlowerArgList - ) - } - private fun createRemapDep(): MavenDep = - determineMavenDep(remapperUrl, remapperConfig) + determineMavenDep(pluginRemapperUrl, pluginRemapperConfig) + + private fun createMacheDep(): MavenDep = + determineMavenDep(macheUrl, macheConfig) data class DevBundleConfig( val minecraftVersion: String, - val mappedServerCoordinates: String, - val apiCoordinates: String, - val mojangApiCoordinates: String? = null, - val buildData: BuildData, - val decompile: Runner, - val remapper: MavenDep, - val patchDir: String - ) - - data class BuildData( - val paramMappings: MavenDep, + val mache: MavenDep, + val pluginRemapper: MavenDep, + val patchDir: String, val reobfMappingsFile: String, - val accessTransformFile: String, val mojangMappedPaperclipFile: String, - val vanillaJarIncludes: List, - val compileDependencies: List, - val runtimeDependencies: List, val libraryRepositories: List, - val relocations: List, - val minecraftRemapArgs: List, val pluginRemapArgs: List, ) - data class Runner(val dep: MavenDep, val args: List) - companion object { const val unsupportedEnvironmentPropName: String = "paperweight.generateDevBundle.ignoreUnsupportedEnvironment" - const val atFileName = "transform.at" const val reobfMappingsFileName = "$DEOBF_NAMESPACE-$SPIGOT_NAMESPACE-reobf.tiny" const val mojangMappedPaperclipFileName = "paperclip-$DEOBF_NAMESPACE.jar" // Should be bumped when the dev bundle config/contents changes in a way which will require users to update paperweight - const val currentDataVersion = 5 - - fun createCoordinatesFor(project: Project): String = - sequenceOf(project.group, project.name.lowercase(Locale.ENGLISH), "userdev-" + project.version).joinToString(":") + const val currentDataVersion = 6 } private fun checkEnvironment() { diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt index 5e324b4c2..72e99896b 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/DecompileJar.kt @@ -24,13 +24,15 @@ package io.papermc.paperweight.tasks.mache import io.papermc.paperweight.tasks.* import io.papermc.paperweight.util.* -import io.papermc.paperweight.util.constants.* +import java.nio.file.Path import kotlin.io.path.* import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.FileCollection import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property import org.gradle.api.tasks.* +import org.gradle.jvm.toolchain.JavaLauncher @CacheableTask abstract class DecompileJar : JavaLauncherTask() { @@ -61,40 +63,62 @@ abstract class DecompileJar : JavaLauncherTask() { @TaskAction fun run() { - val out = outputJar.convertToPath().ensureClean() - - val cfgFile = layout.cache.resolve(DECOMP_CFG).ensureClean() - val cfgText = buildString { - for (file in minecraftClasspath.files) { - append("-e=") - append(file.toPath().absolutePathString()) - append(System.lineSeparator()) - } + macheDecompileJar( + outputJar.path, + minecraftClasspath.files.map { it.toPath() }, + decompilerArgs.get(), + inputJar.path, + launcher.get(), + decompiler, + temporaryDir.toPath(), + memory.get() + ) + } +} + +fun macheDecompileJar( + outputJar: Path, + minecraftClasspath: List, + decompilerArgs: List, + inputJar: Path, + launcher: JavaLauncher, + decompiler: FileCollection, + workDir: Path, + memory: String = "4G" +) { + val out = outputJar.ensureClean() + + val cfgFile = out.resolveSibling("${out.name}.cfg") + val cfgText = buildString { + for (file in minecraftClasspath) { + append("-e=") + append(file.absolutePathString()) + append(System.lineSeparator()) } - cfgFile.writeText(cfgText) + } + cfgFile.writeText(cfgText) - val logs = out.resolveSibling("${out.name}.log") + val logs = out.resolveSibling("${out.name}.log") - val args = mutableListOf() + val args = mutableListOf() - args += decompilerArgs.get() + args += decompilerArgs - args += "-cfg" - args += cfgFile.absolutePathString() + args += "-cfg" + args += cfgFile.absolutePathString() - args += inputJar.convertToPath().absolutePathString() - args += out.absolutePathString() + args += inputJar.convertToPath().absolutePathString() + args += out.absolutePathString() - launcher.runJar( - decompiler, - temporaryDir, - logs, - jvmArgs = listOf("-Xmx${memory.get()}"), - args = args.toTypedArray() - ) + launcher.runJar( + decompiler, + workDir, + logs, + jvmArgs = listOf("-Xmx$memory"), + args = args.toTypedArray() + ) - out.openZip().use { root -> - root.getPath("META-INF", "MANIFEST.MF").deleteIfExists() - } + out.openZip().use { root -> + root.getPath("META-INF", "MANIFEST.MF").deleteIfExists() } } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt index 7a40fc49b..64a5fbf51 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/RemapJar.kt @@ -24,11 +24,14 @@ package io.papermc.paperweight.tasks.mache import io.papermc.paperweight.tasks.* import io.papermc.paperweight.util.* +import java.nio.file.Path import kotlin.io.path.* import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.FileCollection import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.ListProperty import org.gradle.api.tasks.* +import org.gradle.jvm.toolchain.JavaLauncher @CacheableTask abstract class RemapJar : JavaLauncherTask() { @@ -65,30 +68,58 @@ abstract class RemapJar : JavaLauncherTask() { @TaskAction fun run() { - val out = outputJar.convertToPath().ensureClean() - - val logFile = out.resolveSibling("${out.name}.log") - - val args = mutableListOf() - - remapperArgs.get().forEach { arg -> - args += arg - .replace(Regex("\\{tempDir}")) { temporaryDir.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 } } - } - - launcher.runJar( + macheRemapJar( + launcher.get(), codebookClasspath, + outputJar.path, + remapperArgs.get(), temporaryDir.toPath(), - logFile, - jvmArgs = listOf("-Xmx2G"), - args = args.toTypedArray() + remapperClasspath, + serverMappings.path, + paramMappings.singleFile.toPath(), + constants.files.singleOrNull()?.toPath(), + serverJar.path, + minecraftClasspath.files.map { it.toPath() } ) } } + +fun macheRemapJar( + launcher: JavaLauncher, + codebookClasspath: FileCollection, + outputJar: Path, + remapperArgs: List, + tempDir: Path, + remapperClasspath: FileCollection, + serverMappings: Path, + paramMappings: Path, + constants: Path?, + serverJar: Path, + minecraftClasspath: List, +) { + val out = outputJar.ensureClean() + + val logFile = out.resolveSibling("${out.name}.log") + + val args = mutableListOf() + + remapperArgs.forEach { arg -> + args += arg + .replace(Regex("\\{tempDir}")) { tempDir.absolutePathString() } + .replace(Regex("\\{remapperFile}")) { remapperClasspath.singleFile.absolutePath } + .replace(Regex("\\{mappingsFile}")) { serverMappings.absolutePathString() } + .replace(Regex("\\{paramsFile}")) { paramMappings.absolutePathString() } + .replace(Regex("\\{constantsFile}")) { constants!!.absolutePathString() } + .replace(Regex("\\{output}")) { outputJar.absolutePathString() } + .replace(Regex("\\{input}")) { serverJar.absolutePathString() } + .replace(Regex("\\{inputClasspath}")) { minecraftClasspath.joinToString(":") { it.absolutePathString() } } + } + + launcher.runJar( + codebookClasspath, + tempDir, + logFile, + jvmArgs = listOf("-Xmx2G"), + args = args.toTypedArray() + ) +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt index 42428e23e..459598329 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt @@ -45,6 +45,11 @@ const val PLUGIN_REMAPPER_CONFIG = "pluginRemapper" const val DECOMPILER_CONFIG = "decompiler" const val PAPERCLIP_CONFIG = "paperclip" const val MACHE_CONFIG = "mache" +const val MACHE_CODEBOOK_CONFIG = "macheCodebook" +const val MACHE_REMAPPER_CONFIG = "macheRemapper" +const val MACHE_DECOMPILER_CONFIG = "macheDecompiler" +const val MACHE_PARAM_MAPPINGS_CONFIG = "macheParamMappings" +const val MACHE_CONSTANTS_CONFIG = "machineConstants" const val RESTAMP_CONFIG = "restamp" const val DEV_BUNDLE_CONFIG = "paperweightDevelopmentBundle" const val MOJANG_MAPPED_SERVER_CONFIG = "mojangMappedServer" @@ -113,7 +118,6 @@ private const val TASK_CACHE = "$PAPER_PATH/taskCache" const val FINAL_REMAPPED_CODEBOOK_JAR = "$TASK_CACHE/codebook-minecraft.jar" const val FINAL_DECOMPILE_JAR = "$TASK_CACHE/decompileJar.jar" -const val DECOMP_CFG = "$TASK_CACHE/decomp_cfg.txt" const val MC_DEV_SOURCES_DIR = "$PAPER_PATH/mc-dev-sources" diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheMeta.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheMeta.kt index e594ed51c..cb613557c 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheMeta.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/data/mache/MacheMeta.kt @@ -22,6 +22,10 @@ package io.papermc.paperweight.util.data.mache +import io.papermc.paperweight.util.constants.* +import org.gradle.api.Project +import org.gradle.kotlin.dsl.* + data class MacheMeta( val minecraftVersion: String, val macheVersion: String, @@ -30,4 +34,60 @@ data class MacheMeta( val decompilerArgs: List, val remapperArgs: List, val additionalCompileDependencies: MacheAdditionalDependencies? = null, -) +) { + fun addRepositories(project: Project) { + project.repositories { + for (repository in repositories) { + maven(repository.url) { + name = repository.name + mavenContent { + for (group in repository.groups ?: listOf()) { + includeGroupByRegex("$group.*") + } + } + } + } + } + } + + fun addDependencies(project: Project) { + val macheDeps = this@MacheMeta.dependencies + project.configurations { + named(MACHE_CODEBOOK_CONFIG) { + defaultDependencies { + macheDeps.codebook.forEach { + add(project.dependencies.create(it.toMavenString())) + } + } + } + named(MACHE_PARAM_MAPPINGS_CONFIG) { + defaultDependencies { + macheDeps.paramMappings.forEach { + add(project.dependencies.create(it.toMavenString())) + } + } + } + named(MACHE_CONSTANTS_CONFIG) { + defaultDependencies { + macheDeps.constants.forEach { + add(project.dependencies.create(it.toMavenString())) + } + } + } + named(MACHE_REMAPPER_CONFIG) { + defaultDependencies { + macheDeps.remapper.forEach { + add(project.dependencies.create(it.toMavenString())) + } + } + } + named(MACHE_DECOMPILER_CONFIG) { + defaultDependencies { + macheDeps.decompiler.forEach { + add(project.dependencies.create(it.toMavenString())) + } + } + } + } + } +} diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt index ffe5b78e3..bf03a3952 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt @@ -29,6 +29,7 @@ import io.papermc.paperweight.DownloadService import io.papermc.paperweight.PaperweightException import io.papermc.paperweight.tasks.* import io.papermc.paperweight.util.constants.* +import io.papermc.paperweight.util.data.mache.* import java.io.File import java.io.InputStream import java.io.OutputStream @@ -52,6 +53,7 @@ import kotlin.io.path.* import org.cadixdev.lorenz.merge.MergeResult import org.gradle.api.Project import org.gradle.api.Task +import org.gradle.api.artifacts.ConfigurationContainer import org.gradle.api.attributes.Attribute import org.gradle.api.file.FileCollection import org.gradle.api.file.FileSystemLocation @@ -411,3 +413,7 @@ fun modifyManifest(path: Path, create: Boolean = true, op: Manifest.() -> Unit) } val mainCapabilityAttribute: Attribute = Attribute.of("io.papermc.paperweight.main-capability", String::class.java) + +fun ConfigurationContainer.resolveMacheMeta() = getByName(MACHE_CONFIG).singleFile.toPath().openZip().use { zip -> + gson.fromJson(zip.getPath("/mache.json").readText()) +} diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt index 6124b8e2a..e3e59c2c8 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt @@ -24,6 +24,8 @@ package io.papermc.paperweight.userdev import io.papermc.paperweight.DownloadService import io.papermc.paperweight.PaperweightException +import io.papermc.paperweight.attribute.DevBundleOutput +import io.papermc.paperweight.attribute.MacheOutput import io.papermc.paperweight.tasks.* import io.papermc.paperweight.userdev.attribute.Obfuscation import io.papermc.paperweight.userdev.internal.JunitExclusionRule @@ -37,9 +39,11 @@ import javax.inject.Inject import org.gradle.api.Action import org.gradle.api.Plugin import org.gradle.api.Project +import org.gradle.api.artifacts.Configuration import org.gradle.api.artifacts.ModuleDependency import org.gradle.api.artifacts.ProjectDependency import org.gradle.api.artifacts.component.ModuleComponentIdentifier +import org.gradle.api.artifacts.dsl.DependencyFactory import org.gradle.api.artifacts.result.ResolvedDependencyResult import org.gradle.api.attributes.Bundling import org.gradle.api.attributes.Category @@ -62,6 +66,9 @@ abstract class PaperweightUser : Plugin { @get:Inject abstract val javaToolchainService: JavaToolchainService + @get:Inject + abstract val dependencyFactory: DependencyFactory + override fun apply(target: Project) { val sharedCacheRoot = target.gradle.gradleUserHomeDir.toPath().resolve("caches/paperweight-userdev") @@ -81,7 +88,9 @@ abstract class PaperweightUser : Plugin { delete(target.layout.cache) } - target.configurations.register(DEV_BUNDLE_CONFIG) + target.configurations.register(DEV_BUNDLE_CONFIG) { + attributes.attribute(DevBundleOutput.ATTRIBUTE, target.objects.named(DevBundleOutput.ZIP)) + } // must not be initialized until afterEvaluate, as it resolves the dev bundle val userdevSetup by lazy { createSetup(target, sharedCacheRoot.resolve(paperweightHash)) } @@ -165,6 +174,8 @@ abstract class PaperweightUser : Plugin { configureRepositories(userdevSetup) + userdevSetup.afterEvaluate(createContext(this)) + cleanSharedCaches(this, sharedCacheRoot) } } @@ -188,17 +199,27 @@ abstract class PaperweightUser : Plugin { } private fun Project.configureRepositories(userdevSetup: UserdevSetup) = repositories { - maven(userdevSetup.paramMappings.url) { - name = PARAM_MAPPINGS_REPO_NAME - content { onlyForConfigurations(PARAM_MAPPINGS_CONFIG) } + userdevSetup.mache?.url?.let { + maven(it) { + name = MACHE_REPO_NAME + content { onlyForConfigurations(MACHE_CONFIG) } + } + } + userdevSetup.paramMappings?.url?.let { + maven(it) { + name = PARAM_MAPPINGS_REPO_NAME + content { onlyForConfigurations(PARAM_MAPPINGS_CONFIG) } + } } maven(userdevSetup.remapper.url) { name = REMAPPER_REPO_NAME content { onlyForConfigurations(REMAPPER_CONFIG) } } - maven(userdevSetup.decompiler.url) { - name = DECOMPILER_REPO_NAME - content { onlyForConfigurations(DECOMPILER_CONFIG) } + userdevSetup.decompiler?.url?.let { + maven(it) { + name = DECOMPILER_REPO_NAME + content { onlyForConfigurations(DECOMPILER_CONFIG) } + } } for (repo in userdevSetup.libraryRepositories) { maven(repo) @@ -213,7 +234,7 @@ abstract class PaperweightUser : Plugin { } if (hasDevBundle.isFailure || !hasDevBundle.getOrThrow()) { val message = "paperweight requires a development bundle to be added to the 'paperweightDevelopmentBundle' configuration, as" + - " well as a repository to resolve it from in order to function. Use the paperweightDevBundle extension function to do this easily." + " well as a repository to resolve it from in order to function. Use the dependencies.paperweight extension to do this easily." throw PaperweightException( message, hasDevBundle.exceptionOrNull()?.let { PaperweightException("Failed to resolve dev bundle", it) } @@ -221,40 +242,39 @@ abstract class PaperweightUser : Plugin { } } + private fun Configuration.dependenciesFrom( + transitive: (String) -> Boolean = { true }, + supplier: () -> MavenDep? + ) { + defaultDependencies { + for (dep in supplier()?.coordinates ?: emptyList()) { + val dependency = dependencyFactory.create(dep) + dependency.isTransitive = transitive(dep) + add(dependency) + } + } + } + private fun createConfigurations( target: Project, userdevSetup: Provider ) { + target.configurations.register(MACHE_CONFIG) { + dependenciesFrom { userdevSetup.get().mache } + attributes.attribute(MacheOutput.ATTRIBUTE, target.objects.named(MacheOutput.ZIP)) + } target.configurations.register(DECOMPILER_CONFIG) { - defaultDependencies { - for (dep in userdevSetup.get().decompiler.coordinates) { - add(target.dependencies.create(dep)) - } - } + dependenciesFrom { userdevSetup.get().decompiler } } - target.configurations.register(PARAM_MAPPINGS_CONFIG) { - defaultDependencies { - for (dep in userdevSetup.get().paramMappings.coordinates) { - add(target.dependencies.create(dep)) - } - } + dependenciesFrom { userdevSetup.get().paramMappings } } fun makeRemapperConfig(name: String) { target.configurations.register(name) { - defaultDependencies { - for (dep in userdevSetup.get().remapper.coordinates) { - // we use a fat jar for tiny-remapper, so we don't need its transitive deps - val fatTiny = dep.contains(":tiny-remapper:") && dep.endsWith(":fat") - add( - target.dependencies.create(dep) { - if (fatTiny) { - isTransitive = false - } - } - ) - } + // when using a fat jar for tiny-remapper we don't need its transitive deps + dependenciesFrom({ !it.contains(":tiny-remapper:") || !it.endsWith(":fat") }) { + userdevSetup.get().remapper } } } @@ -271,26 +291,19 @@ abstract class PaperweightUser : Plugin { } } + target.configurations.register(MOJANG_MAPPED_SERVER_RUNTIME_CONFIG) + target.plugins.withType().configureEach { listOf( JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME, - JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME + JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME, + MOJANG_MAPPED_SERVER_RUNTIME_CONFIG ).map(target.configurations::named).forEach { config -> config { extendsFrom(mojangMappedServerConfig.get()) } } } - - target.configurations.register(MOJANG_MAPPED_SERVER_RUNTIME_CONFIG) { - defaultDependencies { - val ctx = createContext(target) - userdevSetup.get().let { setup -> - setup.createOrUpdateIvyRepository(ctx) - setup.populateRuntimeConfiguration(ctx, this) - } - } - } } private fun createContext(project: Project): SetupHandler.Context = diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/ExtractDevBundle.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/ExtractDevBundle.kt index 35dd38601..ea4ae2a17 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/ExtractDevBundle.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/ExtractDevBundle.kt @@ -25,15 +25,17 @@ package io.papermc.paperweight.userdev.internal.setup import io.papermc.paperweight.PaperweightException import io.papermc.paperweight.tasks.* import io.papermc.paperweight.userdev.internal.setup.v2.DevBundleV2 +import io.papermc.paperweight.userdev.internal.setup.v5.DevBundleV5 import io.papermc.paperweight.util.* import java.nio.file.Path import kotlin.io.path.* private val supported = mapOf( 2 to DevBundleV2.Config::class, // 1.17.1 - 3 to GenerateDevBundle.DevBundleConfig::class, // up to 1.20.4 - 4 to GenerateDevBundle.DevBundleConfig::class, // 1.20.5, early 1.20.6 - GenerateDevBundle.currentDataVersion to GenerateDevBundle.DevBundleConfig::class, // 1.20.6+ (nullable mojangApiCoordinates) + 3 to DevBundleV5.Config::class, // up to 1.20.4 + 4 to DevBundleV5.Config::class, // 1.20.5, early 1.20.6 + 5 to DevBundleV5.Config::class, // 1.20.6+ (nullable mojangApiCoordinates) + 6 to GenerateDevBundle.DevBundleConfig::class // TODO update comment ) data class ExtractedBundle( diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandler.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandler.kt index 7cd113e49..b42758b22 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandler.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandler.kt @@ -26,6 +26,8 @@ import io.papermc.paperweight.PaperweightException import io.papermc.paperweight.tasks.* import io.papermc.paperweight.userdev.internal.setup.v2.DevBundleV2 import io.papermc.paperweight.userdev.internal.setup.v2.SetupHandlerImplV2 +import io.papermc.paperweight.userdev.internal.setup.v5.DevBundleV5 +import io.papermc.paperweight.userdev.internal.setup.v5.SetupHandlerImplV5 import io.papermc.paperweight.util.* import java.nio.file.Path import org.gradle.api.Project @@ -46,6 +48,9 @@ interface SetupHandler { fun serverJar(context: Context): Path + fun afterEvaluate(context: Context) { + } + val serverJar: Path val reobfMappings: Path @@ -54,12 +59,14 @@ interface SetupHandler { val pluginRemapArgs: List - val paramMappings: MavenDep + val paramMappings: MavenDep? - val decompiler: MavenDep + val decompiler: MavenDep? val remapper: MavenDep + val mache: MavenDep? + val libraryRepositories: List data class Context( @@ -81,10 +88,17 @@ interface SetupHandler { parameters, extractedBundle as ExtractedBundle, ) + + is DevBundleV5.Config -> SetupHandlerImplV5( + parameters, + extractedBundle as ExtractedBundle + ) + is DevBundleV2.Config -> SetupHandlerImplV2( parameters, extractedBundle as ExtractedBundle ) + else -> throw PaperweightException("Unknown dev bundle config type: ${extractedBundle.config::class.java.typeName}") } } diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandlerImpl.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandlerImpl.kt index d031b3efc..5f65ad5ff 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandlerImpl.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandlerImpl.kt @@ -24,19 +24,23 @@ package io.papermc.paperweight.userdev.internal.setup import io.papermc.paperweight.tasks.* import io.papermc.paperweight.userdev.internal.setup.step.* +import io.papermc.paperweight.userdev.internal.setup.step.MinecraftSourcesMache +import io.papermc.paperweight.userdev.internal.setup.step.RemapMinecraftMache import io.papermc.paperweight.userdev.internal.setup.util.* import io.papermc.paperweight.util.* import io.papermc.paperweight.util.constants.* +import io.papermc.paperweight.util.data.mache.* import java.nio.file.Path import org.gradle.api.artifacts.DependencySet -import org.gradle.api.artifacts.ExternalModuleDependency import org.gradle.api.artifacts.repositories.IvyArtifactRepository +import org.gradle.kotlin.dsl.* class SetupHandlerImpl( private val parameters: UserdevSetup.Parameters, private val bundle: ExtractedBundle, private val cache: Path = parameters.cache.path, ) : SetupHandler { + private var macheMeta: MacheMeta? = null private val vanillaSteps by lazy { VanillaSteps( bundle.config.minecraftVersion, @@ -47,75 +51,52 @@ class SetupHandlerImpl( } private val vanillaServerJar: Path = cache.resolve(paperSetupOutput("vanillaServerJar", "jar")) private val minecraftLibraryJars = cache.resolve(MINECRAFT_JARS_PATH) - private val filteredVanillaServerJar: Path = cache.resolve(paperSetupOutput("filterJar", "jar")) - private val mojangPlusYarnMappings: Path = cache.resolve(MOJANG_YARN_MAPPINGS) - private val mappedMinecraftServerJar: Path = cache.resolve(paperSetupOutput("mappedMinecraftServerJar", "jar")) - private val fixedMinecraftServerJar: Path = cache.resolve(paperSetupOutput("fixedMinecraftServerJar", "jar")) - private val accessTransformedServerJar: Path = cache.resolve(paperSetupOutput("accessTransformedServerJar", "jar")) - private val decompiledMinecraftServerJar: Path = cache.resolve(paperSetupOutput("decompileMinecraftServerJar", "jar")) - private val patchedSourcesJar: Path = cache.resolve(paperSetupOutput("patchedSourcesJar", "jar")) + private val mappedServerJar: Path = cache.resolve(paperSetupOutput("remapServerJar", "jar")) + private val baseSources: Path = cache.resolve(paperSetupOutput("baseSources", "jar")) + private val patchedSourcesJar: Path = cache.resolve(paperSetupOutput("patchedSources", "jar")) private val mojangMappedPaperJar: Path = cache.resolve(paperSetupOutput("applyMojangMappedPaperclipPatch", "jar")) private fun minecraftLibraryJars(): List = minecraftLibraryJars.filesMatchingRecursive("*.jar") private fun generateSources(context: SetupHandler.Context) { vanillaSteps.downloadVanillaServerJar() + vanillaSteps.downloadServerMappings() + applyMojangMappedPaperclipPatch(context) val extractStep = createExtractFromBundlerStep() - val filterVanillaJarStep = FilterVanillaJar(vanillaServerJar, bundle.config.buildData.vanillaJarIncludes, filteredVanillaServerJar) - - val genMappingsStep = GenerateMappingsStep.create( - context, - vanillaSteps, - filteredVanillaServerJar, - ::minecraftLibraryJars, - mojangPlusYarnMappings, - ) - - val remapMinecraftStep = RemapMinecraft.create( + val remapStep = RemapMinecraftMache.create( context, - bundle.config.buildData.minecraftRemapArgs, - filteredVanillaServerJar, + macheMeta().remapperArgs, + vanillaServerJar, ::minecraftLibraryJars, - mojangPlusYarnMappings, - mappedMinecraftServerJar, + vanillaSteps.serverMappings, + mappedServerJar, cache, ) - val fixStep = FixMinecraftJar(mappedMinecraftServerJar, fixedMinecraftServerJar, vanillaServerJar) - - val atStep = AccessTransformMinecraft( - bundle.dir.resolve(bundle.config.buildData.accessTransformFile), - fixedMinecraftServerJar, - accessTransformedServerJar, - ) - - val decomp = DecompileMinecraft.create( + val macheSourcesStep = MinecraftSourcesMache.create( context, - accessTransformedServerJar, - decompiledMinecraftServerJar, + mappedServerJar, + baseSources, cache, ::minecraftLibraryJars, - bundle.config.decompile.args, + macheMeta().decompilerArgs, ) val applyDevBundlePatchesStep = ApplyDevBundlePatches( - decompiledMinecraftServerJar, + baseSources, bundle.dir.resolve(bundle.config.patchDir), - patchedSourcesJar + patchedSourcesJar, + mojangMappedPaperJar ) StepExecutor.executeSteps( bundle.changed, context, extractStep, - filterVanillaJarStep, - genMappingsStep, - remapMinecraftStep, - fixStep, - atStep, - decomp, + remapStep, + macheSourcesStep, applyDevBundlePatchesStep, ) } @@ -133,7 +114,7 @@ class SetupHandlerImpl( StepExecutor.executeStep( context, RunPaperclip( - bundle.dir.resolve(bundle.config.buildData.mojangMappedPaperclipFile), + bundle.dir.resolve(bundle.config.mojangMappedPaperclipFile), mojangMappedPaperJar, vanillaSteps.mojangJar, minecraftVersion, @@ -162,19 +143,14 @@ class SetupHandlerImpl( } else { vanillaSteps.downloadVanillaServerJar() StepExecutor.executeStep(context, createExtractFromBundlerStep()) + applyMojangMappedPaperclipPatch(context) null } - applyMojangMappedPaperclipPatch(context) - - val deps = mutableListOf() - deps.addAll(bundle.config.buildData.compileDependencies) - deps.add(bundle.config.apiCoordinates) - bundle.config.mojangApiCoordinates?.let { deps.add(it) } installPaperServer( cache, - bundle.config.mappedServerCoordinates, - deps, + mappedServerCoordinates(), + determineArtifactCoordinates(context.project.configurations.getByName(DEV_BUNDLE_CONFIG)), mojangMappedPaperJar, source, minecraftVersion, @@ -183,34 +159,21 @@ class SetupHandlerImpl( setupCompleted = true } + private fun mappedServerCoordinates(): String = + "io.papermc.paperweight:dev-bundle-server:$minecraftVersion" + override fun configureIvyRepo(repo: IvyArtifactRepository) { repo.content { - includeFromDependencyNotation(bundle.config.mappedServerCoordinates) + includeFromDependencyNotation(mappedServerCoordinates()) } } override fun populateCompileConfiguration(context: SetupHandler.Context, dependencySet: DependencySet) { - dependencySet.add(context.project.dependencies.create(bundle.config.mappedServerCoordinates)) + dependencySet.add(context.project.dependencies.create(mappedServerCoordinates())) } override fun populateRuntimeConfiguration(context: SetupHandler.Context, dependencySet: DependencySet) { - listOfNotNull( - bundle.config.mappedServerCoordinates, - bundle.config.apiCoordinates, - bundle.config.mojangApiCoordinates - ).forEach { coordinate -> - val dep = context.project.dependencies.create(coordinate).also { - (it as ExternalModuleDependency).isTransitive = false - } - dependencySet.add(dep) - } - - for (coordinates in bundle.config.buildData.runtimeDependencies) { - val dep = context.project.dependencies.create(coordinates).also { - (it as ExternalModuleDependency).isTransitive = false - } - dependencySet.add(dep) - } + dependencySet.add(context.project.dependencies.create(mappedServerCoordinates())) } override fun serverJar(context: SetupHandler.Context): Path { @@ -218,29 +181,62 @@ class SetupHandlerImpl( return mojangMappedPaperJar } + private fun macheMeta(): MacheMeta = requireNotNull(macheMeta) { "Mache meta is not setup yet" } + + @Synchronized + override fun afterEvaluate(context: SetupHandler.Context) { + val project = context.project + val configurations = project.configurations + if (macheMeta == null) { + macheMeta = configurations.resolveMacheMeta() + + configurations.register(MACHE_CODEBOOK_CONFIG) { + isTransitive = false + } + configurations.register(MACHE_REMAPPER_CONFIG) { + isTransitive = false + } + configurations.register(MACHE_DECOMPILER_CONFIG) { + isTransitive = false + } + configurations.register(MACHE_PARAM_MAPPINGS_CONFIG) { + isTransitive = false + } + configurations.register(MACHE_CONSTANTS_CONFIG) { + isTransitive = false + } + + macheMeta().addDependencies(project) + macheMeta().addRepositories(project) + } + } + override val serverJar: Path get() = mojangMappedPaperJar override val reobfMappings: Path - get() = bundle.dir.resolve(bundle.config.buildData.reobfMappingsFile) + get() = bundle.dir.resolve(bundle.config.reobfMappingsFile) override val minecraftVersion: String get() = bundle.config.minecraftVersion override val pluginRemapArgs: List - get() = bundle.config.buildData.pluginRemapArgs + get() = bundle.config.pluginRemapArgs - override val paramMappings: MavenDep - get() = bundle.config.buildData.paramMappings + override val paramMappings: MavenDep? + get() = null - override val decompiler: MavenDep - get() = bundle.config.decompile.dep + override val decompiler: MavenDep? + get() = null override val remapper: MavenDep - get() = bundle.config.remapper + get() = bundle.config.pluginRemapper + + override val mache: MavenDep + get() = bundle.config.mache override val libraryRepositories: List - get() = bundle.config.buildData.libraryRepositories + get() = bundle.config.libraryRepositories private fun createExtractFromBundlerStep(): ExtractFromBundlerStep = ExtractFromBundlerStep( cache, diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/UserdevSetup.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/UserdevSetup.kt index 6e7dae68f..4b8c33652 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/UserdevSetup.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/UserdevSetup.kt @@ -97,6 +97,10 @@ abstract class UserdevSetup : BuildService, SetupHandle return setup.serverJar(context) } + override fun afterEvaluate(context: SetupHandler.Context) { + setup.afterEvaluate(context) + } + override val serverJar: Path get() = setup.serverJar @@ -109,15 +113,18 @@ abstract class UserdevSetup : BuildService, SetupHandle override val pluginRemapArgs: List get() = setup.pluginRemapArgs - override val paramMappings: MavenDep + override val paramMappings: MavenDep? get() = setup.paramMappings - override val decompiler: MavenDep + override val decompiler: MavenDep? get() = setup.decompiler override val remapper: MavenDep get() = setup.remapper + override val mache: MavenDep? + get() = setup.mache + override val libraryRepositories: List get() = setup.libraryRepositories // end delegate to setup diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/ApplyDevBundlePatches.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/ApplyDevBundlePatches.kt index f9630a8fe..b6b9ca90b 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/ApplyDevBundlePatches.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/ApplyDevBundlePatches.kt @@ -42,6 +42,7 @@ class ApplyDevBundlePatches( @Input private val decompiledJar: Path, private val devBundlePatches: Path, @Output private val outputJar: Path, + @Input private val resourcesJar: Path? = null, ) : SetupStep { override val name: String = "apply patches to decompiled jar" @@ -88,6 +89,25 @@ class ApplyDevBundlePatches( ensureDeleted(outputJar) zip(outputDir, outputJar) + + // Bring in resources + resourcesJar?.let { jarWithResources -> + outputJar.openZip().use { fs -> + val out = fs.getPath("/") + jarWithResources.openZip().use { resources -> + val vanilla = resources.getPath("/") + + vanilla.walk() + .filter { it.isRegularFile() } + .filterNot { it.name.endsWith(".class") } + .forEach { resourceFile -> + val copyTo = out.resolve(resourceFile.relativeTo(vanilla).invariantSeparatorsPathString) + copyTo.createParentDirectories() + resourceFile.copyTo(copyTo) + } + } + } + } } finally { ensureDeleted(outputDir, tempPatchDir) } diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/MinecraftSourcesMache.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/MinecraftSourcesMache.kt new file mode 100644 index 000000000..02fb945b5 --- /dev/null +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/MinecraftSourcesMache.kt @@ -0,0 +1,105 @@ +/* + * 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.userdev.internal.setup.step + +import codechicken.diffpatch.cli.PatchOperation +import codechicken.diffpatch.util.LoggingOutputStream +import codechicken.diffpatch.util.archiver.ArchiveFormat +import io.papermc.paperweight.tasks.mache.macheDecompileJar +import io.papermc.paperweight.userdev.internal.setup.SetupHandler +import io.papermc.paperweight.userdev.internal.setup.util.HashFunctionBuilder +import io.papermc.paperweight.userdev.internal.setup.util.siblingHashesFile +import io.papermc.paperweight.util.* +import io.papermc.paperweight.util.constants.* +import java.nio.file.Path +import kotlin.io.path.* +import org.gradle.api.artifacts.Configuration +import org.gradle.api.logging.LogLevel + +class MinecraftSourcesMache( + @Input private val inputJar: Path, + @Output private val outputJar: Path, + private val cache: Path, + private val minecraftLibraryJars: () -> List, + @Input private val decompileArgs: List, + private val decompiler: Configuration, + private val mache: Configuration, +) : SetupStep { + override val name: String = "decompile and setup sources with mache" + + override val hashFile: Path = outputJar.siblingHashesFile() + + override fun run(context: SetupHandler.Context) { + // Decompile + val tempOut = outputJar.resolveSibling("${outputJar.name}.tmp") + macheDecompileJar( + tempOut, + minecraftLibraryJars(), + decompileArgs, + inputJar, + context.defaultJavaLauncher, + decompiler, + cache, + ) + + // Apply mache patches + outputJar.ensureClean() + val result = PatchOperation.builder() + .logTo(LoggingOutputStream(context.project.logger, LogLevel.LIFECYCLE)) + .basePath(tempOut, ArchiveFormat.ZIP) + .outputPath(outputJar, ArchiveFormat.ZIP) + .patchesPath(mache.singleFile.toPath(), ArchiveFormat.ZIP) + .patchesPrefix("patches") + .level(codechicken.diffpatch.util.LogLevel.INFO) + .build() + .operate() + tempOut.ensureClean() + + if (result.exit != 0) { + throw Exception("Failed to apply ${result.summary.failedMatches} mache patches") + } + } + + override fun touchHashFunctionBuilder(builder: HashFunctionBuilder) { + builder.include(minecraftLibraryJars()) + builder.include(decompiler.map { it.toPath() }) + builder.include(mache.map { it.toPath() }) + builder.includePaperweightHash = false + } + + companion object { + fun create( + context: SetupHandler.Context, + inputJar: Path, + outputJar: Path, + cache: Path, + minecraftLibraryJars: () -> List, + decompileArgs: List, + ): MinecraftSourcesMache { + // resolve dependencies + val decompiler = context.project.configurations.getByName(MACHE_DECOMPILER_CONFIG).also { it.resolve() } + val mache = context.project.configurations.getByName(MACHE_CONFIG).also { it.resolve() } + return MinecraftSourcesMache(inputJar, outputJar, cache, minecraftLibraryJars, decompileArgs, decompiler, mache) + } + } +} diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RemapMinecraftMache.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RemapMinecraftMache.kt new file mode 100644 index 000000000..afe6bd1a3 --- /dev/null +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RemapMinecraftMache.kt @@ -0,0 +1,105 @@ +/* + * 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.userdev.internal.setup.step + +import io.papermc.paperweight.tasks.mache.macheRemapJar +import io.papermc.paperweight.userdev.internal.setup.SetupHandler +import io.papermc.paperweight.userdev.internal.setup.util.HashFunctionBuilder +import io.papermc.paperweight.userdev.internal.setup.util.siblingHashesFile +import io.papermc.paperweight.util.* +import io.papermc.paperweight.util.constants.* +import java.nio.file.Path +import kotlin.io.path.* +import org.gradle.api.artifacts.Configuration + +class RemapMinecraftMache( + @Input private val minecraftRemapArgs: List, + @Input private val vanillaJar: Path, + private val minecraftLibraryJars: () -> List, + @Input private val mappings: Path, + @Input private val paramMappings: Path, + @Input private val constants: Path?, + private val codebook: Configuration, + private val remapper: Configuration, + @Output private val outputJar: Path, + private val cache: Path, +) : SetupStep { + override val name: String = "remap minecraft server jar" + + override val hashFile: Path = outputJar.siblingHashesFile() + + override fun run(context: SetupHandler.Context) { + val temp = createTempDirectory(cache, "remap") + macheRemapJar( + context.defaultJavaLauncher, + codebook, + outputJar, + minecraftRemapArgs, + temp, + remapper, + mappings, + paramMappings, + constants, + vanillaJar, + minecraftLibraryJars() + ) + temp.deleteRecursive() + } + + override fun touchHashFunctionBuilder(builder: HashFunctionBuilder) { + builder.includePaperweightHash = false + builder.include(minecraftLibraryJars()) + builder.include(remapper.map { it.toPath() }) + builder.include(codebook.map { it.toPath() }) + } + + companion object { + fun create( + context: SetupHandler.Context, + minecraftRemapArgs: List, + vanillaJar: Path, + minecraftLibraryJars: () -> List, + mappings: Path, + outputJar: Path, + cache: Path, + ): RemapMinecraftMache { + // resolve dependencies + val remapper = context.project.configurations.getByName(MACHE_REMAPPER_CONFIG).also { it.resolve() } + val paramMappings = context.project.configurations.getByName(MACHE_PARAM_MAPPINGS_CONFIG).singleFile.toPath() + val constants = context.project.configurations.getByName(MACHE_CONSTANTS_CONFIG).files.singleOrNull()?.toPath() + val codebook = context.project.configurations.getByName(MACHE_CODEBOOK_CONFIG).also { it.resolve() } + return RemapMinecraftMache( + minecraftRemapArgs, + vanillaJar, + minecraftLibraryJars, + mappings, + paramMappings, + constants, + codebook, + remapper, + outputJar, + cache, + ) + } + } +} diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v2/SetupHandlerImplV2.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v2/SetupHandlerImplV2.kt index ade6bbdda..01a709710 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v2/SetupHandlerImplV2.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v2/SetupHandlerImplV2.kt @@ -258,6 +258,9 @@ class SetupHandlerImplV2( override val remapper: MavenDep get() = bundle.config.remap.dep + override val mache: MavenDep? + get() = null + override val libraryRepositories: List get() = bundle.config.buildData.libraryRepositories } diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v5/DevBundleV5.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v5/DevBundleV5.kt new file mode 100644 index 000000000..ad3e94fd3 --- /dev/null +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v5/DevBundleV5.kt @@ -0,0 +1,54 @@ +/* + * 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.userdev.internal.setup.v5 + +import io.papermc.paperweight.util.* + +object DevBundleV5 { + data class Config( + val minecraftVersion: String, + val mappedServerCoordinates: String, + val apiCoordinates: String, + val mojangApiCoordinates: String? = null, + val buildData: BuildData, + val decompile: Runner, + val remapper: MavenDep, + val patchDir: String + ) + + data class BuildData( + val paramMappings: MavenDep, + val reobfMappingsFile: String, + val accessTransformFile: String, + val mojangMappedPaperclipFile: String, + val vanillaJarIncludes: List, + val compileDependencies: List, + val runtimeDependencies: List, + val libraryRepositories: List, + val relocations: List, + val minecraftRemapArgs: List, + val pluginRemapArgs: List, + ) + + data class Runner(val dep: MavenDep, val args: List) +} diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v5/SetupHandlerImplV5.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v5/SetupHandlerImplV5.kt new file mode 100644 index 000000000..66c5bc472 --- /dev/null +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v5/SetupHandlerImplV5.kt @@ -0,0 +1,289 @@ +/* + * 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.userdev.internal.setup.v5 + +import io.papermc.paperweight.tasks.* +import io.papermc.paperweight.userdev.internal.setup.ExtractedBundle +import io.papermc.paperweight.userdev.internal.setup.RunPaperclip +import io.papermc.paperweight.userdev.internal.setup.SetupHandler +import io.papermc.paperweight.userdev.internal.setup.UserdevSetup +import io.papermc.paperweight.userdev.internal.setup.step.* +import io.papermc.paperweight.userdev.internal.setup.util.* +import io.papermc.paperweight.util.* +import io.papermc.paperweight.util.constants.* +import java.nio.file.Path +import org.gradle.api.artifacts.DependencySet +import org.gradle.api.artifacts.ExternalModuleDependency +import org.gradle.api.artifacts.repositories.IvyArtifactRepository +import org.gradle.kotlin.dsl.* + +class SetupHandlerImplV5( + private val parameters: UserdevSetup.Parameters, + private val bundle: ExtractedBundle, + private val cache: Path = parameters.cache.path, +) : SetupHandler { + private val vanillaSteps by lazy { + VanillaSteps( + bundle.config.minecraftVersion, + cache, + parameters.downloadService.get(), + bundle.changed, + ) + } + private val vanillaServerJar: Path = cache.resolve(paperSetupOutput("vanillaServerJar", "jar")) + private val minecraftLibraryJars = cache.resolve(MINECRAFT_JARS_PATH) + private val filteredVanillaServerJar: Path = cache.resolve(paperSetupOutput("filterJar", "jar")) + private val mojangPlusYarnMappings: Path = cache.resolve(MOJANG_YARN_MAPPINGS) + private val mappedMinecraftServerJar: Path = cache.resolve(paperSetupOutput("mappedMinecraftServerJar", "jar")) + private val fixedMinecraftServerJar: Path = cache.resolve(paperSetupOutput("fixedMinecraftServerJar", "jar")) + private val accessTransformedServerJar: Path = cache.resolve(paperSetupOutput("accessTransformedServerJar", "jar")) + private val decompiledMinecraftServerJar: Path = cache.resolve(paperSetupOutput("decompileMinecraftServerJar", "jar")) + private val patchedSourcesJar: Path = cache.resolve(paperSetupOutput("patchedSourcesJar", "jar")) + private val mojangMappedPaperJar: Path = cache.resolve(paperSetupOutput("applyMojangMappedPaperclipPatch", "jar")) + + private fun minecraftLibraryJars(): List = minecraftLibraryJars.filesMatchingRecursive("*.jar") + + private fun generateSources(context: SetupHandler.Context) { + vanillaSteps.downloadVanillaServerJar() + + val extractStep = createExtractFromBundlerStep() + + val filterVanillaJarStep = FilterVanillaJar(vanillaServerJar, bundle.config.buildData.vanillaJarIncludes, filteredVanillaServerJar) + + val genMappingsStep = GenerateMappingsStep.create( + context, + vanillaSteps, + filteredVanillaServerJar, + ::minecraftLibraryJars, + mojangPlusYarnMappings, + ) + + val remapMinecraftStep = RemapMinecraft.create( + context, + bundle.config.buildData.minecraftRemapArgs, + filteredVanillaServerJar, + ::minecraftLibraryJars, + mojangPlusYarnMappings, + mappedMinecraftServerJar, + cache, + ) + + val fixStep = FixMinecraftJar(mappedMinecraftServerJar, fixedMinecraftServerJar, vanillaServerJar) + + val atStep = AccessTransformMinecraft( + bundle.dir.resolve(bundle.config.buildData.accessTransformFile), + fixedMinecraftServerJar, + accessTransformedServerJar, + ) + + val decomp = DecompileMinecraft.create( + context, + accessTransformedServerJar, + decompiledMinecraftServerJar, + cache, + ::minecraftLibraryJars, + bundle.config.decompile.args, + ) + + val applyDevBundlePatchesStep = ApplyDevBundlePatches( + decompiledMinecraftServerJar, + bundle.dir.resolve(bundle.config.patchDir), + patchedSourcesJar + ) + + StepExecutor.executeSteps( + bundle.changed, + context, + extractStep, + filterVanillaJarStep, + genMappingsStep, + remapMinecraftStep, + fixStep, + atStep, + decomp, + applyDevBundlePatchesStep, + ) + } + + // This can be called when a user queries the server jar provider in + // PaperweightUserExtension, possibly by a task running in a separate + // thread to dependency resolution. + @Synchronized + private fun applyMojangMappedPaperclipPatch(context: SetupHandler.Context) { + if (setupCompleted) { + return + } + + lockSetup(cache, true) { + StepExecutor.executeStep( + context, + RunPaperclip( + bundle.dir.resolve(bundle.config.buildData.mojangMappedPaperclipFile), + mojangMappedPaperJar, + vanillaSteps.mojangJar, + minecraftVersion, + ) + ) + } + } + + private var setupCompleted = false + + @Synchronized + override fun createOrUpdateIvyRepository(context: SetupHandler.Context) { + if (setupCompleted) { + return + } + + lockSetup(cache) { + createOrUpdateIvyRepositoryDirect(context) + } + } + + private fun createOrUpdateIvyRepositoryDirect(context: SetupHandler.Context) { + val source = if (parameters.genSources.get()) { + generateSources(context) + patchedSourcesJar + } else { + vanillaSteps.downloadVanillaServerJar() + StepExecutor.executeStep(context, createExtractFromBundlerStep()) + null + } + + applyMojangMappedPaperclipPatch(context) + + val deps = mutableListOf() + deps.addAll(bundle.config.buildData.compileDependencies) + deps.add(bundle.config.apiCoordinates) + bundle.config.mojangApiCoordinates?.let { deps.add(it) } + installPaperServer( + cache, + bundle.config.mappedServerCoordinates, + deps, + mojangMappedPaperJar, + source, + minecraftVersion, + ) + + setupCompleted = true + } + + override fun configureIvyRepo(repo: IvyArtifactRepository) { + repo.content { + includeFromDependencyNotation(bundle.config.mappedServerCoordinates) + } + } + + override fun populateCompileConfiguration(context: SetupHandler.Context, dependencySet: DependencySet) { + dependencySet.add(context.project.dependencies.create(bundle.config.mappedServerCoordinates)) + } + + override fun populateRuntimeConfiguration(context: SetupHandler.Context, dependencySet: DependencySet) { + listOfNotNull( + bundle.config.mappedServerCoordinates, + bundle.config.apiCoordinates, + bundle.config.mojangApiCoordinates + ).forEach { coordinate -> + val dep = context.project.dependencies.create(coordinate).also { + (it as ExternalModuleDependency).isTransitive = false + } + dependencySet.add(dep) + } + + for (coordinates in bundle.config.buildData.runtimeDependencies) { + val dep = context.project.dependencies.create(coordinates).also { + (it as ExternalModuleDependency).isTransitive = false + } + dependencySet.add(dep) + } + } + + override fun serverJar(context: SetupHandler.Context): Path { + applyMojangMappedPaperclipPatch(context) + return mojangMappedPaperJar + } + + override val serverJar: Path + get() = mojangMappedPaperJar + + override val reobfMappings: Path + get() = bundle.dir.resolve(bundle.config.buildData.reobfMappingsFile) + + override val minecraftVersion: String + get() = bundle.config.minecraftVersion + + override val pluginRemapArgs: List + get() = bundle.config.buildData.pluginRemapArgs + + override val paramMappings: MavenDep + get() = bundle.config.buildData.paramMappings + + override val decompiler: MavenDep + get() = bundle.config.decompile.dep + + override val remapper: MavenDep + get() = bundle.config.remapper + + override val mache: MavenDep? + get() = null + + override val libraryRepositories: List + get() = bundle.config.buildData.libraryRepositories + + private fun createExtractFromBundlerStep(): ExtractFromBundlerStep = ExtractFromBundlerStep( + cache, + vanillaSteps, + vanillaServerJar, + minecraftLibraryJars, + ::minecraftLibraryJars + ) + + private class ExtractFromBundlerStep( + cache: Path, + private val vanillaSteps: VanillaSteps, + private val vanillaServerJar: Path, + private val minecraftLibraryJars: Path, + private val listMinecraftLibraryJars: () -> List, + ) : SetupStep { + override val name: String = "extract libraries and server from downloaded jar" + + override val hashFile: Path = cache.resolve(paperSetupOutput("extractFromServerBundler", "hashes")) + + override fun run(context: SetupHandler.Context) { + ServerBundler.extractFromBundler( + vanillaSteps.mojangJar, + vanillaServerJar, + minecraftLibraryJars, + null, + null, + null, + null, + ) + } + + override fun touchHashFunctionBuilder(builder: HashFunctionBuilder) { + builder.include(vanillaSteps.mojangJar, vanillaServerJar) + builder.include(listMinecraftLibraryJars()) + } + } +} From 9be31dd4f2d9abc3b5e01a291459ecbd66bbd6be Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Mon, 9 Dec 2024 11:19:16 -0700 Subject: [PATCH 27/38] Move userdev setup execution to task execution time Uses a hack where IntelliJ will attach sources inside the same jar as the classes. This is a working (and from what I can tell configuration cache-compatible) implementation, but is mostly the same pipeline, moved to task execution time. More work is still needed to clean this up and future-proof certain areas. --- .../paperweight/util/constants/constants.kt | 2 +- .../io/papermc/paperweight/util/utils.kt | 21 +++ .../paperweight/userdev/PaperweightUser.kt | 86 +++++---- .../userdev/PaperweightUserExtension.kt | 36 ++-- .../userdev/internal/setup/SetupHandler.kt | 63 +++++-- .../internal/setup/SetupHandlerImpl.kt | 169 +++++++----------- .../userdev/internal/setup/UserdevSetup.kt | 40 ++--- .../internal/setup/UserdevSetupTask.kt | 115 ++++++++++++ .../setup/step/AccessTransformMinecraft.kt | 4 +- .../setup/step/ApplyDevBundlePatches.kt | 24 +-- .../internal/setup/step/DecompileMinecraft.kt | 13 +- .../setup/step/ExtractFromBundlerStep.kt | 58 ++++++ .../setup/step/FilterPaperShadowJar.kt | 10 +- .../internal/setup/step/FilterVanillaJar.kt | 2 +- .../internal/setup/step/FixMinecraftJar.kt | 4 +- .../setup/step/GenerateMappingsStep.kt | 10 +- .../setup/step/MinecraftSourcesMache.kt | 23 ++- .../internal/setup/step/RemapMinecraft.kt | 12 +- .../setup/step/RemapMinecraftMache.kt | 25 ++- .../internal/setup/step/RunPaperclip.kt | 8 +- .../userdev/internal/setup/step/steps.kt | 6 +- .../internal/setup/v2/SetupHandlerImplV2.kt | 75 ++++---- .../internal/setup/v5/SetupHandlerImplV5.kt | 153 ++++++---------- 23 files changed, 550 insertions(+), 409 deletions(-) create mode 100644 paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/UserdevSetupTask.kt create mode 100644 paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/ExtractFromBundlerStep.kt diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt index 459598329..542512b00 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/constants/constants.kt @@ -49,7 +49,7 @@ const val MACHE_CODEBOOK_CONFIG = "macheCodebook" const val MACHE_REMAPPER_CONFIG = "macheRemapper" const val MACHE_DECOMPILER_CONFIG = "macheDecompiler" const val MACHE_PARAM_MAPPINGS_CONFIG = "macheParamMappings" -const val MACHE_CONSTANTS_CONFIG = "machineConstants" +const val MACHE_CONSTANTS_CONFIG = "macheConstants" const val RESTAMP_CONFIG = "restamp" const val DEV_BUNDLE_CONFIG = "paperweightDevelopmentBundle" const val MOJANG_MAPPED_SERVER_CONFIG = "mojangMappedServer" diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt index bf03a3952..22774dd6a 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt @@ -63,6 +63,7 @@ import org.gradle.api.file.RegularFileProperty import org.gradle.api.invocation.Gradle import org.gradle.api.logging.LogLevel import org.gradle.api.logging.Logger +import org.gradle.api.model.ObjectFactory import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.provider.Property import org.gradle.api.provider.Provider @@ -417,3 +418,23 @@ val mainCapabilityAttribute: Attribute = Attribute.of("io.papermc.paperw fun ConfigurationContainer.resolveMacheMeta() = getByName(MACHE_CONFIG).singleFile.toPath().openZip().use { zip -> gson.fromJson(zip.getPath("/mache.json").readText()) } + +fun isIDEASync(): Boolean = + java.lang.Boolean.getBoolean("idea.sync.active") + +inline fun ObjectFactory.providerSet( + vararg providers: Provider +): Provider> { + if (providers.isEmpty()) { + return setProperty() + } + var current: Provider>? = null + for (provider in providers) { + if (current == null) { + current = provider.map { setOf(it) } + } else { + current = current.zip(provider) { set, add -> set + add } + } + } + return current!! +} diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt index e3e59c2c8..eeada843d 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUser.kt @@ -31,7 +31,11 @@ import io.papermc.paperweight.userdev.attribute.Obfuscation import io.papermc.paperweight.userdev.internal.JunitExclusionRule import io.papermc.paperweight.userdev.internal.setup.SetupHandler import io.papermc.paperweight.userdev.internal.setup.UserdevSetup -import io.papermc.paperweight.userdev.internal.setup.util.* +import io.papermc.paperweight.userdev.internal.setup.UserdevSetupTask +import io.papermc.paperweight.userdev.internal.setup.util.cleanSharedCaches +import io.papermc.paperweight.userdev.internal.setup.util.genSources +import io.papermc.paperweight.userdev.internal.setup.util.paperweightHash +import io.papermc.paperweight.userdev.internal.setup.util.sharedCaches import io.papermc.paperweight.util.* import io.papermc.paperweight.util.constants.* import java.nio.file.Path @@ -49,10 +53,12 @@ import org.gradle.api.attributes.Bundling import org.gradle.api.attributes.Category import org.gradle.api.attributes.LibraryElements import org.gradle.api.attributes.Usage -import org.gradle.api.plugins.JavaPlugin import org.gradle.api.provider.Provider import org.gradle.api.tasks.Delete +import org.gradle.api.tasks.TaskProvider import org.gradle.api.tasks.bundling.Jar +import org.gradle.build.event.BuildEventsListenerRegistry +import org.gradle.internal.DefaultTaskExecutionRequest import org.gradle.jvm.toolchain.JavaToolchainService import org.gradle.kotlin.dsl.* import org.gradle.util.internal.NameMatcher @@ -69,6 +75,9 @@ abstract class PaperweightUser : Plugin { @get:Inject abstract val dependencyFactory: DependencyFactory + @get:Inject + abstract val buildEventsListenerRegistry: BuildEventsListenerRegistry + override fun apply(target: Project) { val sharedCacheRoot = target.gradle.gradleUserHomeDir.toPath().resolve("caches/paperweight-userdev") @@ -92,17 +101,18 @@ abstract class PaperweightUser : Plugin { attributes.attribute(DevBundleOutput.ATTRIBUTE, target.objects.named(DevBundleOutput.ZIP)) } + val setupTask = target.tasks.register("paperweightUserdevSetup", UserdevSetupTask::class) {} + // must not be initialized until afterEvaluate, as it resolves the dev bundle - val userdevSetup by lazy { createSetup(target, sharedCacheRoot.resolve(paperweightHash)) } + val userdevSetupProvider by lazy { createSetup(target, sharedCacheRoot.resolve(paperweightHash)) } + val userdevSetup by lazy { userdevSetupProvider.get() } val userdev = target.extensions.create( PAPERWEIGHT_EXTENSION, PaperweightUserExtension::class, - target, - workerExecutor, - javaToolchainService, target.provider { userdevSetup }, - target.objects + target.objects, + target, ) target.dependencies.extensions.create( @@ -111,14 +121,14 @@ abstract class PaperweightUser : Plugin { target.dependencies ) - createConfigurations(target, target.provider { userdevSetup }) + createConfigurations(target, target.provider { userdevSetup }, setupTask) val reobfJar by target.tasks.registering { group = "paperweight" description = "Remap the compiled plugin jar to Spigot's obfuscated runtime names." mappingsFile.pathProvider(target.provider { userdevSetup.reobfMappings }) - remapClasspath.from(target.provider { userdevSetup.serverJar }) + remapClasspath.from(setupTask.flatMap { it.mappedServerJar }) fromNamespace.set(DEOBF_NAMESPACE) toNamespace.set(SPIGOT_NAMESPACE) @@ -154,6 +164,13 @@ abstract class PaperweightUser : Plugin { return@afterEvaluate } + if (isIDEASync()) { + val startParameter = gradle.startParameter + val taskRequests = startParameter.taskRequests.toMutableList() + taskRequests.add(DefaultTaskExecutionRequest(listOf(setupTask.name))) + startParameter.setTaskRequests(taskRequests) + } + userdev.reobfArtifactConfiguration.get() .configure(this, reobfJar) @@ -174,7 +191,12 @@ abstract class PaperweightUser : Plugin { configureRepositories(userdevSetup) - userdevSetup.afterEvaluate(createContext(this)) + setupTask.configure { setupService.set(userdevSetupProvider) } + userdevSetup.afterEvaluate(this) + + userdev.addServerDependencyTo.get().forEach { + it.extendsFrom(target.configurations.getByName(MOJANG_MAPPED_SERVER_CONFIG)) + } cleanSharedCaches(this, sharedCacheRoot) } @@ -224,8 +246,6 @@ abstract class PaperweightUser : Plugin { for (repo in userdevSetup.libraryRepositories) { maven(repo) } - - userdevSetup.addIvyRepository(project) } private fun Project.checkForDevBundle() { @@ -247,7 +267,8 @@ abstract class PaperweightUser : Plugin { supplier: () -> MavenDep? ) { defaultDependencies { - for (dep in supplier()?.coordinates ?: emptyList()) { + val deps = supplier()?.coordinates ?: emptyList() + for (dep in deps) { val dependency = dependencyFactory.create(dep) dependency.isTransitive = transitive(dep) add(dependency) @@ -257,7 +278,8 @@ abstract class PaperweightUser : Plugin { private fun createConfigurations( target: Project, - userdevSetup: Provider + userdevSetup: Provider, + setupTask: TaskProvider, ) { target.configurations.register(MACHE_CONFIG) { dependenciesFrom { userdevSetup.get().mache } @@ -281,35 +303,25 @@ abstract class PaperweightUser : Plugin { makeRemapperConfig(REMAPPER_CONFIG) makeRemapperConfig(PLUGIN_REMAPPER_CONFIG) - val mojangMappedServerConfig = target.configurations.register(MOJANG_MAPPED_SERVER_CONFIG) { + target.configurations.register(MOJANG_MAPPED_SERVER_CONFIG) { defaultDependencies { - val ctx = createContext(target) - userdevSetup.get().let { setup -> - setup.createOrUpdateIvyRepository(ctx) - setup.populateCompileConfiguration(ctx, this) - } + userdevSetup.get() + .populateCompileConfiguration(createContext(target, setupTask), this) } } - target.configurations.register(MOJANG_MAPPED_SERVER_RUNTIME_CONFIG) - - target.plugins.withType().configureEach { - listOf( - JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME, - JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME, - MOJANG_MAPPED_SERVER_RUNTIME_CONFIG - ).map(target.configurations::named).forEach { config -> - config { - extendsFrom(mojangMappedServerConfig.get()) - } + target.configurations.register(MOJANG_MAPPED_SERVER_RUNTIME_CONFIG) { + defaultDependencies { + userdevSetup.get() + .populateRuntimeConfiguration(createContext(target, setupTask), this) } } } - private fun createContext(project: Project): SetupHandler.Context = - SetupHandler.Context(project, workerExecutor, javaToolchainService) + private fun createContext(project: Project, setupTask: TaskProvider): SetupHandler.ConfigurationContext = + SetupHandler.ConfigurationContext(project, dependencyFactory, setupTask) - private fun createSetup(target: Project, sharedCacheRoot: Path): UserdevSetup { + private fun createSetup(target: Project, sharedCacheRoot: Path): Provider { val bundleConfig = target.configurations.named(DEV_BUNDLE_CONFIG) val devBundleZip = bundleConfig.map { it.singleFile }.convertToPath() val bundleHash = devBundleZip.sha256asHex() @@ -331,8 +343,9 @@ abstract class PaperweightUser : Plugin { } val serviceName = "paperweight-userdev:setupService:$bundleHash" - return target.gradle.sharedServices + val ret = target.gradle.sharedServices .registerIfAbsent(serviceName, UserdevSetup::class) { + maxParallelUsages = 1 parameters { cache.set(cacheDir) bundleZip.set(devBundleZip) @@ -341,6 +354,7 @@ abstract class PaperweightUser : Plugin { genSources.set(target.genSources) } } - .get() + buildEventsListenerRegistry.onTaskCompletion(ret) + return ret } } diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUserExtension.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUserExtension.kt index 028fcc100..f62b2a766 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUserExtension.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/PaperweightUserExtension.kt @@ -25,23 +25,21 @@ package io.papermc.paperweight.userdev import io.papermc.paperweight.userdev.internal.setup.SetupHandler import io.papermc.paperweight.util.* import org.gradle.api.Project -import org.gradle.api.file.RegularFile +import org.gradle.api.artifacts.Configuration import org.gradle.api.model.ObjectFactory +import org.gradle.api.plugins.JavaPlugin import org.gradle.api.provider.Property import org.gradle.api.provider.Provider -import org.gradle.jvm.toolchain.JavaToolchainService +import org.gradle.api.provider.SetProperty import org.gradle.kotlin.dsl.* -import org.gradle.workers.WorkerExecutor /** * Extension exposing configuration and other APIs for paperweight userdev. */ abstract class PaperweightUserExtension( - project: Project, - workerExecutor: WorkerExecutor, - javaToolchainService: JavaToolchainService, setup: Provider, - objects: ObjectFactory + objects: ObjectFactory, + project: Project, ) { /** * Whether to inject the Paper maven repository for use by the dev bundle configuration. @@ -50,6 +48,16 @@ abstract class PaperweightUserExtension( */ val injectPaperRepository: Property = objects.property().convention(true) + /** + * Configurations to add the Minecraft server dependency to. + */ + val addServerDependencyTo: SetProperty = objects.setProperty().convention( + objects.providerSet( + project.configurations.named(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME), + project.configurations.named(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME) + ) + ) + /** * Whether to patch dependencies to exclude `junit:junit` from the transitive dependencies of `com.googlecode.json-simple:json-simple`. * @@ -62,19 +70,7 @@ abstract class PaperweightUserExtension( * as well as changing the classifiers of other jars (i.e. `jar` or `shadowJar`). */ val reobfArtifactConfiguration: Property = objects.property() - .convention(ReobfArtifactConfiguration.REOBF_PRODUCTION) - - /** - * Provides a runnable Mojang mapped server jar, extracted from the current dev bundle. - */ - @Deprecated( - message = "As of 1.18, the dev bundle no longer contains a runnable server jar. Use the mojangMappedServerRuntime configuration instead.", - replaceWith = ReplaceWith("project.configurations.mojangMappedServerRuntime"), - level = DeprecationLevel.WARNING - ) - val mojangMappedServerJar: Provider = objects.fileProperty().pathProvider( - setup.map { it.serverJar(SetupHandler.Context(project, workerExecutor, javaToolchainService)) } - ).withDisallowChanges().withDisallowUnsafeRead() + .convention(ReobfArtifactConfiguration.MOJANG_PRODUCTION) /** * Provides the Minecraft version of the current dev bundle. diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandler.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandler.kt index b42758b22..18f8b7f4d 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandler.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandler.kt @@ -29,30 +29,32 @@ import io.papermc.paperweight.userdev.internal.setup.v2.SetupHandlerImplV2 import io.papermc.paperweight.userdev.internal.setup.v5.DevBundleV5 import io.papermc.paperweight.userdev.internal.setup.v5.SetupHandlerImplV5 import io.papermc.paperweight.util.* +import io.papermc.paperweight.util.constants.* import java.nio.file.Path import org.gradle.api.Project import org.gradle.api.artifacts.DependencySet -import org.gradle.api.artifacts.repositories.IvyArtifactRepository +import org.gradle.api.artifacts.dsl.DependencyFactory +import org.gradle.api.file.FileCollection +import org.gradle.api.file.ProjectLayout +import org.gradle.api.logging.Logger +import org.gradle.api.tasks.TaskProvider import org.gradle.jvm.toolchain.JavaLauncher -import org.gradle.jvm.toolchain.JavaToolchainService +import org.gradle.kotlin.dsl.* import org.gradle.workers.WorkerExecutor interface SetupHandler { - fun createOrUpdateIvyRepository(context: Context) + fun populateCompileConfiguration(context: ConfigurationContext, dependencySet: DependencySet) - fun configureIvyRepo(repo: IvyArtifactRepository) + fun populateRuntimeConfiguration(context: ConfigurationContext, dependencySet: DependencySet) - fun populateCompileConfiguration(context: Context, dependencySet: DependencySet) + fun combinedOrClassesJar(context: ExecutionContext): Path - fun populateRuntimeConfiguration(context: Context, dependencySet: DependencySet) - - fun serverJar(context: Context): Path - - fun afterEvaluate(context: Context) { + fun afterEvaluate(project: Project) { + project.tasks.withType(UserdevSetupTask::class).configureEach { + devBundleCoordinates.set(determineArtifactCoordinates(project.configurations.getByName(DEV_BUNDLE_CONFIG)).single()) + } } - val serverJar: Path - val reobfMappings: Path val minecraftVersion: String @@ -69,15 +71,42 @@ interface SetupHandler { val libraryRepositories: List - data class Context( + data class ConfigurationContext( val project: Project, - val workerExecutor: WorkerExecutor, - val javaToolchainService: JavaToolchainService + val dependencyFactory: DependencyFactory, + val devBundleCoordinates: String, + val setupTask: TaskProvider, + val layout: ProjectLayout = project.layout, ) { - val defaultJavaLauncher: JavaLauncher - get() = javaToolchainService.defaultJavaLauncher(project).get() + constructor( + project: Project, + dependencyFactory: DependencyFactory, + setupTask: TaskProvider + ) : this( + project, + dependencyFactory, + determineArtifactCoordinates(project.configurations.getByName(DEV_BUNDLE_CONFIG)).single(), + setupTask, + ) } + data class ExecutionContext( + val workerExecutor: WorkerExecutor, + val javaLauncher: JavaLauncher, + val layout: ProjectLayout, + val logger: Logger, + + val decompilerConfig: FileCollection, + val paramMappingsConfig: FileCollection, + val macheDecompilerConfig: FileCollection, + val macheConfig: FileCollection, + val remapperConfig: FileCollection, + val macheRemapperConfig: FileCollection, + val macheParamMappingsConfig: FileCollection, + val macheConstantsConfig: FileCollection, + val macheCodebookConfig: FileCollection, + ) + companion object { @Suppress("unchecked_cast") fun create( diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandlerImpl.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandlerImpl.kt index 5f65ad5ff..be3b13ee1 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandlerImpl.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandlerImpl.kt @@ -24,15 +24,13 @@ package io.papermc.paperweight.userdev.internal.setup import io.papermc.paperweight.tasks.* import io.papermc.paperweight.userdev.internal.setup.step.* -import io.papermc.paperweight.userdev.internal.setup.step.MinecraftSourcesMache -import io.papermc.paperweight.userdev.internal.setup.step.RemapMinecraftMache -import io.papermc.paperweight.userdev.internal.setup.util.* +import io.papermc.paperweight.userdev.internal.setup.util.lockSetup import io.papermc.paperweight.util.* import io.papermc.paperweight.util.constants.* import io.papermc.paperweight.util.data.mache.* import java.nio.file.Path +import org.gradle.api.Project import org.gradle.api.artifacts.DependencySet -import org.gradle.api.artifacts.repositories.IvyArtifactRepository import org.gradle.kotlin.dsl.* class SetupHandlerImpl( @@ -58,7 +56,7 @@ class SetupHandlerImpl( private fun minecraftLibraryJars(): List = minecraftLibraryJars.filesMatchingRecursive("*.jar") - private fun generateSources(context: SetupHandler.Context) { + private fun generateSources(context: SetupHandler.ExecutionContext) { vanillaSteps.downloadVanillaServerJar() vanillaSteps.downloadServerMappings() applyMojangMappedPaperclipPatch(context) @@ -105,7 +103,7 @@ class SetupHandlerImpl( // PaperweightUserExtension, possibly by a task running in a separate // thread to dependency resolution. @Synchronized - private fun applyMojangMappedPaperclipPatch(context: SetupHandler.Context) { + private fun applyMojangMappedPaperclipPatch(context: SetupHandler.ExecutionContext) { if (setupCompleted) { return } @@ -123,96 +121,88 @@ class SetupHandlerImpl( } } + override fun populateCompileConfiguration(context: SetupHandler.ConfigurationContext, dependencySet: DependencySet) { + dependencySet.add(context.dependencyFactory.create(context.layout.files(context.setupTask.flatMap { it.mappedServerJar }))) + dependencySet.add(context.dependencyFactory.create(context.devBundleCoordinates)) + } + + override fun populateRuntimeConfiguration(context: SetupHandler.ConfigurationContext, dependencySet: DependencySet) { + populateCompileConfiguration(context, dependencySet) + } + private var setupCompleted = false @Synchronized - override fun createOrUpdateIvyRepository(context: SetupHandler.Context) { + override fun combinedOrClassesJar(context: SetupHandler.ExecutionContext): Path { if (setupCompleted) { - return - } - - lockSetup(cache) { - createOrUpdateIvyRepositoryDirect(context) + return if (parameters.genSources.get()) { + patchedSourcesJar + } else { + mojangMappedPaperJar + } } - } - private fun createOrUpdateIvyRepositoryDirect(context: SetupHandler.Context) { - val source = if (parameters.genSources.get()) { - generateSources(context) - patchedSourcesJar - } else { - vanillaSteps.downloadVanillaServerJar() - StepExecutor.executeStep(context, createExtractFromBundlerStep()) - applyMojangMappedPaperclipPatch(context) - null + val ret = lockSetup(cache) { + if (parameters.genSources.get()) { + generateSources(context) + patchedSourcesJar + } else { + vanillaSteps.downloadVanillaServerJar() + StepExecutor.executeStep(context, createExtractFromBundlerStep()) + applyMojangMappedPaperclipPatch(context) + mojangMappedPaperJar + } } - installPaperServer( - cache, - mappedServerCoordinates(), - determineArtifactCoordinates(context.project.configurations.getByName(DEV_BUNDLE_CONFIG)), - mojangMappedPaperJar, - source, - minecraftVersion, - ) - setupCompleted = true - } - - private fun mappedServerCoordinates(): String = - "io.papermc.paperweight:dev-bundle-server:$minecraftVersion" - - override fun configureIvyRepo(repo: IvyArtifactRepository) { - repo.content { - includeFromDependencyNotation(mappedServerCoordinates()) - } - } - - override fun populateCompileConfiguration(context: SetupHandler.Context, dependencySet: DependencySet) { - dependencySet.add(context.project.dependencies.create(mappedServerCoordinates())) - } - - override fun populateRuntimeConfiguration(context: SetupHandler.Context, dependencySet: DependencySet) { - dependencySet.add(context.project.dependencies.create(mappedServerCoordinates())) - } - override fun serverJar(context: SetupHandler.Context): Path { - applyMojangMappedPaperclipPatch(context) - return mojangMappedPaperJar + return ret } private fun macheMeta(): MacheMeta = requireNotNull(macheMeta) { "Mache meta is not setup yet" } - @Synchronized - override fun afterEvaluate(context: SetupHandler.Context) { - val project = context.project + override fun afterEvaluate(project: Project) { + super.afterEvaluate(project) val configurations = project.configurations if (macheMeta == null) { - macheMeta = configurations.resolveMacheMeta() - - configurations.register(MACHE_CODEBOOK_CONFIG) { - isTransitive = false - } - configurations.register(MACHE_REMAPPER_CONFIG) { - isTransitive = false - } - configurations.register(MACHE_DECOMPILER_CONFIG) { - isTransitive = false - } - configurations.register(MACHE_PARAM_MAPPINGS_CONFIG) { - isTransitive = false + synchronized(this) { + macheMeta = configurations.resolveMacheMeta() } - configurations.register(MACHE_CONSTANTS_CONFIG) { - isTransitive = false + } + + val macheCodebook = configurations.register(MACHE_CODEBOOK_CONFIG) { + isTransitive = false + } + val macheRemapper = configurations.register(MACHE_REMAPPER_CONFIG) { + isTransitive = false + } + val macheDecompiler = configurations.register(MACHE_DECOMPILER_CONFIG) { + isTransitive = false + } + val macheParamMappings = configurations.register(MACHE_PARAM_MAPPINGS_CONFIG) { + isTransitive = false + } + val macheConstants = configurations.register(MACHE_CONSTANTS_CONFIG) { + isTransitive = false + } + + project.tasks.withType(UserdevSetupTask::class).configureEach { + if (parameters.genSources.get()) { + mappedServerJar.set(patchedSourcesJar) + } else { + mappedServerJar.set(mojangMappedPaperJar) } - macheMeta().addDependencies(project) - macheMeta().addRepositories(project) + macheCodebookConfig.from(macheCodebook) + macheRemapperConfig.from(macheRemapper) + macheDecompilerConfig.from(macheDecompiler) + macheParamMappingsConfig.from(macheParamMappings) + macheConstantsConfig.from(macheConstants) } - } - override val serverJar: Path - get() = mojangMappedPaperJar + macheMeta().addDependencies(project) + macheMeta().addRepositories(project) + } override val reobfMappings: Path get() = bundle.dir.resolve(bundle.config.reobfMappingsFile) @@ -245,33 +235,4 @@ class SetupHandlerImpl( minecraftLibraryJars, ::minecraftLibraryJars ) - - private class ExtractFromBundlerStep( - cache: Path, - private val vanillaSteps: VanillaSteps, - private val vanillaServerJar: Path, - private val minecraftLibraryJars: Path, - private val listMinecraftLibraryJars: () -> List, - ) : SetupStep { - override val name: String = "extract libraries and server from downloaded jar" - - override val hashFile: Path = cache.resolve(paperSetupOutput("extractFromServerBundler", "hashes")) - - override fun run(context: SetupHandler.Context) { - ServerBundler.extractFromBundler( - vanillaSteps.mojangJar, - vanillaServerJar, - minecraftLibraryJars, - null, - null, - null, - null, - ) - } - - override fun touchHashFunctionBuilder(builder: HashFunctionBuilder) { - builder.include(vanillaSteps.mojangJar, vanillaServerJar) - builder.include(listMinecraftLibraryJars()) - } - } } diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/UserdevSetup.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/UserdevSetup.kt index 4b8c33652..05f3013c8 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/UserdevSetup.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/UserdevSetup.kt @@ -30,16 +30,16 @@ import java.nio.file.Path import kotlin.io.path.* import org.gradle.api.Project import org.gradle.api.artifacts.DependencySet -import org.gradle.api.artifacts.repositories.IvyArtifactRepository import org.gradle.api.file.RegularFileProperty import org.gradle.api.logging.Logger import org.gradle.api.logging.Logging import org.gradle.api.provider.Property import org.gradle.api.services.BuildService import org.gradle.api.services.BuildServiceParameters -import org.gradle.kotlin.dsl.* +import org.gradle.tooling.events.FinishEvent +import org.gradle.tooling.events.OperationCompletionListener -abstract class UserdevSetup : BuildService, SetupHandler { +abstract class UserdevSetup : BuildService, SetupHandler, AutoCloseable, OperationCompletionListener { companion object { val LOGGER: Logger = Logging.getLogger(UserdevSetup::class.java) @@ -68,42 +68,32 @@ abstract class UserdevSetup : BuildService, SetupHandle private fun createSetup(): SetupHandler = SetupHandler.create(parameters, extractDevBundle) - fun addIvyRepository(project: Project) { - project.repositories { - setupIvyRepository(parameters.cache.path.resolve(IVY_REPOSITORY)) { - configureIvyRepo(this) - } - } + override fun onFinish(event: FinishEvent?) { + // no-op, a workaround to keep the service alive for the entire build + // see https://github.com/diffplug/spotless/pull/720#issuecomment-713399731 } - // begin delegate to setup - override fun createOrUpdateIvyRepository(context: SetupHandler.Context) { - setup.createOrUpdateIvyRepository(context) - } - - override fun configureIvyRepo(repo: IvyArtifactRepository) { - setup.configureIvyRepo(repo) + override fun close() { + // see comments in onFinish } - override fun populateCompileConfiguration(context: SetupHandler.Context, dependencySet: DependencySet) { + // begin delegate to setup + override fun populateCompileConfiguration(context: SetupHandler.ConfigurationContext, dependencySet: DependencySet) { setup.populateCompileConfiguration(context, dependencySet) } - override fun populateRuntimeConfiguration(context: SetupHandler.Context, dependencySet: DependencySet) { + override fun populateRuntimeConfiguration(context: SetupHandler.ConfigurationContext, dependencySet: DependencySet) { setup.populateRuntimeConfiguration(context, dependencySet) } - override fun serverJar(context: SetupHandler.Context): Path { - return setup.serverJar(context) + override fun combinedOrClassesJar(context: SetupHandler.ExecutionContext): Path { + return setup.combinedOrClassesJar(context) } - override fun afterEvaluate(context: SetupHandler.Context) { - setup.afterEvaluate(context) + override fun afterEvaluate(project: Project) { + setup.afterEvaluate(project) } - override val serverJar: Path - get() = setup.serverJar - override val reobfMappings: Path get() = setup.reobfMappings diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/UserdevSetupTask.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/UserdevSetupTask.kt new file mode 100644 index 000000000..3b0f71402 --- /dev/null +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/UserdevSetupTask.kt @@ -0,0 +1,115 @@ +/* + * 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.userdev.internal.setup + +import io.papermc.paperweight.tasks.* +import io.papermc.paperweight.util.constants.* +import javax.inject.Inject +import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.RegularFileProperty +import org.gradle.api.provider.Property +import org.gradle.api.services.ServiceReference +import org.gradle.api.tasks.CompileClasspath +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.Optional +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction +import org.gradle.workers.WorkerExecutor + +abstract class UserdevSetupTask : JavaLauncherTask() { + @get:ServiceReference + abstract val setupService: Property + + @get:Inject + abstract val workerExecutor: WorkerExecutor + + @get:Input + abstract val devBundleCoordinates: Property + + @get:CompileClasspath + abstract val devBundle: ConfigurableFileCollection + + @get:CompileClasspath + abstract val decompilerConfig: ConfigurableFileCollection + + @get:CompileClasspath + abstract val paramMappingsConfig: ConfigurableFileCollection + + @get:CompileClasspath + abstract val macheDecompilerConfig: ConfigurableFileCollection + + @get:CompileClasspath + abstract val macheConfig: ConfigurableFileCollection + + @get:CompileClasspath + abstract val remapperConfig: ConfigurableFileCollection + + @get:CompileClasspath + abstract val macheRemapperConfig: ConfigurableFileCollection + + @get:CompileClasspath + abstract val macheParamMappingsConfig: ConfigurableFileCollection + + @get:CompileClasspath + abstract val macheConstantsConfig: ConfigurableFileCollection + + @get:CompileClasspath + abstract val macheCodebookConfig: ConfigurableFileCollection + + @get:OutputFile + abstract val mappedServerJar: RegularFileProperty + + @get:OutputFile + @get:Optional + abstract val legacyPaperclipResult: RegularFileProperty + + override fun init() { + super.init() + devBundle.from(project.configurations.named(DEV_BUNDLE_CONFIG)) + decompilerConfig.from(project.configurations.named(DECOMPILER_CONFIG)) + paramMappingsConfig.from(project.configurations.named(PARAM_MAPPINGS_CONFIG)) + remapperConfig.from(project.configurations.named(REMAPPER_CONFIG)) + macheConfig.from(project.configurations.named(MACHE_CONFIG)) + } + + @TaskAction + fun run() { + val context = SetupHandler.ExecutionContext( + workerExecutor, + launcher.get(), + layout, + logger, + decompilerConfig, + paramMappingsConfig, + macheDecompilerConfig, + macheConfig, + remapperConfig, + macheRemapperConfig, + macheParamMappingsConfig, + macheConstantsConfig, + macheCodebookConfig, + ) + + setupService.get().combinedOrClassesJar(context) + } +} diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/AccessTransformMinecraft.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/AccessTransformMinecraft.kt index 5e1ded706..2ec6d1aa9 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/AccessTransformMinecraft.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/AccessTransformMinecraft.kt @@ -36,13 +36,13 @@ class AccessTransformMinecraft( override val hashFile: Path = outputJar.siblingHashesFile() - override fun run(context: SetupHandler.Context) { + override fun run(context: SetupHandler.ExecutionContext) { applyAccessTransform( inputJarPath = inputJar, outputJarPath = outputJar, atFilePath = at, workerExecutor = context.workerExecutor, - launcher = context.defaultJavaLauncher + launcher = context.javaLauncher ).await() } } diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/ApplyDevBundlePatches.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/ApplyDevBundlePatches.kt index b6b9ca90b..f8a29d0b0 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/ApplyDevBundlePatches.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/ApplyDevBundlePatches.kt @@ -42,13 +42,14 @@ class ApplyDevBundlePatches( @Input private val decompiledJar: Path, private val devBundlePatches: Path, @Output private val outputJar: Path, - @Input private val resourcesJar: Path? = null, + @Input private val patchedJar: Path? = null, ) : SetupStep { - override val name: String = "apply patches to decompiled jar" + override val name: String + get() = if (patchedJar == null) "apply patches to decompiled jar" else "apply source patches and merge jars" override val hashFile: Path = outputJar.siblingHashesFile() - override fun run(context: SetupHandler.Context) { + override fun run(context: SetupHandler.ExecutionContext) { val tempPatchDir = findOutputDir(outputJar) val outputDir = findOutputDir(outputJar) val log = outputJar.siblingLogFile() @@ -90,20 +91,19 @@ class ApplyDevBundlePatches( ensureDeleted(outputJar) zip(outputDir, outputJar) - // Bring in resources - resourcesJar?.let { jarWithResources -> + // Merge classes and resources in + patchedJar?.let { patched -> outputJar.openZip().use { fs -> val out = fs.getPath("/") - jarWithResources.openZip().use { resources -> - val vanilla = resources.getPath("/") + patched.openZip().use { patchedFs -> + val patchedRoot = patchedFs.getPath("/") - vanilla.walk() + patchedRoot.walk() .filter { it.isRegularFile() } - .filterNot { it.name.endsWith(".class") } - .forEach { resourceFile -> - val copyTo = out.resolve(resourceFile.relativeTo(vanilla).invariantSeparatorsPathString) + .forEach { file -> + val copyTo = out.resolve(file.relativeTo(patchedRoot).invariantSeparatorsPathString) copyTo.createParentDirectories() - resourceFile.copyTo(copyTo) + file.copyTo(copyTo) } } } diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/DecompileMinecraft.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/DecompileMinecraft.kt index 85bfb2892..41e53486d 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/DecompileMinecraft.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/DecompileMinecraft.kt @@ -27,9 +27,8 @@ import io.papermc.paperweight.userdev.internal.setup.SetupHandler import io.papermc.paperweight.userdev.internal.setup.util.HashFunctionBuilder import io.papermc.paperweight.userdev.internal.setup.util.siblingHashesFile import io.papermc.paperweight.userdev.internal.setup.util.siblingLogFile -import io.papermc.paperweight.util.constants.DECOMPILER_CONFIG import java.nio.file.Path -import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.FileCollection class DecompileMinecraft( @Input private val inputJar: Path, @@ -37,13 +36,13 @@ class DecompileMinecraft( private val cache: Path, private val minecraftLibraryJars: () -> List, @Input private val decompileArgs: List, - private val decompiler: Configuration, + private val decompiler: FileCollection, ) : SetupStep { override val name: String = "decompile transformed minecraft server jar" override val hashFile: Path = outputJar.siblingHashesFile() - override fun run(context: SetupHandler.Context) { + override fun run(context: SetupHandler.ExecutionContext) { runDecompiler( argsList = decompileArgs, logFile = outputJar.siblingLogFile(), @@ -52,7 +51,7 @@ class DecompileMinecraft( inputJar = inputJar, libraries = minecraftLibraryJars(), outputJar = outputJar, - javaLauncher = context.defaultJavaLauncher + javaLauncher = context.javaLauncher ) } @@ -64,14 +63,14 @@ class DecompileMinecraft( companion object { fun create( - context: SetupHandler.Context, + context: SetupHandler.ExecutionContext, inputJar: Path, outputJar: Path, cache: Path, minecraftLibraryJars: () -> List, decompileArgs: List, ): DecompileMinecraft { - val decompiler = context.project.configurations.getByName(DECOMPILER_CONFIG).also { it.resolve() } // resolve decompiler + val decompiler = context.decompilerConfig.also { it.files.size } // resolve decompiler return DecompileMinecraft(inputJar, outputJar, cache, minecraftLibraryJars, decompileArgs, decompiler) } } diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/ExtractFromBundlerStep.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/ExtractFromBundlerStep.kt new file mode 100644 index 000000000..79e587a87 --- /dev/null +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/ExtractFromBundlerStep.kt @@ -0,0 +1,58 @@ +/* + * 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.userdev.internal.setup.step + +import io.papermc.paperweight.tasks.ServerBundler +import io.papermc.paperweight.userdev.internal.setup.SetupHandler +import io.papermc.paperweight.userdev.internal.setup.util.HashFunctionBuilder +import io.papermc.paperweight.util.constants.paperSetupOutput +import java.nio.file.Path + +class ExtractFromBundlerStep( + cache: Path, + private val vanillaSteps: VanillaSteps, + private val vanillaServerJar: Path, + private val minecraftLibraryJars: Path, + private val listMinecraftLibraryJars: () -> List, +) : SetupStep { + override val name: String = "extract libraries and server from downloaded jar" + + override val hashFile: Path = cache.resolve(paperSetupOutput("extractFromServerBundler", "hashes")) + + override fun run(context: SetupHandler.ExecutionContext) { + ServerBundler.extractFromBundler( + vanillaSteps.mojangJar, + vanillaServerJar, + minecraftLibraryJars, + null, + null, + null, + null, + ) + } + + override fun touchHashFunctionBuilder(builder: HashFunctionBuilder) { + builder.include(vanillaSteps.mojangJar, vanillaServerJar) + builder.include(listMinecraftLibraryJars()) + } +} diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/FilterPaperShadowJar.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/FilterPaperShadowJar.kt index 217f29928..0ce5e7031 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/FilterPaperShadowJar.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/FilterPaperShadowJar.kt @@ -37,11 +37,11 @@ class FilterPaperShadowJar( @Output private val outputJar: Path, private val relocations: List, ) : SetupStep { - override val name: String = "filter mojang mapped paper jar" + override val name: String = "filter and merge mojang mapped paper jar" override val hashFile: Path = outputJar.siblingHashesFile() - override fun run(context: SetupHandler.Context) { + override fun run(context: SetupHandler.ExecutionContext) { filterPaperJar(sourcesJar, inputJar, outputJar, relocations) } @@ -77,6 +77,12 @@ class FilterPaperShadowJar( includedFiles.contains(str) } } + + outputJar.openZip().use { outFs -> + sourcesJar.openZip().use { sourcesFs -> + sourcesFs.getPath("/").copyRecursivelyTo(outFs.getPath("/")) + } + } } private fun collectIncludes( diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/FilterVanillaJar.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/FilterVanillaJar.kt index 1b2498a5d..ff51aed0f 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/FilterVanillaJar.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/FilterVanillaJar.kt @@ -36,7 +36,7 @@ class FilterVanillaJar( override val hashFile: Path = outputJar.siblingHashesFile() - override fun run(context: SetupHandler.Context) { + override fun run(context: SetupHandler.ExecutionContext) { filterJar(vanillaJar, outputJar, includes) } } diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/FixMinecraftJar.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/FixMinecraftJar.kt index 27084e354..62f489e91 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/FixMinecraftJar.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/FixMinecraftJar.kt @@ -37,10 +37,10 @@ class FixMinecraftJar( override val hashFile: Path = outputJar.siblingHashesFile() - override fun run(context: SetupHandler.Context) { + override fun run(context: SetupHandler.ExecutionContext) { fixJar( workerExecutor = context.workerExecutor, - launcher = context.defaultJavaLauncher, + launcher = context.javaLauncher, vanillaJarPath = vanillaServerJar, inputJarPath = inputJar, outputJarPath = outputJar, diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/GenerateMappingsStep.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/GenerateMappingsStep.kt index fd8b318d5..f7bc503bd 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/GenerateMappingsStep.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/GenerateMappingsStep.kt @@ -26,8 +26,6 @@ import io.papermc.paperweight.tasks.* import io.papermc.paperweight.userdev.internal.setup.SetupHandler import io.papermc.paperweight.userdev.internal.setup.util.HashFunctionBuilder import io.papermc.paperweight.userdev.internal.setup.util.siblingHashesFile -import io.papermc.paperweight.util.* -import io.papermc.paperweight.util.constants.* import java.nio.file.Path class GenerateMappingsStep( @@ -41,7 +39,7 @@ class GenerateMappingsStep( override val hashFile: Path = outputMappings.siblingHashesFile() - override fun run(context: SetupHandler.Context) { + override fun run(context: SetupHandler.ExecutionContext) { generateMappings( vanillaJarPath = filteredVanillaJar, libraryPaths = minecraftLibraryJars(), @@ -49,7 +47,7 @@ class GenerateMappingsStep( paramMappingsPath = paramMappings, outputMappingsPath = outputMappings, workerExecutor = context.workerExecutor, - launcher = context.defaultJavaLauncher + launcher = context.javaLauncher ).await() } @@ -60,7 +58,7 @@ class GenerateMappingsStep( companion object { fun create( - context: SetupHandler.Context, + context: SetupHandler.ExecutionContext, vanillaSteps: VanillaSteps, filteredVanillaJar: Path, minecraftLibraryJars: () -> List, @@ -69,7 +67,7 @@ class GenerateMappingsStep( vanillaSteps.downloadServerMappings() // resolve param mappings - val paramMappings = context.project.configurations.named(PARAM_MAPPINGS_CONFIG).map { it.singleFile }.convertToPath() + val paramMappings = context.paramMappingsConfig.singleFile.toPath() return GenerateMappingsStep(vanillaSteps, filteredVanillaJar, paramMappings, minecraftLibraryJars, outputMappings) } diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/MinecraftSourcesMache.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/MinecraftSourcesMache.kt index 02fb945b5..df47eefec 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/MinecraftSourcesMache.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/MinecraftSourcesMache.kt @@ -29,11 +29,10 @@ import io.papermc.paperweight.tasks.mache.macheDecompileJar import io.papermc.paperweight.userdev.internal.setup.SetupHandler import io.papermc.paperweight.userdev.internal.setup.util.HashFunctionBuilder import io.papermc.paperweight.userdev.internal.setup.util.siblingHashesFile -import io.papermc.paperweight.util.* -import io.papermc.paperweight.util.constants.* +import io.papermc.paperweight.util.ensureClean import java.nio.file.Path -import kotlin.io.path.* -import org.gradle.api.artifacts.Configuration +import kotlin.io.path.name +import org.gradle.api.file.FileCollection import org.gradle.api.logging.LogLevel class MinecraftSourcesMache( @@ -42,14 +41,14 @@ class MinecraftSourcesMache( private val cache: Path, private val minecraftLibraryJars: () -> List, @Input private val decompileArgs: List, - private val decompiler: Configuration, - private val mache: Configuration, + private val decompiler: FileCollection, + private val mache: FileCollection, ) : SetupStep { override val name: String = "decompile and setup sources with mache" override val hashFile: Path = outputJar.siblingHashesFile() - override fun run(context: SetupHandler.Context) { + override fun run(context: SetupHandler.ExecutionContext) { // Decompile val tempOut = outputJar.resolveSibling("${outputJar.name}.tmp") macheDecompileJar( @@ -57,7 +56,7 @@ class MinecraftSourcesMache( minecraftLibraryJars(), decompileArgs, inputJar, - context.defaultJavaLauncher, + context.javaLauncher, decompiler, cache, ) @@ -65,7 +64,7 @@ class MinecraftSourcesMache( // Apply mache patches outputJar.ensureClean() val result = PatchOperation.builder() - .logTo(LoggingOutputStream(context.project.logger, LogLevel.LIFECYCLE)) + .logTo(LoggingOutputStream(context.logger, LogLevel.LIFECYCLE)) .basePath(tempOut, ArchiveFormat.ZIP) .outputPath(outputJar, ArchiveFormat.ZIP) .patchesPath(mache.singleFile.toPath(), ArchiveFormat.ZIP) @@ -89,7 +88,7 @@ class MinecraftSourcesMache( companion object { fun create( - context: SetupHandler.Context, + context: SetupHandler.ExecutionContext, inputJar: Path, outputJar: Path, cache: Path, @@ -97,8 +96,8 @@ class MinecraftSourcesMache( decompileArgs: List, ): MinecraftSourcesMache { // resolve dependencies - val decompiler = context.project.configurations.getByName(MACHE_DECOMPILER_CONFIG).also { it.resolve() } - val mache = context.project.configurations.getByName(MACHE_CONFIG).also { it.resolve() } + val decompiler = context.macheDecompilerConfig.also { it.files.size } + val mache = context.macheConfig.also { it.files.size } return MinecraftSourcesMache(inputJar, outputJar, cache, minecraftLibraryJars, decompileArgs, decompiler, mache) } } diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RemapMinecraft.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RemapMinecraft.kt index 428777b2e..bd6f57281 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RemapMinecraft.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RemapMinecraft.kt @@ -29,14 +29,14 @@ import io.papermc.paperweight.userdev.internal.setup.util.siblingHashesFile import io.papermc.paperweight.userdev.internal.setup.util.siblingLogFile import io.papermc.paperweight.util.constants.* import java.nio.file.Path -import org.gradle.api.artifacts.Configuration +import org.gradle.api.file.FileCollection class RemapMinecraft( @Input private val minecraftRemapArgs: List, @Input private val filteredVanillaJar: Path, private val minecraftLibraryJars: () -> List, @Input private val mappings: Path, - private val remapper: Configuration, + private val remapper: FileCollection, @Output private val outputJar: Path, private val cache: Path, ) : SetupStep { @@ -44,7 +44,7 @@ class RemapMinecraft( override val hashFile: Path = outputJar.siblingHashesFile() - override fun run(context: SetupHandler.Context) { + override fun run(context: SetupHandler.ExecutionContext) { TinyRemapper.run( argsList = minecraftRemapArgs, logFile = outputJar.siblingLogFile(), @@ -55,7 +55,7 @@ class RemapMinecraft( remapClasspath = minecraftLibraryJars(), remapper = remapper, outputJar = outputJar, - launcher = context.defaultJavaLauncher, + launcher = context.javaLauncher, workingDir = cache ) } @@ -68,7 +68,7 @@ class RemapMinecraft( companion object { fun create( - context: SetupHandler.Context, + context: SetupHandler.ExecutionContext, minecraftRemapArgs: List, filteredVanillaJar: Path, minecraftLibraryJars: () -> List, @@ -76,7 +76,7 @@ class RemapMinecraft( outputJar: Path, cache: Path, ): RemapMinecraft { - val remapper = context.project.configurations.getByName(REMAPPER_CONFIG).also { it.resolve() } // resolve remapper + val remapper = context.remapperConfig.also { it.files.size } // resolve remapper return RemapMinecraft( minecraftRemapArgs, filteredVanillaJar, diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RemapMinecraftMache.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RemapMinecraftMache.kt index afe6bd1a3..34c5c8de1 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RemapMinecraftMache.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RemapMinecraftMache.kt @@ -26,11 +26,10 @@ import io.papermc.paperweight.tasks.mache.macheRemapJar import io.papermc.paperweight.userdev.internal.setup.SetupHandler import io.papermc.paperweight.userdev.internal.setup.util.HashFunctionBuilder import io.papermc.paperweight.userdev.internal.setup.util.siblingHashesFile -import io.papermc.paperweight.util.* -import io.papermc.paperweight.util.constants.* +import io.papermc.paperweight.util.deleteRecursive import java.nio.file.Path -import kotlin.io.path.* -import org.gradle.api.artifacts.Configuration +import kotlin.io.path.createTempDirectory +import org.gradle.api.file.FileCollection class RemapMinecraftMache( @Input private val minecraftRemapArgs: List, @@ -39,8 +38,8 @@ class RemapMinecraftMache( @Input private val mappings: Path, @Input private val paramMappings: Path, @Input private val constants: Path?, - private val codebook: Configuration, - private val remapper: Configuration, + private val codebook: FileCollection, + private val remapper: FileCollection, @Output private val outputJar: Path, private val cache: Path, ) : SetupStep { @@ -48,10 +47,10 @@ class RemapMinecraftMache( override val hashFile: Path = outputJar.siblingHashesFile() - override fun run(context: SetupHandler.Context) { + override fun run(context: SetupHandler.ExecutionContext) { val temp = createTempDirectory(cache, "remap") macheRemapJar( - context.defaultJavaLauncher, + context.javaLauncher, codebook, outputJar, minecraftRemapArgs, @@ -75,7 +74,7 @@ class RemapMinecraftMache( companion object { fun create( - context: SetupHandler.Context, + context: SetupHandler.ExecutionContext, minecraftRemapArgs: List, vanillaJar: Path, minecraftLibraryJars: () -> List, @@ -84,10 +83,10 @@ class RemapMinecraftMache( cache: Path, ): RemapMinecraftMache { // resolve dependencies - val remapper = context.project.configurations.getByName(MACHE_REMAPPER_CONFIG).also { it.resolve() } - val paramMappings = context.project.configurations.getByName(MACHE_PARAM_MAPPINGS_CONFIG).singleFile.toPath() - val constants = context.project.configurations.getByName(MACHE_CONSTANTS_CONFIG).files.singleOrNull()?.toPath() - val codebook = context.project.configurations.getByName(MACHE_CODEBOOK_CONFIG).also { it.resolve() } + val remapper = context.macheRemapperConfig.also { it.files.size } + val paramMappings = context.macheParamMappingsConfig.singleFile.toPath() + val constants = context.macheConstantsConfig.files.singleOrNull()?.toPath() + val codebook = context.macheCodebookConfig.also { it.files.size } return RemapMinecraftMache( minecraftRemapArgs, vanillaJar, diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RunPaperclip.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RunPaperclip.kt index 78a5e9334..1b4da1172 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RunPaperclip.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/RunPaperclip.kt @@ -45,7 +45,7 @@ class RunPaperclip( override val hashFile: Path = outputJar.siblingHashesFile() - override fun run(context: SetupHandler.Context) { + override fun run(context: SetupHandler.ExecutionContext) { patchPaperclip(context, paperclip, outputJar, mojangJar, minecraftVersion, bundler) } @@ -54,7 +54,7 @@ class RunPaperclip( } private fun patchPaperclip( - context: SetupHandler.Context, + context: SetupHandler.ExecutionContext, paperclip: Path, outputJar: Path, mojangJar: Path, @@ -71,8 +71,8 @@ class RunPaperclip( cache.createDirectories() mojangJar.copyTo(cache.resolve("mojang_$minecraftVersion.jar")) - context.defaultJavaLauncher.runJar( - classpath = context.project.files(paperclip), + context.javaLauncher.runJar( + classpath = context.layout.files(paperclip), workingDir = work, logFile = logFile, jvmArgs = listOf("-Dpaperclip.patchonly=true"), diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/steps.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/steps.kt index dbae6e4c5..a20ffba5f 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/steps.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/step/steps.kt @@ -50,7 +50,7 @@ interface SetupStep { val hashFile: Path - fun run(context: SetupHandler.Context) + fun run(context: SetupHandler.ExecutionContext) fun touchHashFunctionBuilder(builder: HashFunctionBuilder) {} } @@ -64,7 +64,7 @@ object StepExecutor { private val inputOutputDataCache: MutableMap, InputOutputData> = ConcurrentHashMap, InputOutputData>() - fun executeSteps(expectingChange: Boolean, context: SetupHandler.Context, vararg steps: SetupStep) { + fun executeSteps(expectingChange: Boolean, context: SetupHandler.ExecutionContext, vararg steps: SetupStep) { // if we aren't expecting change, assume the last step is the output that matters // and only verify its inputs/outputs - if it fails then we need to go back through // and check each step anyway @@ -87,7 +87,7 @@ object StepExecutor { } } - fun executeStep(context: SetupHandler.Context, step: SetupStep) { + fun executeStep(context: SetupHandler.ExecutionContext, step: SetupStep) { val hashFunction = makeHashFunction(step) if (hashFunction.upToDate(step.hashFile)) { diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v2/SetupHandlerImplV2.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v2/SetupHandlerImplV2.kt index 01a709710..050a7a1e8 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v2/SetupHandlerImplV2.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v2/SetupHandlerImplV2.kt @@ -27,14 +27,16 @@ import io.papermc.paperweight.userdev.internal.setup.ExtractedBundle import io.papermc.paperweight.userdev.internal.setup.RunPaperclip import io.papermc.paperweight.userdev.internal.setup.SetupHandler import io.papermc.paperweight.userdev.internal.setup.UserdevSetup +import io.papermc.paperweight.userdev.internal.setup.UserdevSetupTask import io.papermc.paperweight.userdev.internal.setup.step.* import io.papermc.paperweight.userdev.internal.setup.util.* import io.papermc.paperweight.util.* import io.papermc.paperweight.util.constants.* import java.nio.file.Path import kotlin.io.path.* +import org.gradle.api.Project import org.gradle.api.artifacts.DependencySet -import org.gradle.api.artifacts.repositories.IvyArtifactRepository +import org.gradle.kotlin.dsl.* class SetupHandlerImplV2( private val parameters: UserdevSetup.Parameters, @@ -61,7 +63,7 @@ class SetupHandlerImplV2( private fun minecraftLibraryJars(): List = minecraftLibraryJars.listDirectoryEntries("*.jar") - private fun generateSources(context: SetupHandler.Context) { + private fun generateSources(context: SetupHandler.ExecutionContext) { vanillaSteps.downloadVanillaServerJar() val downloadMcLibs = object : SetupStep { @@ -69,7 +71,7 @@ class SetupHandlerImplV2( override val hashFile: Path = cache.resolve(paperSetupOutput("minecraftLibraries", "hashes")) - override fun run(context: SetupHandler.Context) { + override fun run(context: SetupHandler.ExecutionContext) { downloadLibraries( download = parameters.downloadService, workerExecutor = context.workerExecutor, @@ -166,7 +168,7 @@ class SetupHandlerImplV2( // PaperweightUserExtension, possibly by a task running in a separate // thread to dependency resolution. @Synchronized - private fun applyMojangMappedPaperclipPatch(context: SetupHandler.Context) { + private fun applyMojangMappedPaperclipPatch(context: SetupHandler.ExecutionContext) { if (setupCompleted) { return } @@ -187,59 +189,48 @@ class SetupHandlerImplV2( private val filteredMojangMappedPaperJar: Path = cache.resolve(paperSetupOutput("filteredMojangMappedPaperJar", "jar")) + override fun populateCompileConfiguration(context: SetupHandler.ConfigurationContext, dependencySet: DependencySet) { + dependencySet.add(context.dependencyFactory.create(context.layout.files(context.setupTask.flatMap { it.mappedServerJar }))) + listOfNotNull( + bundle.config.apiCoordinates, + bundle.config.mojangApiCoordinates + ).forEach { coordinate -> + dependencySet.add(context.dependencyFactory.create(coordinate)) + } + for (coordinates in bundle.config.buildData.libraryDependencies) { + dependencySet.add(context.dependencyFactory.create(coordinates)) + } + } + + override fun populateRuntimeConfiguration(context: SetupHandler.ConfigurationContext, dependencySet: DependencySet) { + dependencySet.add(context.dependencyFactory.create(context.layout.files(context.setupTask.flatMap { it.legacyPaperclipResult }))) + } + private var setupCompleted = false @Synchronized - override fun createOrUpdateIvyRepository(context: SetupHandler.Context) { + override fun combinedOrClassesJar(context: SetupHandler.ExecutionContext): Path { if (setupCompleted) { - return + return filteredMojangMappedPaperJar } lockSetup(cache) { - createOrUpdateIvyRepositoryDirect(context) + generateSources(context) } - } - - private fun createOrUpdateIvyRepositoryDirect(context: SetupHandler.Context) { - generateSources(context) - - val deps = bundle.config.buildData.libraryDependencies.toList() + - bundle.config.apiCoordinates + - bundle.config.mojangApiCoordinates - installPaperServer( - cache, - bundle.config.mappedServerCoordinates, - deps, - filteredMojangMappedPaperJar, - patchedSourcesJar, - minecraftVersion, - ) setupCompleted = true - } - - override fun configureIvyRepo(repo: IvyArtifactRepository) { - repo.content { - includeFromDependencyNotation(bundle.config.mappedServerCoordinates) - } - } - override fun populateCompileConfiguration(context: SetupHandler.Context, dependencySet: DependencySet) { - dependencySet.add(context.project.dependencies.create(bundle.config.mappedServerCoordinates)) + return filteredMojangMappedPaperJar } - override fun populateRuntimeConfiguration(context: SetupHandler.Context, dependencySet: DependencySet) { - dependencySet.add(context.project.dependencies.create(context.project.files(serverJar(context)))) - } - - override fun serverJar(context: SetupHandler.Context): Path { - applyMojangMappedPaperclipPatch(context) - return mojangMappedPaperJar + override fun afterEvaluate(project: Project) { + super.afterEvaluate(project) + project.tasks.withType(UserdevSetupTask::class).configureEach { + mappedServerJar.set(filteredMojangMappedPaperJar) + legacyPaperclipResult.set(mojangMappedPaperJar) + } } - override val serverJar: Path - get() = mojangMappedPaperJar - override val reobfMappings: Path get() = bundle.dir.resolve(bundle.config.buildData.reobfMappingsFile) diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v5/SetupHandlerImplV5.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v5/SetupHandlerImplV5.kt index 66c5bc472..5b664a06d 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v5/SetupHandlerImplV5.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/v5/SetupHandlerImplV5.kt @@ -22,19 +22,18 @@ package io.papermc.paperweight.userdev.internal.setup.v5 -import io.papermc.paperweight.tasks.* import io.papermc.paperweight.userdev.internal.setup.ExtractedBundle import io.papermc.paperweight.userdev.internal.setup.RunPaperclip import io.papermc.paperweight.userdev.internal.setup.SetupHandler import io.papermc.paperweight.userdev.internal.setup.UserdevSetup +import io.papermc.paperweight.userdev.internal.setup.UserdevSetupTask import io.papermc.paperweight.userdev.internal.setup.step.* import io.papermc.paperweight.userdev.internal.setup.util.* import io.papermc.paperweight.util.* import io.papermc.paperweight.util.constants.* import java.nio.file.Path +import org.gradle.api.Project import org.gradle.api.artifacts.DependencySet -import org.gradle.api.artifacts.ExternalModuleDependency -import org.gradle.api.artifacts.repositories.IvyArtifactRepository import org.gradle.kotlin.dsl.* class SetupHandlerImplV5( @@ -63,8 +62,9 @@ class SetupHandlerImplV5( private fun minecraftLibraryJars(): List = minecraftLibraryJars.filesMatchingRecursive("*.jar") - private fun generateSources(context: SetupHandler.Context) { + private fun generateSources(context: SetupHandler.ExecutionContext) { vanillaSteps.downloadVanillaServerJar() + applyMojangMappedPaperclipPatch(context) val extractStep = createExtractFromBundlerStep() @@ -108,7 +108,8 @@ class SetupHandlerImplV5( val applyDevBundlePatchesStep = ApplyDevBundlePatches( decompiledMinecraftServerJar, bundle.dir.resolve(bundle.config.patchDir), - patchedSourcesJar + patchedSourcesJar, + mojangMappedPaperJar ) StepExecutor.executeSteps( @@ -129,7 +130,7 @@ class SetupHandlerImplV5( // PaperweightUserExtension, possibly by a task running in a separate // thread to dependency resolution. @Synchronized - private fun applyMojangMappedPaperclipPatch(context: SetupHandler.Context) { + private fun applyMojangMappedPaperclipPatch(context: SetupHandler.ExecutionContext) { if (setupCompleted) { return } @@ -147,84 +148,77 @@ class SetupHandlerImplV5( } } - private var setupCompleted = false - - @Synchronized - override fun createOrUpdateIvyRepository(context: SetupHandler.Context) { - if (setupCompleted) { - return - } - - lockSetup(cache) { - createOrUpdateIvyRepositoryDirect(context) - } - } - - private fun createOrUpdateIvyRepositoryDirect(context: SetupHandler.Context) { - val source = if (parameters.genSources.get()) { - generateSources(context) - patchedSourcesJar - } else { - vanillaSteps.downloadVanillaServerJar() - StepExecutor.executeStep(context, createExtractFromBundlerStep()) - null + override fun populateCompileConfiguration(context: SetupHandler.ConfigurationContext, dependencySet: DependencySet) { + dependencySet.add(context.dependencyFactory.create(context.layout.files(context.setupTask.flatMap { it.mappedServerJar }))) + listOfNotNull( + bundle.config.apiCoordinates, + bundle.config.mojangApiCoordinates + ).forEach { coordinate -> + dependencySet.add(context.dependencyFactory.create(coordinate)) } - - applyMojangMappedPaperclipPatch(context) - - val deps = mutableListOf() - deps.addAll(bundle.config.buildData.compileDependencies) - deps.add(bundle.config.apiCoordinates) - bundle.config.mojangApiCoordinates?.let { deps.add(it) } - installPaperServer( - cache, - bundle.config.mappedServerCoordinates, - deps, - mojangMappedPaperJar, - source, - minecraftVersion, - ) - - setupCompleted = true - } - - override fun configureIvyRepo(repo: IvyArtifactRepository) { - repo.content { - includeFromDependencyNotation(bundle.config.mappedServerCoordinates) + for (coordinates in bundle.config.buildData.compileDependencies) { + dependencySet.add(context.dependencyFactory.create(coordinates)) } } - override fun populateCompileConfiguration(context: SetupHandler.Context, dependencySet: DependencySet) { - dependencySet.add(context.project.dependencies.create(bundle.config.mappedServerCoordinates)) - } - - override fun populateRuntimeConfiguration(context: SetupHandler.Context, dependencySet: DependencySet) { + override fun populateRuntimeConfiguration(context: SetupHandler.ConfigurationContext, dependencySet: DependencySet) { + dependencySet.add(context.dependencyFactory.create(context.layout.files(context.setupTask.flatMap { it.mappedServerJar }))) listOfNotNull( - bundle.config.mappedServerCoordinates, bundle.config.apiCoordinates, bundle.config.mojangApiCoordinates ).forEach { coordinate -> - val dep = context.project.dependencies.create(coordinate).also { - (it as ExternalModuleDependency).isTransitive = false + val dep = context.dependencyFactory.create(coordinate).also { + it.isTransitive = false } dependencySet.add(dep) } - for (coordinates in bundle.config.buildData.runtimeDependencies) { - val dep = context.project.dependencies.create(coordinates).also { - (it as ExternalModuleDependency).isTransitive = false + val dep = context.dependencyFactory.create(coordinates).also { + it.isTransitive = false } dependencySet.add(dep) } } - override fun serverJar(context: SetupHandler.Context): Path { - applyMojangMappedPaperclipPatch(context) - return mojangMappedPaperJar + private var setupCompleted = false + + @Synchronized + override fun combinedOrClassesJar(context: SetupHandler.ExecutionContext): Path { + if (setupCompleted) { + return if (parameters.genSources.get()) { + patchedSourcesJar + } else { + mojangMappedPaperJar + } + } + + val ret = lockSetup(cache) { + if (parameters.genSources.get()) { + generateSources(context) + patchedSourcesJar + } else { + vanillaSteps.downloadVanillaServerJar() + StepExecutor.executeStep(context, createExtractFromBundlerStep()) + applyMojangMappedPaperclipPatch(context) + mojangMappedPaperJar + } + } + + setupCompleted = true + + return ret } - override val serverJar: Path - get() = mojangMappedPaperJar + override fun afterEvaluate(project: Project) { + super.afterEvaluate(project) + project.tasks.withType(UserdevSetupTask::class).configureEach { + if (parameters.genSources.get()) { + mappedServerJar.set(patchedSourcesJar) + } else { + mappedServerJar.set(mojangMappedPaperJar) + } + } + } override val reobfMappings: Path get() = bundle.dir.resolve(bundle.config.buildData.reobfMappingsFile) @@ -257,33 +251,4 @@ class SetupHandlerImplV5( minecraftLibraryJars, ::minecraftLibraryJars ) - - private class ExtractFromBundlerStep( - cache: Path, - private val vanillaSteps: VanillaSteps, - private val vanillaServerJar: Path, - private val minecraftLibraryJars: Path, - private val listMinecraftLibraryJars: () -> List, - ) : SetupStep { - override val name: String = "extract libraries and server from downloaded jar" - - override val hashFile: Path = cache.resolve(paperSetupOutput("extractFromServerBundler", "hashes")) - - override fun run(context: SetupHandler.Context) { - ServerBundler.extractFromBundler( - vanillaSteps.mojangJar, - vanillaServerJar, - minecraftLibraryJars, - null, - null, - null, - null, - ) - } - - override fun touchHashFunctionBuilder(builder: HashFunctionBuilder) { - builder.include(vanillaSteps.mojangJar, vanillaServerJar) - builder.include(listMinecraftLibraryJars()) - } - } } From 6ceb7e8f96aa802dd4ed122782b5ea210eedf3bd Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Mon, 9 Dec 2024 12:48:02 -0700 Subject: [PATCH 28/38] Fix rebuildPatches and work on config caching compat --- .../paperweight/core/PaperweightCore.kt | 2 +- .../taskcontainers/DevBundleTasks.kt | 4 +-- .../paperweight/tasks/GenerateDevBundle.kt | 14 ++++---- .../tasks/softspoon/RebuildFilePatches.kt | 36 ++++++++++--------- .../kotlin/io/papermc/paperweight/util/git.kt | 35 ++++++++++++++++-- 5 files changed, 62 insertions(+), 29 deletions(-) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt index 73d9df019..312daf1a0 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/PaperweightCore.kt @@ -45,7 +45,7 @@ class PaperweightCore : Plugin { } override fun apply(target: Project) { - Git.checkForGit() + Git.checkForGit(target.providers) printId("paperweight-core", target.gradle) val ext = target.extensions.create(PAPERWEIGHT_EXTENSION, PaperweightCoreExtension::class) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt index ff85a3d82..439d3932d 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/taskcontainers/DevBundleTasks.kt @@ -53,8 +53,6 @@ class DevBundleTasks( val generateDevelopmentBundle by tasks.registering { group = "paperweight" - macheConfig.set(project.configurations.named(MACHE_CONFIG)) - pluginRemapperConfig.set(project.configurations.named(REMAPPER_CONFIG)) devBundleFile.set(project.layout.buildDirectory.file("libs/paperweight-development-bundle-${project.version}.zip")) ignoreUnsupportedEnvironment.set(project.providers.gradleProperty(GenerateDevBundle.unsupportedEnvironmentPropName).map { it.toBoolean() }) @@ -104,6 +102,8 @@ class DevBundleTasks( generateDevelopmentBundle { pluginRemapperUrl.set(project.repositories.named(REMAPPER_REPO_NAME).map { it.url.toString() }) macheUrl.set(project.repositories.named(MACHE_REPO_NAME).map { it.url.toString() }) + macheDep.set(determineArtifactCoordinates(project.configurations.getByName(MACHE_CONFIG)).single()) + pluginRemapperDep.set(determineArtifactCoordinates(project.configurations.getByName(REMAPPER_CONFIG))) } } } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateDevBundle.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateDevBundle.kt index 15aaf1b2e..e629886c2 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateDevBundle.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/GenerateDevBundle.kt @@ -34,13 +34,11 @@ import java.util.regex.Pattern import javax.inject.Inject import kotlin.io.path.* import org.gradle.api.DefaultTask -import org.gradle.api.artifacts.Configuration import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.ProjectLayout import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.ListProperty import org.gradle.api.provider.Property -import org.gradle.api.tasks.Classpath import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.InputFile @@ -71,14 +69,14 @@ abstract class GenerateDevBundle : DefaultTask() { @get:Input abstract val pluginRemapperUrl: Property - @get:Classpath - abstract val pluginRemapperConfig: Property + @get:Input + abstract val pluginRemapperDep: ListProperty @get:Input abstract val macheUrl: Property - @get:Classpath - abstract val macheConfig: Property + @get:Input + abstract val macheDep: Property @get:InputFile abstract val reobfMappingsFile: RegularFileProperty @@ -234,10 +232,10 @@ abstract class GenerateDevBundle : DefaultTask() { } private fun createRemapDep(): MavenDep = - determineMavenDep(pluginRemapperUrl, pluginRemapperConfig) + pluginRemapperUrl.zip(pluginRemapperDep) { url, dep -> MavenDep(url, dep) }.get() private fun createMacheDep(): MavenDep = - determineMavenDep(macheUrl, macheConfig) + macheUrl.zip(macheDep) { url, dep -> MavenDep(url, listOf(dep)) }.get() data class DevBundleConfig( val minecraftVersion: String, diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt index 39b77a753..b440a1f44 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt @@ -104,24 +104,28 @@ abstract class RebuildFilePatches : JavaLauncherTask() { git("stash", "push").executeSilently(silenceErr = true) git("checkout", "file").executeSilently(silenceErr = true) - val queue = worker.processIsolation { - forkOptions { - maxHeapSize = "2G" - executable(launcher.get().executablePath.path.absolutePathString()) - classpath.from(restamp) + val filesWithNewAts = if (!restamp.isEmpty) { + val queue = worker.processIsolation { + forkOptions { + maxHeapSize = "2G" + executable(launcher.get().executablePath.path.absolutePathString()) + classpath.from(restamp) + } } + val filesWithNewAtsPath = temporaryDir.toPath().resolve("filesWithNewAts.txt") + queue.submit(RebuildFilePatchesRestampWorker::class) { + this.baseDir.set(baseDir) + this.inputDir.set(inputDir) + this.atFile.set(this@RebuildFilePatches.atFile.orNull) + this.atFileOut.set(this@RebuildFilePatches.atFileOut.orNull) + this.minecraftClasspath.from(this@RebuildFilePatches.minecraftClasspath) + this.filesWithNewAts.set(filesWithNewAtsPath) + } + queue.await() + filesWithNewAtsPath.readLines() + } else { + emptyList() } - val filesWithNewAtsPath = temporaryDir.toPath().resolve("filesWithNewAts.txt") - queue.submit(RebuildFilePatchesRestampWorker::class) { - this.baseDir.set(baseDir) - this.inputDir.set(inputDir) - this.atFile.set(this@RebuildFilePatches.atFile.orNull) - this.atFileOut.set(this@RebuildFilePatches.atFileOut.orNull) - this.minecraftClasspath.from(this@RebuildFilePatches.minecraftClasspath) - this.filesWithNewAts.set(filesWithNewAtsPath) - } - queue.await() - val filesWithNewAts = filesWithNewAtsPath.readLines() if (filesWithNewAts.isNotEmpty()) { git("status").executeOut() diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/git.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/git.kt index 4d276271a..0686bcf84 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/git.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/git.kt @@ -46,8 +46,26 @@ class Git(private val repo: Path, private val env: Map = emptyMa fun withEnv(env: Map): Git = Git(repo, env) + private fun cmd(args: Array) = + arrayOf("git", "-c", "commit.gpgsign=false", "-c", "core.safecrlf=false", *args) + + fun exec(providers: ProviderFactory, vararg args: String): Provider { + val cmd = cmd(args) + val exec = providers.exec { + workingDir = repo.toFile() + commandLine = cmd.toMutableList() + environment.putAll(env) + } + return exec.standardOutput.asText.zip(exec.result) { output, result -> + if (result.exitValue != 0) { + throw PaperweightException("Failed to execute command: '${cmd.joinToString(separator = " ")}'; Exit code ${result.exitValue}") + } + return@zip output + } + } + operator fun invoke(vararg args: String): Command { - val cmd = arrayOf("git", "-c", "commit.gpgsign=false", "-c", "core.safecrlf=false", *args) + val cmd = cmd(args) return try { val builder = ProcessBuilder(*cmd).directory(repo) builder.environment().putAll(env) @@ -91,6 +109,15 @@ class Git(private val repo: Path, private val env: Map = emptyMa } } + fun checkForGit(providers: ProviderFactory) { + val result = providers.exec { + commandLine("git", "--version") + }.result.get() + if (result.exitValue != 0) { + missingGit() + } + } + fun checkForGit() { try { val proc = ProcessBuilder("git", "--version").redirectErrorStream(true).start() @@ -98,8 +125,12 @@ class Git(private val repo: Path, private val env: Map = emptyMa if (proc.waitFor() == 0) { return } - } catch (_: Exception) {} + } catch (_: Exception) { + } + missingGit() + } + private fun missingGit(): Nothing { throw PaperweightException("You must have git installed and available on your PATH in order to use paperweight.") } From e556389a62ab68499399d341df96712f9dd474af Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Mon, 9 Dec 2024 13:58:03 -0700 Subject: [PATCH 29/38] Override snappy temp dir --- .../io/papermc/paperweight/tasks/mache/SetupVanilla.kt | 2 ++ .../io/papermc/paperweight/tasks/softspoon/ApplySourceAT.kt | 2 ++ .../paperweight/tasks/softspoon/RebuildFilePatches.kt | 2 ++ .../kotlin/io/papermc/paperweight/restamp/restamp-utils.kt | 6 ++++++ 4 files changed, 12 insertions(+) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt index dfd5be141..713760f48 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt @@ -26,6 +26,7 @@ import codechicken.diffpatch.cli.PatchOperation import codechicken.diffpatch.util.LoggingOutputStream import codechicken.diffpatch.util.archiver.ArchiveFormat import io.papermc.paperweight.restamp.SetupVanillaRestampWorker +import io.papermc.paperweight.restamp.setSnappyTempDir import io.papermc.paperweight.tasks.* import io.papermc.paperweight.util.* import java.nio.file.Path @@ -186,6 +187,7 @@ abstract class SetupVanilla : JavaLauncherTask() { maxHeapSize = "2G" executable(launcher.get().executablePath.path.absolutePathString()) classpath.from(restamp) + setSnappyTempDir(temporaryDir) } } queue.submit(SetupVanillaRestampWorker::class) { diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceAT.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceAT.kt index 8b9086d2b..28c662395 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceAT.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplySourceAT.kt @@ -23,6 +23,7 @@ package io.papermc.paperweight.tasks.softspoon import io.papermc.paperweight.restamp.ApplySourceATWorker +import io.papermc.paperweight.restamp.setSnappyTempDir import io.papermc.paperweight.tasks.* import io.papermc.paperweight.util.* import javax.inject.Inject @@ -65,6 +66,7 @@ abstract class ApplySourceAT : JavaLauncherTask() { forkOptions { maxHeapSize = "2G" executable(launcher.get().executablePath.path.absolutePathString()) + setSnappyTempDir(temporaryDir) } } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt index b440a1f44..4ebb0d606 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt @@ -26,6 +26,7 @@ import codechicken.diffpatch.cli.DiffOperation import codechicken.diffpatch.util.LogLevel import codechicken.diffpatch.util.LoggingOutputStream import io.papermc.paperweight.restamp.RebuildFilePatchesRestampWorker +import io.papermc.paperweight.restamp.setSnappyTempDir import io.papermc.paperweight.tasks.* import io.papermc.paperweight.util.* import java.io.PrintStream @@ -110,6 +111,7 @@ abstract class RebuildFilePatches : JavaLauncherTask() { maxHeapSize = "2G" executable(launcher.get().executablePath.path.absolutePathString()) classpath.from(restamp) + setSnappyTempDir(temporaryDir) } } val filesWithNewAtsPath = temporaryDir.toPath().resolve("filesWithNewAts.txt") diff --git a/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/restamp-utils.kt b/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/restamp-utils.kt index 191a783bb..fb2e427ab 100644 --- a/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/restamp-utils.kt +++ b/paperweight-lib/src/restamp/kotlin/io/papermc/paperweight/restamp/restamp-utils.kt @@ -23,6 +23,7 @@ package io.papermc.paperweight.restamp import java.io.BufferedWriter +import java.io.File import java.io.StringWriter import java.nio.file.Path import kotlin.io.path.* @@ -31,6 +32,11 @@ import org.cadixdev.at.AccessTransform import org.cadixdev.at.AccessTransformSet import org.cadixdev.at.ModifierChange import org.cadixdev.at.io.AccessTransformFormat +import org.gradle.process.JavaForkOptions + +fun JavaForkOptions.setSnappyTempDir(dir: File) { + systemProperties["org.xerial.snappy.tempdir"] = dir.absolutePath +} fun atFromString(input: String): AccessTransform { var last = input.length - 1 From cc0127abf8d19b345c45089da965b1a28f97cbe9 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Mon, 9 Dec 2024 22:37:17 +0100 Subject: [PATCH 30/38] don't copy nbt files to resources --- .../core/taskcontainers/SoftSpoonTasks.kt | 2 +- .../paperweight/tasks/mache/SetupVanilla.kt | 16 ++++++---------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt index 5c8abd0c6..eb706495e 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt @@ -154,7 +154,7 @@ open class SoftSpoonTasks( description = "Setup vanilla resources dir" inputFile.set(allTasks.extractFromBundler.flatMap { it.serverJar }) - predicate.set { Files.isRegularFile(it) && !it.toString().endsWith(".class") } + predicate.set { Files.isRegularFile(it) && !it.toString().endsWith(".class") && !it.toString().endsWith(".nbt") } outputDir.set(layout.cache.resolve(BASE_PROJECT).resolve("resources")) } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt index 713760f48..842de61c8 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt @@ -134,17 +134,13 @@ abstract class SetupVanilla : JavaLauncherTask() { .forEach { val target = outputPath.resolve(it.toString().substring(1)) target.parent.createDirectories() - if (it.toString().endsWith(".nbt")) { - // nbt files are binary, so we can just copy them - it.copyTo(target) - } else { - // for text files we make sure we have a trailing newline - var content = it.readText() - if (!content.endsWith("\n")) { - content += "\n" - } - target.writeText(content) + + var content = it.readText() + // make sure we have a newline at the end of the file + if (!content.endsWith("\n")) { + content += "\n" } + target.writeText(content) } println("Setup git repo...") From 7014cccf2ec1d090efb6a951a34d73403e93240a Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Mon, 9 Dec 2024 22:45:50 +0100 Subject: [PATCH 31/38] Revert "don't copy nbt files to resources" This reverts commit cc0127abf8d19b345c45089da965b1a28f97cbe9. --- .../core/taskcontainers/SoftSpoonTasks.kt | 2 +- .../paperweight/tasks/mache/SetupVanilla.kt | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt index eb706495e..5c8abd0c6 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt @@ -154,7 +154,7 @@ open class SoftSpoonTasks( description = "Setup vanilla resources dir" inputFile.set(allTasks.extractFromBundler.flatMap { it.serverJar }) - predicate.set { Files.isRegularFile(it) && !it.toString().endsWith(".class") && !it.toString().endsWith(".nbt") } + predicate.set { Files.isRegularFile(it) && !it.toString().endsWith(".class") } outputDir.set(layout.cache.resolve(BASE_PROJECT).resolve("resources")) } diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt index 842de61c8..713760f48 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/mache/SetupVanilla.kt @@ -134,13 +134,17 @@ abstract class SetupVanilla : JavaLauncherTask() { .forEach { val target = outputPath.resolve(it.toString().substring(1)) target.parent.createDirectories() - - var content = it.readText() - // make sure we have a newline at the end of the file - if (!content.endsWith("\n")) { - content += "\n" + if (it.toString().endsWith(".nbt")) { + // nbt files are binary, so we can just copy them + it.copyTo(target) + } else { + // for text files we make sure we have a trailing newline + var content = it.readText() + if (!content.endsWith("\n")) { + content += "\n" + } + target.writeText(content) } - target.writeText(content) } println("Setup git repo...") From 8ff2d5c589cdd0d41b91db943c09d7b8b1181d32 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Mon, 9 Dec 2024 22:51:53 +0100 Subject: [PATCH 32/38] use the right ignorePrefix to ignore the nbt files --- .../papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt index 4ebb0d606..ffece58fb 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/RebuildFilePatches.kt @@ -214,7 +214,7 @@ abstract class RebuildFilePatches : JavaLauncherTask() { .level(if (verbose.get()) LogLevel.ALL else LogLevel.INFO) .lineEnding("\n") .ignorePrefix(".git") - .ignorePrefix("data/minecraft/structures") + .ignorePrefix("data/minecraft/structure") .ignorePrefix("data/.mc") .ignorePrefix("assets/.mc") .context(contextLines.get()) From 89c113a29b284ba664651a738a6e92adfbaa17ae Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Mon, 9 Dec 2024 15:13:14 -0700 Subject: [PATCH 33/38] Update testing mache --- .../src/test/resources/functional_test/test-server/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/paperweight-core/src/test/resources/functional_test/test-server/build.gradle b/paperweight-core/src/test/resources/functional_test/test-server/build.gradle index 43965f04c..f0f7eb8a6 100644 --- a/paperweight-core/src/test/resources/functional_test/test-server/build.gradle +++ b/paperweight-core/src/test/resources/functional_test/test-server/build.gradle @@ -23,7 +23,7 @@ dependencies { // this could be resolved by creating a fake maven repo that holds proper module metadata implementation 'com.github.oshi:oshi-core:6.6.5' } else { - mache 'io.papermc:mache:1.21.4+build.3' + mache 'io.papermc:mache:1.21.4+build.4' } } From 243ab68a06d3ae4f47d61dcdf70d8f3c373452ce Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Tue, 10 Dec 2024 21:51:11 -0700 Subject: [PATCH 34/38] Populate mache config at execution time when config cache is reused --- .../kotlin/io/papermc/paperweight/util/utils.kt | 4 +++- .../userdev/internal/setup/SetupHandlerImpl.kt | 15 +++++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt index 22774dd6a..deadd729f 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/util/utils.kt @@ -415,7 +415,9 @@ fun modifyManifest(path: Path, create: Boolean = true, op: Manifest.() -> Unit) val mainCapabilityAttribute: Attribute = Attribute.of("io.papermc.paperweight.main-capability", String::class.java) -fun ConfigurationContainer.resolveMacheMeta() = getByName(MACHE_CONFIG).singleFile.toPath().openZip().use { zip -> +fun ConfigurationContainer.resolveMacheMeta() = getByName(MACHE_CONFIG).resolveMacheMeta() + +fun FileCollection.resolveMacheMeta() = singleFile.toPath().openZip().use { zip -> gson.fromJson(zip.getPath("/mache.json").readText()) } diff --git a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandlerImpl.kt b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandlerImpl.kt index be3b13ee1..4f8ae9680 100644 --- a/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandlerImpl.kt +++ b/paperweight-userdev/src/main/kotlin/io/papermc/paperweight/userdev/internal/setup/SetupHandlerImpl.kt @@ -31,6 +31,7 @@ import io.papermc.paperweight.util.data.mache.* import java.nio.file.Path import org.gradle.api.Project import org.gradle.api.artifacts.DependencySet +import org.gradle.api.file.FileCollection import org.gradle.kotlin.dsl.* class SetupHandlerImpl( @@ -57,6 +58,7 @@ class SetupHandlerImpl( private fun minecraftLibraryJars(): List = minecraftLibraryJars.filesMatchingRecursive("*.jar") private fun generateSources(context: SetupHandler.ExecutionContext) { + setupMacheMeta(context.macheConfig) // If the config cache is reused then the mache config may not be populated vanillaSteps.downloadVanillaServerJar() vanillaSteps.downloadServerMappings() applyMojangMappedPaperclipPatch(context) @@ -161,14 +163,19 @@ class SetupHandlerImpl( private fun macheMeta(): MacheMeta = requireNotNull(macheMeta) { "Mache meta is not setup yet" } - override fun afterEvaluate(project: Project) { - super.afterEvaluate(project) - val configurations = project.configurations + private fun setupMacheMeta(macheFiles: FileCollection) { if (macheMeta == null) { synchronized(this) { - macheMeta = configurations.resolveMacheMeta() + macheMeta = macheFiles.resolveMacheMeta() } } + } + + override fun afterEvaluate(project: Project) { + super.afterEvaluate(project) + setupMacheMeta(project.configurations.getByName(MACHE_CONFIG)) + + val configurations = project.configurations val macheCodebook = configurations.register(MACHE_CODEBOOK_CONFIG) { isTransitive = false From a7f1809ab15ed9135ebaeeb4c5da995efc21f086 Mon Sep 17 00:00:00 2001 From: MiniDigger | Martin Date: Fri, 13 Dec 2024 17:26:26 +0100 Subject: [PATCH 35/38] allow having a not existing feature patches folder --- .../io/papermc/paperweight/tasks/CollectATsFromPatches.kt | 7 +++++++ .../paperweight/tasks/softspoon/ApplyFeaturePatches.kt | 2 ++ 2 files changed, 9 insertions(+) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CollectATsFromPatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CollectATsFromPatches.kt index 7f5ba37ff..a340ddd63 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CollectATsFromPatches.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CollectATsFromPatches.kt @@ -28,6 +28,7 @@ import kotlin.io.path.* import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.Property +import org.gradle.api.tasks.IgnoreEmptyDirectories import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.Optional @@ -43,6 +44,7 @@ abstract class CollectATsFromPatches : BaseTask() { @get:Input abstract val header: Property + @get:IgnoreEmptyDirectories @get:InputDirectory abstract val patchDir: DirectoryProperty @@ -60,6 +62,11 @@ abstract class CollectATsFromPatches : BaseTask() { @TaskAction fun run() { + if (patchDir.isPresent.not() && extraPatchDir.isPresent.not()) { + outputFile.path.writeText("") + return + } + outputFile.path.deleteForcefully() val patches = patchDir.path.listDirectoryEntries("*.patch") + (extraPatchDir.pathOrNull?.listDirectoryEntries("*.patch") ?: emptyList()) diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFeaturePatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFeaturePatches.kt index 5474e07e0..76da30f2e 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFeaturePatches.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFeaturePatches.kt @@ -32,6 +32,7 @@ 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.SkipWhenEmpty import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.UntrackedTask @@ -42,6 +43,7 @@ abstract class ApplyFeaturePatches : ControllableOutputTask() { @get:InputDirectory abstract val repo: DirectoryProperty + @get:SkipWhenEmpty @get:PathSensitive(PathSensitivity.NONE) @get:InputDirectory abstract val patches: DirectoryProperty From f5702e060363fd601f536ed866f42fd5d9a9093c Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Fri, 13 Dec 2024 13:38:40 -0700 Subject: [PATCH 36/38] Adjust CollectATsFromPatches optional inputs --- .../core/taskcontainers/SoftSpoonTasks.kt | 2 +- .../paperweight/tasks/CollectATsFromPatches.kt | 17 ++++++++--------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt index 5c8abd0c6..158ac9763 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt @@ -108,7 +108,7 @@ open class SoftSpoonTasks( val collectAccessTransform by tasks.registering(CollectATsFromPatches::class) { group = "mache" - patchDir.set(project.ext.paper.featurePatchDir) + patchDir.set(project.ext.paper.featurePatchDir.fileExists(project)) } val mergeCollectedAts by tasks.registering { diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CollectATsFromPatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CollectATsFromPatches.kt index a340ddd63..2bccdafd8 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CollectATsFromPatches.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/CollectATsFromPatches.kt @@ -28,7 +28,6 @@ import kotlin.io.path.* import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.Property -import org.gradle.api.tasks.IgnoreEmptyDirectories import org.gradle.api.tasks.Input import org.gradle.api.tasks.InputDirectory import org.gradle.api.tasks.Optional @@ -44,8 +43,8 @@ abstract class CollectATsFromPatches : BaseTask() { @get:Input abstract val header: Property - @get:IgnoreEmptyDirectories @get:InputDirectory + @get:Optional abstract val patchDir: DirectoryProperty @get:InputDirectory @@ -62,14 +61,14 @@ abstract class CollectATsFromPatches : BaseTask() { @TaskAction fun run() { - if (patchDir.isPresent.not() && extraPatchDir.isPresent.not()) { - outputFile.path.writeText("") - return - } - outputFile.path.deleteForcefully() - val patches = patchDir.path.listDirectoryEntries("*.patch") + - (extraPatchDir.pathOrNull?.listDirectoryEntries("*.patch") ?: emptyList()) + val patches = mutableListOf() + patchDir.orNull?.let { + patches += it.path.listDirectoryEntries("*.patch") + } + extraPatchDir.orNull?.let { + patches += it.path.listDirectoryEntries("*.patch") + } outputFile.path.writeLines(readAts(patches)) } From 9848675edb14d38558a529565c8813e9162b73a2 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Fri, 13 Dec 2024 13:46:21 -0700 Subject: [PATCH 37/38] Make patches optional for ApplyFilePatches --- .../paperweight/core/taskcontainers/SoftSpoonTasks.kt | 6 +++--- .../paperweight/tasks/softspoon/ApplyFilePatches.kt | 7 ++++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt index 158ac9763..7a361ce1d 100644 --- a/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt +++ b/paperweight-core/src/main/kotlin/io/papermc/paperweight/core/taskcontainers/SoftSpoonTasks.kt @@ -164,7 +164,7 @@ open class SoftSpoonTasks( input.set(setupMacheSources.flatMap { it.outputDir }) output.set(layout.projectDirectory.dir("src/vanilla/java")) - patches.set(project.ext.paper.sourcePatchDir) + patches.set(project.ext.paper.sourcePatchDir.fileExists(project)) rejects.set(project.ext.paper.rejectsDir) gitFilePatches.set(project.ext.gitFilePatches) } @@ -175,7 +175,7 @@ open class SoftSpoonTasks( input.set(setupMacheSources.flatMap { it.outputDir }) output.set(layout.projectDirectory.dir("src/vanilla/java")) - patches.set(project.ext.paper.sourcePatchDir) + patches.set(project.ext.paper.sourcePatchDir.fileExists(project)) rejects.set(project.ext.paper.rejectsDir) gitFilePatches.set(project.ext.gitFilePatches) } @@ -186,7 +186,7 @@ open class SoftSpoonTasks( input.set(setupMacheResources.flatMap { it.outputDir }) output.set(layout.projectDirectory.dir("src/vanilla/resources")) - patches.set(project.ext.paper.resourcePatchDir) + patches.set(project.ext.paper.resourcePatchDir.fileExists(project)) } val applyFilePatches by tasks.registering(Task::class) { diff --git a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatches.kt b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatches.kt index 0837044c9..9f7a00d8d 100644 --- a/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatches.kt +++ b/paperweight-lib/src/main/kotlin/io/papermc/paperweight/tasks/softspoon/ApplyFilePatches.kt @@ -59,6 +59,7 @@ abstract class ApplyFilePatches : BaseTask() { @get:PathSensitive(PathSensitivity.NONE) @get:InputDirectory + @get:Optional abstract val patches: DirectoryProperty @get:Optional @@ -87,7 +88,10 @@ abstract class ApplyFilePatches : BaseTask() { setupGitHook(outputPath) - val result = if (gitFilePatches.get()) { + val result = if (!patches.isPresent) { + commit() + 0 + } else if (gitFilePatches.get()) { applyWithGit(outputPath) } else { applyWithDiffPatch() @@ -155,6 +159,7 @@ abstract class ApplyFilePatches : BaseTask() { git.commit() .setMessage("File Patches") .setAuthor(ident) + .setAllowEmpty(true) .setSign(false) .call() git.tagDelete().setTags("file").call() From dce2d7e567f646ad60169f1e1d3de6e75e7a9619 Mon Sep 17 00:00:00 2001 From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Date: Fri, 13 Dec 2024 13:52:08 -0700 Subject: [PATCH 38/38] Disable patcher build for now --- settings.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.gradle.kts b/settings.gradle.kts index 7331fbc3f..ec558e591 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -4,6 +4,6 @@ plugins { rootProject.name = "paperweight" -include("paperweight-core", "paperweight-lib", "paperweight-patcher", "paperweight-userdev") +include("paperweight-core", "paperweight-lib", /*"paperweight-patcher",*/ "paperweight-userdev") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")