From 1cba44c9acd08f5312b43c04f33824fb5dfdb84f Mon Sep 17 00:00:00 2001 From: Ashley Wright Date: Mon, 23 Dec 2024 04:52:52 +0300 Subject: [PATCH] Add global & local caches, use symlinks where possible, use capabilities for stubs --- build.gradle.kts | 19 +---- .../accesswidener/AccessWiden.kt | 48 ++++++++--- .../core/MinecraftComponentMetadataRule.kt | 80 +++++++++++------- .../core/resolve/ServerExtractionState.kt | 4 +- .../core/resolve/VanillaSplittingState.kt | 28 ++----- .../core/task/CachedMinecraftTask.kt | 6 +- .../core/task/ResolveMinecraftMappings.kt | 12 ++- .../minecraftcodev/core/utils/Cache.kt | 84 ++++++++++++++++++- minecraft-codev-decompiler/build.gradle.kts | 2 +- .../runs/FabricRunsDefaultsContainer.kt | 7 +- ...aftForgeComponentClassifierMetadataRule.kt | 34 +++++++- .../MinecraftForgeComponentMetadataRule.kt | 26 +++--- .../McpConfigMappingResolutionRule.kt | 4 +- .../forge/task/ResolvePatchedMinecraft.kt | 20 +++-- .../intersection/JarIntersection.kt | 24 ++++-- .../minecraftcodev/remapper/JarRemapper.kt | 8 +- .../minecraftcodev/remapper/RemapAction.kt | 39 ++++++--- .../minecraftcodev/remapper/task/RemapTask.kt | 43 +++++++--- .../runs/MinecraftCodevRunsPlugin.kt | 5 +- 19 files changed, 334 insertions(+), 159 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7d9e377..59c8a23 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,7 +13,7 @@ subprojects { apply(plugin = "java") java { - toolchain.languageVersion.set(JavaLanguageVersion.of(11)) + toolchain.languageVersion.set(JavaLanguageVersion.of(8)) withSourcesJar() withJavadocJar() } @@ -54,23 +54,6 @@ childProjects.values.forEach { project -> } } - tasks.compileKotlin { - kotlinOptions { - jvmTarget = "11" - - freeCompilerArgs = - listOf( - "-opt-in=kotlin.ExperimentalStdlibApi", - "-opt-in=kotlinx.serialization.ExperimentalSerializationApi", - "-Xunrestricted-builder-inference", - "-Xjvm-default=all", - ) - - apiVersion = "1.6" - languageVersion = "1.6" - } - } - tasks.test { maxHeapSize = "3G" diff --git a/minecraft-codev-access-widener/src/main/kotlin/net/msrandom/minecraftcodev/accesswidener/AccessWiden.kt b/minecraft-codev-access-widener/src/main/kotlin/net/msrandom/minecraftcodev/accesswidener/AccessWiden.kt index 1a63713..91f1790 100644 --- a/minecraft-codev-access-widener/src/main/kotlin/net/msrandom/minecraftcodev/accesswidener/AccessWiden.kt +++ b/minecraft-codev-access-widener/src/main/kotlin/net/msrandom/minecraftcodev/accesswidener/AccessWiden.kt @@ -1,20 +1,25 @@ package net.msrandom.minecraftcodev.accesswidener -import net.msrandom.minecraftcodev.core.resolve.isCodevGeneratedMinecraftJar -import net.msrandom.minecraftcodev.core.utils.* +import net.msrandom.minecraftcodev.core.utils.cacheExpensiveOperation +import net.msrandom.minecraftcodev.core.utils.getAsPath +import net.msrandom.minecraftcodev.core.utils.getLocalCacheDirectoryProvider +import net.msrandom.minecraftcodev.core.utils.toPath +import net.msrandom.minecraftcodev.core.utils.tryLink +import net.msrandom.minecraftcodev.core.utils.walk +import net.msrandom.minecraftcodev.core.utils.zipFileSystem import org.gradle.api.DefaultTask -import org.gradle.api.artifacts.transform.* import org.gradle.api.file.ConfigurableFileCollection -import org.gradle.api.file.FileSystemLocation +import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty +import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.Property -import org.gradle.api.provider.Provider import org.gradle.api.tasks.* import org.objectweb.asm.ClassReader import org.objectweb.asm.ClassWriter import org.objectweb.asm.Opcodes import java.nio.file.Path import java.nio.file.StandardCopyOption +import javax.inject.Inject import kotlin.io.path.* @CacheableTask @@ -37,6 +42,12 @@ abstract class AccessWiden : DefaultTask() { abstract val outputFile: RegularFileProperty @OutputFile get + abstract val cacheDirectory: DirectoryProperty + @Internal get + + abstract val objectFactory: ObjectFactory + @Inject get + init { outputFile.convention( project.layout.file( @@ -45,18 +56,23 @@ abstract class AccessWiden : DefaultTask() { }, ), ) - } - @TaskAction - fun accessWiden() { - outputFile.getAsPath().deleteIfExists() + cacheDirectory.set(getLocalCacheDirectoryProvider(project)) + } + private fun accessWiden(outputPath: Path) { val input = inputFile.get().toPath() + if (accessWideners.isEmpty) { + outputPath.tryLink(input) + + return + } + val accessModifiers = loadAccessWideners(accessWideners, namespace.takeIf(Property<*>::isPresent)?.get()) zipFileSystem(input).use { inputZip -> - zipFileSystem(outputFile.getAsPath(), true).use { outputZip -> + zipFileSystem(outputPath, true).use { outputZip -> inputZip.getPath("/").walk { for (path in filter(Path::isRegularFile)) { val name = path.toString() @@ -86,4 +102,16 @@ abstract class AccessWiden : DefaultTask() { } } } + + @TaskAction + fun accessWiden() { + val cacheKey = objectFactory.fileCollection().apply { + from(accessWideners) + from(inputFile) + } + + cacheExpensiveOperation(cacheDirectory.getAsPath(), "access-widened", cacheKey, outputFile.getAsPath()) { + accessWiden(it) + } + } } diff --git a/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/MinecraftComponentMetadataRule.kt b/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/MinecraftComponentMetadataRule.kt index e1f4a6f..62f8a9d 100644 --- a/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/MinecraftComponentMetadataRule.kt +++ b/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/MinecraftComponentMetadataRule.kt @@ -2,14 +2,11 @@ package net.msrandom.minecraftcodev.core import net.msrandom.minecraftcodev.core.resolve.MinecraftVersionList import net.msrandom.minecraftcodev.core.resolve.getAllDependencies -import net.msrandom.minecraftcodev.core.resolve.getClientDependencies import net.msrandom.minecraftcodev.core.resolve.setupCommon import org.gradle.api.artifacts.CacheableRule import org.gradle.api.artifacts.ComponentMetadataContext import org.gradle.api.artifacts.ComponentMetadataRule -import org.gradle.api.attributes.Attribute -import org.gradle.api.attributes.Category -import org.gradle.api.model.ObjectFactory +import org.gradle.api.artifacts.Dependency import java.io.File import java.nio.file.Path import javax.inject.Inject @@ -26,41 +23,66 @@ fun getVersionList( @CacheableRule abstract class MinecraftComponentMetadataRule @Inject constructor( private val cacheDirectory: File, - private val version: String, + private val versions: List, private val versionManifestUrl: String, private val isOffline: Boolean, - private val client: Boolean, - private val attribute: Attribute, - private val commonAttributeValue: String, - private val clientAttributeValue: String, + private val commonCapability: String, + private val clientCapability: String, ) : ComponentMetadataRule { - abstract val objectFactory: ObjectFactory - @Inject get - - override fun execute(context: ComponentMetadataContext) { - val variantName = if (client) { - clientAttributeValue - } else { - commonAttributeValue - } + private fun ComponentMetadataContext.addVariantDependencies(capabilityName: String, client: Boolean) { + details.addVariant(capabilityName, Dependency.DEFAULT_CONFIGURATION) { variant -> + variant.withCapabilities { + for (capability in it.capabilities) { + it.removeCapability(capability.group, capability.name) + } - context.details.addVariant(variantName) { - it.attributes { attributes -> - attributes - .attribute(Category.CATEGORY_ATTRIBUTE, objectFactory.named(Category::class.java, Category.REGULAR_PLATFORM)) - .attribute(attribute, variantName) + it.addCapability("net.msrandom", capabilityName, "0.0.0") } - it.withDependencies { dependencies -> - val versionMetadata = getVersionList(cacheDirectory.toPath(), versionManifestUrl, isOffline).version(version) + variant.withDependencies { dependencies -> + val versionList = getVersionList(cacheDirectory.toPath(), versionManifestUrl, isOffline) + + val versionDependencies = versions.map { + val versionMetadata = versionList.version(versions[0]) - if (client) { - getAllDependencies(versionMetadata).forEach(dependencies::add) - } else { - setupCommon(cacheDirectory.toPath(), versionMetadata, isOffline).forEach(dependencies::add) + val dependencies = if (client) { + getAllDependencies(versionMetadata) + } else { + setupCommon(cacheDirectory.toPath(), versionMetadata, isOffline) + } + + dependencies.map(ModuleLibraryIdentifier::load) + } + + val commonDependencies = versionDependencies.reduce { a, b -> + val moduleVersionsA = a.associate { + (it.group to it.module) to it.version + } + + val moduleVersionsB = b.associate { + (it.group to it.module) to it.version + } + + val commonModules = moduleVersionsA.keys intersect moduleVersionsB.keys + + commonModules.map { module -> + val (group, name) = module + val version = minOf(moduleVersionsA.getValue(module), moduleVersionsB.getValue(module)) + + ModuleLibraryIdentifier(group, name, version, null) + } + } + + for (dependency in commonDependencies) { + dependencies.add(dependency.toString()) } } } } + + override fun execute(context: ComponentMetadataContext) { + context.addVariantDependencies(commonCapability, false) + context.addVariantDependencies(clientCapability, true) + } } diff --git a/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/resolve/ServerExtractionState.kt b/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/resolve/ServerExtractionState.kt index 2de58ef..d14c851 100644 --- a/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/resolve/ServerExtractionState.kt +++ b/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/resolve/ServerExtractionState.kt @@ -1,7 +1,5 @@ package net.msrandom.minecraftcodev.core.resolve -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext import net.msrandom.minecraftcodev.core.resolve.bundled.ServerExtractor import net.msrandom.minecraftcodev.core.resolve.legacy.ServerFixer import net.msrandom.minecraftcodev.core.utils.zipFileSystem @@ -89,6 +87,8 @@ fun getExtractionState( Files.createFile(bundledMark) } + addMinecraftMarker(extractedJar) + return ServerExtractionResult(extractedJar, isBundled, commonLibraries) } diff --git a/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/resolve/VanillaSplittingState.kt b/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/resolve/VanillaSplittingState.kt index b07c67b..3dbab9e 100644 --- a/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/resolve/VanillaSplittingState.kt +++ b/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/resolve/VanillaSplittingState.kt @@ -3,14 +3,9 @@ package net.msrandom.minecraftcodev.core.resolve import net.msrandom.minecraftcodev.core.resolve.MinecraftVersionMetadata.Rule.OperatingSystem import net.msrandom.minecraftcodev.core.resolve.bundled.BundledClientJarSplitter import net.msrandom.minecraftcodev.core.resolve.legacy.LegacyJarSplitter -import net.msrandom.minecraftcodev.core.utils.clientJarPath -import net.msrandom.minecraftcodev.core.utils.commonJarPath -import net.msrandom.minecraftcodev.core.utils.osName -import net.msrandom.minecraftcodev.core.utils.osVersion +import net.msrandom.minecraftcodev.core.utils.* import org.apache.commons.lang3.SystemUtils import java.nio.file.Path -import java.nio.file.StandardCopyOption -import kotlin.io.path.copyTo import kotlin.io.path.deleteIfExists import kotlin.io.path.exists import kotlin.io.path.notExists @@ -26,10 +21,7 @@ internal fun setupCommon( val (extractedServer, isBundled, libraries) = getExtractionState(cacheDirectory, metadata, isOffline)!! return if (isBundled) { - if (output != null) { - extractedServer.copyTo(output, StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.COPY_ATTRIBUTES) - addMinecraftMarker(output) - } + output?.tryLink(extractedServer) libraries } else { @@ -39,10 +31,7 @@ internal fun setupCommon( LegacyJarSplitter.split(cacheDirectory, metadata, extractedServer, isOffline) } - if (output != null) { - commonJarPath.copyTo(output) - addMinecraftMarker(output) - } + output?.tryLink(commonJarPath) libraries + "net.msrandom:side-annotations:1.0.0" } @@ -59,7 +48,7 @@ internal fun setupClient( val clientJarPath = clientJarPath(cacheDirectory, metadata.id) if (clientJarPath.exists()) { - clientJarPath.copyTo(output) + output.tryLink(clientJarPath) return } @@ -73,15 +62,12 @@ internal fun setupClient( if (isBundled) { BundledClientJarSplitter.split(cacheDirectory, metadata, extractedServer, isOffline) - - clientJarPath.copyTo(output) - addMinecraftMarker(output) } else { LegacyJarSplitter.split(cacheDirectory, metadata, extractedServer, isOffline).client - - clientJarPath.copyTo(output) - addMinecraftMarker(output) } + + addMinecraftMarker(clientJarPath) + output.tryLink(clientJarPath) } fun getAllDependencies(metadata: MinecraftVersionMetadata) = diff --git a/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/task/CachedMinecraftTask.kt b/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/task/CachedMinecraftTask.kt index 441d89f..efa7f9e 100644 --- a/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/task/CachedMinecraftTask.kt +++ b/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/task/CachedMinecraftTask.kt @@ -3,7 +3,7 @@ package net.msrandom.minecraftcodev.core.task import net.msrandom.minecraftcodev.core.VERSION_MANIFEST_URL import net.msrandom.minecraftcodev.core.getVersionList import net.msrandom.minecraftcodev.core.utils.getAsPath -import net.msrandom.minecraftcodev.core.utils.getCacheDirectoryProvider +import net.msrandom.minecraftcodev.core.utils.getGlobalCacheDirectoryProvider import org.gradle.api.DefaultTask import org.gradle.api.Project import org.gradle.api.file.DirectoryProperty @@ -32,8 +32,8 @@ abstract class CachedMinecraftParameters { fun convention(project: Project) { versionManifestUrl.convention(VERSION_MANIFEST_URL) - directory.convention(getCacheDirectoryProvider(project)) - isOffline.convention(project.provider { project.gradle.startParameter.isOffline }) + directory.set(getGlobalCacheDirectoryProvider(project)) + isOffline.set(project.provider { project.gradle.startParameter.isOffline }) } fun versionList() = getVersionList(directory.getAsPath(), versionManifestUrl.get(), isOffline.get()) diff --git a/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/task/ResolveMinecraftMappings.kt b/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/task/ResolveMinecraftMappings.kt index d93a78d..334bc02 100644 --- a/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/task/ResolveMinecraftMappings.kt +++ b/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/task/ResolveMinecraftMappings.kt @@ -3,11 +3,14 @@ package net.msrandom.minecraftcodev.core.task import net.msrandom.minecraftcodev.core.resolve.MinecraftDownloadVariant import net.msrandom.minecraftcodev.core.resolve.downloadMinecraftFile import net.msrandom.minecraftcodev.core.utils.getAsPath +import net.msrandom.minecraftcodev.core.utils.tryLink import org.gradle.api.file.RegularFileProperty import org.gradle.api.provider.Property -import org.gradle.api.tasks.* -import java.nio.file.StandardCopyOption -import kotlin.io.path.copyTo +import org.gradle.api.tasks.CacheableTask +import org.gradle.api.tasks.Input +import org.gradle.api.tasks.OutputFile +import org.gradle.api.tasks.TaskAction +import kotlin.io.path.deleteIfExists @CacheableTask abstract class ResolveMinecraftMappings : CachedMinecraftTask() { @@ -44,6 +47,7 @@ abstract class ResolveMinecraftMappings : CachedMinecraftTask() { val downloadPath = downloadMinecraftFile(cacheParameters.directory.getAsPath(), version, variant, cacheParameters.isOffline.get()) ?: throw IllegalArgumentException("${version.id} does not have variant $variant") - downloadPath.copyTo(output, StandardCopyOption.REPLACE_EXISTING) + output.deleteIfExists() + output.tryLink(downloadPath) } } diff --git a/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/utils/Cache.kt b/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/utils/Cache.kt index df5fb47..af6cf1c 100644 --- a/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/utils/Cache.kt +++ b/minecraft-codev-core/src/main/kotlin/net/msrandom/minecraftcodev/core/utils/Cache.kt @@ -1,18 +1,29 @@ package net.msrandom.minecraftcodev.core.utils +import com.google.common.hash.HashCode +import kotlinx.coroutines.async +import kotlinx.coroutines.awaitAll +import kotlinx.coroutines.runBlocking import org.gradle.api.Project import org.gradle.api.artifacts.type.ArtifactTypeDefinition import org.gradle.api.file.Directory import org.gradle.api.provider.Provider import java.io.File +import java.nio.file.FileSystemException +import java.nio.file.Files import java.nio.file.Path +import java.nio.file.StandardCopyOption +import kotlin.io.path.* -fun getCacheDirectoryProvider(project: Project): Provider = - project.layout.dir(project.provider { getCacheDirectory(project) }) +fun getGlobalCacheDirectoryProvider(project: Project): Provider = + project.layout.dir(project.provider { getGlobalCacheDirectory(project) }) -fun getCacheDirectory(project: Project): File = +fun getGlobalCacheDirectory(project: Project): File = project.gradle.gradleUserHomeDir.resolve("caches/minecraft-codev") +fun getLocalCacheDirectoryProvider(project: Project): Provider = + project.layout.buildDirectory.dir("minecraft-codev") + private fun getVanillaExtractJarPath( cacheDirectory: Path, version: String, @@ -27,7 +38,74 @@ internal fun commonJarPath( version: String, ) = getVanillaExtractJarPath(cacheDirectory, version, "common") +fun Path.tryLink(target: Path) { + try { + createSymbolicLinkPointingTo(target) + } catch (exception: SecurityException) { + if (exception.message?.let { "symbolic" in it } != true) { + throw exception + } + + try { + createLinkPointingTo(target) + } catch (exception: FileSystemException) { + if (exception.message?.let { "Invalid cross-device link" in it } != true) { + throw exception + } + + target.copyTo(this, StandardCopyOption.COPY_ATTRIBUTES) + } + } +} + internal fun clientJarPath( cacheDirectory: Path, version: String, ) = getVanillaExtractJarPath(cacheDirectory, version, "client") + +fun cacheExpensiveOperation( + cacheDirectory: Path, + operationName: String, + inputFiles: Iterable, + outputPath: Path, + generate: (Path) -> Unit, +) { + val hashes = + runBlocking { + inputFiles.map { + async { hashFile(it.toPath()).asBytes().toList() } + }.awaitAll() + } + + val cumulativeHash = + hashes.reduce { acc, bytes -> + acc.zip(bytes).map { (a, b) -> (b + a * 31).toByte() } + }.toByteArray() + + val directoryName = HashCode.fromBytes(cumulativeHash).toString() + + val cachedOperationDirectoryName = cacheDirectory + .resolve("cached-operations") + .resolve(operationName) + .resolve(directoryName) + + val cachedOutput = cachedOperationDirectoryName.resolve(outputPath.fileName) + + if (cachedOutput.exists()) { + outputPath.deleteIfExists() + outputPath.tryLink(cachedOutput) + + return + } + + val temporaryPath = Files.createTempFile("$operationName-${outputPath.nameWithoutExtension}", ".${outputPath.extension}") + temporaryPath.deleteExisting() + + generate(temporaryPath) + + cachedOperationDirectoryName.createDirectories() + temporaryPath.copyTo(cachedOutput, StandardCopyOption.COPY_ATTRIBUTES) + + outputPath.deleteIfExists() + outputPath.tryLink(cachedOutput) +} diff --git a/minecraft-codev-decompiler/build.gradle.kts b/minecraft-codev-decompiler/build.gradle.kts index 0cef801..d04a4f8 100644 --- a/minecraft-codev-decompiler/build.gradle.kts +++ b/minecraft-codev-decompiler/build.gradle.kts @@ -11,7 +11,7 @@ gradlePlugin { } dependencies { - implementation(group = "org.vineflower", name = "vineflower", version = "1.9.3") + implementation(group = "org.vineflower", name = "vineflower", version = "1.10.1") implementation(projects.minecraftCodevCore) } diff --git a/minecraft-codev-fabric/src/main/kotlin/net/msrandom/minecraftcodev/fabric/runs/FabricRunsDefaultsContainer.kt b/minecraft-codev-fabric/src/main/kotlin/net/msrandom/minecraftcodev/fabric/runs/FabricRunsDefaultsContainer.kt index a519264..af68ec7 100644 --- a/minecraft-codev-fabric/src/main/kotlin/net/msrandom/minecraftcodev/fabric/runs/FabricRunsDefaultsContainer.kt +++ b/minecraft-codev-fabric/src/main/kotlin/net/msrandom/minecraftcodev/fabric/runs/FabricRunsDefaultsContainer.kt @@ -56,17 +56,14 @@ open class FabricRunsDefaultsContainer(private val defaults: RunConfigurationDef .assetIndex } - val extractNativesTask = - sourceSet.flatMap { - project.tasks.named(it.extractNativesTaskName, ExtractNatives::class.java) - } + val extractNativesTask = project.tasks.withType(ExtractNatives::class.java).getByName(sourceSet.get().extractNativesTaskName) val downloadAssetsTask = sourceSet.flatMap { project.tasks.named(it.downloadAssetsTaskName, DownloadAssets::class.java) } - val nativesDirectory = extractNativesTask.flatMap(ExtractNatives::destinationDirectory) + val nativesDirectory = extractNativesTask.destinationDirectory val assetsDirectory = downloadAssetsTask.flatMap(DownloadAssets::assetsDirectory) arguments.add(compileArgument("--assetsDir=", assetsDirectory)) diff --git a/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/MinecraftForgeComponentClassifierMetadataRule.kt b/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/MinecraftForgeComponentClassifierMetadataRule.kt index 68ceabb..d3766c0 100644 --- a/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/MinecraftForgeComponentClassifierMetadataRule.kt +++ b/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/MinecraftForgeComponentClassifierMetadataRule.kt @@ -6,8 +6,6 @@ import org.gradle.api.artifacts.ComponentMetadataDetails import org.gradle.api.artifacts.ComponentMetadataRule import org.gradle.api.artifacts.repositories.RepositoryResourceAccessor import org.gradle.api.attributes.Attribute -import org.gradle.api.attributes.Category -import org.gradle.api.model.ObjectFactory import javax.inject.Inject @JvmField @@ -29,7 +27,35 @@ abstract class MinecraftForgeComponentClassifierMetadataRule @Inject constructor it.attributes.attribute(CLASSIFIER_ATTRIBUTE, "") } - addVariant("${classifier}-compile", "compile") { + withVariant("apiElements") { + it.attributes.attribute(CLASSIFIER_ATTRIBUTE, "") + } + + withVariant("runtimeElements") { + it.attributes.attribute(CLASSIFIER_ATTRIBUTE, "") + } + + maybeAddVariant("${classifier}-compile", "compile") { + it.attributes.attribute(CLASSIFIER_ATTRIBUTE, classifier) + + it.withFiles { + it.removeAllFiles() + + it.addFile("${id.name}-${id.version}-$classifier.jar") + } + } + + maybeAddVariant("${classifier}-runtime", "runtime") { + it.attributes.attribute(CLASSIFIER_ATTRIBUTE, classifier) + + it.withFiles { + it.removeAllFiles() + + it.addFile("${id.name}-${id.version}-$classifier.jar") + } + } + + maybeAddVariant("${classifier}ApiElements", "apiElements") { it.attributes.attribute(CLASSIFIER_ATTRIBUTE, classifier) it.withFiles { @@ -39,7 +65,7 @@ abstract class MinecraftForgeComponentClassifierMetadataRule @Inject constructor } } - addVariant("${classifier}-runtime", "runtime") { + maybeAddVariant("${classifier}RuntimeElements", "runtimeElements") { it.attributes.attribute(CLASSIFIER_ATTRIBUTE, classifier) it.withFiles { diff --git a/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/MinecraftForgeComponentMetadataRule.kt b/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/MinecraftForgeComponentMetadataRule.kt index 0d0a964..d2161ea 100644 --- a/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/MinecraftForgeComponentMetadataRule.kt +++ b/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/MinecraftForgeComponentMetadataRule.kt @@ -7,9 +7,8 @@ import net.msrandom.minecraftcodev.core.resolve.getAllDependencies import org.gradle.api.artifacts.CacheableRule import org.gradle.api.artifacts.ComponentMetadataContext import org.gradle.api.artifacts.ComponentMetadataRule +import org.gradle.api.artifacts.Dependency import org.gradle.api.artifacts.repositories.RepositoryResourceAccessor -import org.gradle.api.attributes.Attribute -import org.gradle.api.attributes.Category import org.gradle.api.model.ObjectFactory import java.io.File import java.io.Serializable @@ -55,26 +54,23 @@ abstract class MinecraftForgeComponentMetadataRule @Inject constructor( private val versionManifestUrl: String, private val isOffline: Boolean, private val userdev: UserdevPath, - private val variantName: String, - private val attribute: Attribute, - private val attributeValue: T, + private val capability: String, ) : ComponentMetadataRule { - abstract val objectFactory: ObjectFactory - @Inject get - abstract val repositoryResourceAccessor: RepositoryResourceAccessor @Inject get override fun execute(context: ComponentMetadataContext) { - context.details.addVariant(variantName) { variant -> - val userdevJar by lazy(LazyThreadSafetyMode.NONE) { - getUserdev(userdev, repositoryResourceAccessor)!! + context.details.addVariant(capability, Dependency.DEFAULT_CONFIGURATION) { variant -> + variant.withCapabilities { + for (capability in it.capabilities) { + it.removeCapability(capability.group, capability.name) + } + + it.addCapability("net.msrandom", capability, "0.0.0") } - variant.attributes { - it - .attribute(Category.CATEGORY_ATTRIBUTE, objectFactory.named(Category::class.java, Category.REGULAR_PLATFORM)) - .attribute(attribute, attributeValue) + val userdevJar by lazy(LazyThreadSafetyMode.NONE) { + getUserdev(userdev, repositoryResourceAccessor)!! } variant.withDependencies { diff --git a/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/mappings/McpConfigMappingResolutionRule.kt b/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/mappings/McpConfigMappingResolutionRule.kt index 9b9f26f..447a416 100644 --- a/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/mappings/McpConfigMappingResolutionRule.kt +++ b/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/mappings/McpConfigMappingResolutionRule.kt @@ -10,7 +10,7 @@ import net.msrandom.minecraftcodev.core.VERSION_MANIFEST_URL import net.msrandom.minecraftcodev.core.getVersionList import net.msrandom.minecraftcodev.core.resolve.MinecraftDownloadVariant import net.msrandom.minecraftcodev.core.resolve.downloadMinecraftFile -import net.msrandom.minecraftcodev.core.utils.getCacheDirectoryProvider +import net.msrandom.minecraftcodev.core.utils.getGlobalCacheDirectoryProvider import net.msrandom.minecraftcodev.core.utils.lazyProvider import net.msrandom.minecraftcodev.core.utils.toPath import net.msrandom.minecraftcodev.forge.McpConfigFile @@ -44,7 +44,7 @@ fun mcpConfigDependency( fun mcpConfigExtraRemappingFiles( project: Project, mcpConfigFile: String, - cacheDirectory: Provider = getCacheDirectoryProvider(project), + cacheDirectory: Provider = getGlobalCacheDirectoryProvider(project), metadataUrl: Provider = project.provider { VERSION_MANIFEST_URL }, isOffline: Provider = project.provider { project.gradle.startParameter.isOffline }, ): Provider> { diff --git a/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/task/ResolvePatchedMinecraft.kt b/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/task/ResolvePatchedMinecraft.kt index 1f00f28..bb26d49 100644 --- a/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/task/ResolvePatchedMinecraft.kt +++ b/minecraft-codev-forge/src/main/kotlin/net/msrandom/minecraftcodev/forge/task/ResolvePatchedMinecraft.kt @@ -3,6 +3,7 @@ package net.msrandom.minecraftcodev.forge.task import net.minecraftforge.accesstransformer.TransformerProcessor import net.msrandom.minecraftcodev.core.resolve.* import net.msrandom.minecraftcodev.core.task.CachedMinecraftTask +import net.msrandom.minecraftcodev.core.utils.cacheExpensiveOperation import net.msrandom.minecraftcodev.core.utils.getAsPath import net.msrandom.minecraftcodev.core.utils.toPath import net.msrandom.minecraftcodev.core.utils.walk @@ -14,7 +15,6 @@ import org.gradle.api.Project import org.gradle.api.artifacts.ConfigurationContainer import org.gradle.api.artifacts.dsl.DependencyHandler 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.* @@ -102,9 +102,7 @@ abstract class ResolvePatchedMinecraft : CachedMinecraftTask() { ) } - @TaskAction - fun resolve() { - val cacheDirectory = cacheParameters.directory.getAsPath() + private fun resolve(cacheDirectory: Path, outputPath: Path) { val isOffline = cacheParameters.isOffline.get() val metadata = cacheParameters.versionList().version(version.get()) @@ -150,7 +148,6 @@ abstract class ResolvePatchedMinecraft : CachedMinecraftTask() { librariesFile.writeLines(libraries.flatMap { listOf("-e", it.absolutePath) }) - val outputFile = output.get() val clientExtra = clientExtra.get() val patchLog = temporaryDir.resolve("patch.log").outputStream() @@ -278,7 +275,7 @@ abstract class ResolvePatchedMinecraft : CachedMinecraftTask() { "--inJar", patched.toAbsolutePath().toString(), "--outJar", - outputFile.toString(), + outputPath.toString(), *atFiles .flatMap { at -> listOf("--atFile", at.toAbsolutePath().toString()) @@ -301,6 +298,15 @@ abstract class ResolvePatchedMinecraft : CachedMinecraftTask() { } } - addMinecraftMarker(outputFile.toPath()) + addMinecraftMarker(outputPath) + } + + @TaskAction + fun resolve() { + val cacheDirectory = cacheParameters.directory.getAsPath() + + cacheExpensiveOperation(cacheDirectory, "patch", patches, output.getAsPath()) { + resolve(cacheDirectory, it) + } } } diff --git a/minecraft-codev-intersections/src/main/kotlin/net/msrandom/minecraftcodev/intersection/JarIntersection.kt b/minecraft-codev-intersections/src/main/kotlin/net/msrandom/minecraftcodev/intersection/JarIntersection.kt index 03ceb8f..1250859 100644 --- a/minecraft-codev-intersections/src/main/kotlin/net/msrandom/minecraftcodev/intersection/JarIntersection.kt +++ b/minecraft-codev-intersections/src/main/kotlin/net/msrandom/minecraftcodev/intersection/JarIntersection.kt @@ -1,9 +1,12 @@ package net.msrandom.minecraftcodev.intersection +import net.msrandom.minecraftcodev.core.utils.cacheExpensiveOperation import net.msrandom.minecraftcodev.core.utils.getAsPath +import net.msrandom.minecraftcodev.core.utils.getLocalCacheDirectoryProvider import net.msrandom.minecraftcodev.core.utils.zipFileSystem import org.gradle.api.DefaultTask import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty import org.gradle.api.tasks.* import org.objectweb.asm.ClassReader @@ -223,6 +226,9 @@ abstract class JarIntersection : DefaultTask() { abstract val output: RegularFileProperty @OutputFile get + abstract val cacheDirectory: DirectoryProperty + @Internal get + init { output.convention( project.layout.file( @@ -231,14 +237,11 @@ abstract class JarIntersection : DefaultTask() { }, ), ) - } - @TaskAction - fun intersection() { - val output = output.getAsPath() - - output.deleteIfExists() + cacheDirectory.set(getLocalCacheDirectoryProvider(project)) + } + private fun intersection(output: Path) { val intersection = files.asSequence().map(File::toPath).reduce { acc, path -> val intermediateOutput = Files.createTempFile("intermediate-intersection", ".jar") @@ -271,4 +274,13 @@ abstract class JarIntersection : DefaultTask() { intersection.moveTo(output) } + + @TaskAction + fun intersection() { + val output = output.getAsPath() + + cacheExpensiveOperation(cacheDirectory.getAsPath(), "intersection", files, output) { + intersection(it) + } + } } diff --git a/minecraft-codev-remapper/src/main/kotlin/net/msrandom/minecraftcodev/remapper/JarRemapper.kt b/minecraft-codev-remapper/src/main/kotlin/net/msrandom/minecraftcodev/remapper/JarRemapper.kt index 75c1230..30c5f08 100644 --- a/minecraft-codev-remapper/src/main/kotlin/net/msrandom/minecraftcodev/remapper/JarRemapper.kt +++ b/minecraft-codev-remapper/src/main/kotlin/net/msrandom/minecraftcodev/remapper/JarRemapper.kt @@ -1,10 +1,5 @@ package net.msrandom.minecraftcodev.remapper -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.future.await -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import kotlinx.coroutines.withContext import net.fabricmc.mappingio.MappedElementKind import net.fabricmc.mappingio.MappingVisitor import net.fabricmc.mappingio.adapter.MappingSourceNsSwitch @@ -14,8 +9,11 @@ import net.fabricmc.tinyremapper.IMappingProvider import net.fabricmc.tinyremapper.NonClassCopyMode import net.fabricmc.tinyremapper.OutputConsumerPath import net.fabricmc.tinyremapper.TinyRemapper +import net.msrandom.minecraftcodev.core.utils.cacheExpensiveOperation +import net.msrandom.minecraftcodev.core.utils.getAsPath import net.msrandom.minecraftcodev.core.utils.zipFileSystem import net.msrandom.minecraftcodev.remapper.dependency.getNamespaceId +import org.gradle.api.file.FileCollection import org.objectweb.asm.commons.Remapper import java.io.File import java.nio.file.Path diff --git a/minecraft-codev-remapper/src/main/kotlin/net/msrandom/minecraftcodev/remapper/RemapAction.kt b/minecraft-codev-remapper/src/main/kotlin/net/msrandom/minecraftcodev/remapper/RemapAction.kt index a6f6705..5d06084 100644 --- a/minecraft-codev-remapper/src/main/kotlin/net/msrandom/minecraftcodev/remapper/RemapAction.kt +++ b/minecraft-codev-remapper/src/main/kotlin/net/msrandom/minecraftcodev/remapper/RemapAction.kt @@ -1,7 +1,10 @@ package net.msrandom.minecraftcodev.remapper +import net.msrandom.minecraftcodev.core.utils.cacheExpensiveOperation +import net.msrandom.minecraftcodev.core.utils.getAsPath import org.gradle.api.artifacts.transform.* import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.FileCollection import org.gradle.api.file.FileSystemLocation import org.gradle.api.model.ObjectFactory @@ -40,6 +43,9 @@ abstract class RemapAction : TransformAction { @Input get + abstract val cacheDirectory: DirectoryProperty + @Internal get + init { apply { targetNamespace.convention(MinecraftCodevRemapperPlugin.NAMED_MAPPINGS_NAMESPACE) @@ -77,19 +83,30 @@ abstract class RemapAction : TransformAction { val sourceNamespace = parameters.sourceNamespace.get() val targetNamespace = parameters.targetNamespace.get() - println("Remapping mod $input from $sourceNamespace to $targetNamespace") - val output = outputs.file("${input.nameWithoutExtension}-$targetNamespace.${input.extension}") - val mappings = loadMappings(parameters.mappings, execOperations, parameters.extraFiles.getOrElse(emptyMap())) + val extraFiles = parameters.extraFiles.getOrElse(emptyMap()) + + val cacheKey = objectFactory.fileCollection() + + cacheKey.from(classpath) + cacheKey.from(extraFiles.values) + cacheKey.from(parameters.mappings) + cacheKey.from(inputFile.get().asFile) - JarRemapper.remap( - mappings, - sourceNamespace, - targetNamespace, - input.toPath(), - output.toPath(), - classpath + parameters.extraClasspath - objectFactory.fileTree().apply { from(inputFile) }, - ) + cacheExpensiveOperation(parameters.cacheDirectory.getAsPath(), "remap", cacheKey, output.toPath()) { + println("Remapping mod $input from $sourceNamespace to $targetNamespace") + + val mappings = loadMappings(parameters.mappings, execOperations, extraFiles) + + JarRemapper.remap( + mappings, + sourceNamespace, + targetNamespace, + input.toPath(), + it, + classpath + parameters.extraClasspath, + ) + } } } diff --git a/minecraft-codev-remapper/src/main/kotlin/net/msrandom/minecraftcodev/remapper/task/RemapTask.kt b/minecraft-codev-remapper/src/main/kotlin/net/msrandom/minecraftcodev/remapper/task/RemapTask.kt index adb8b00..5ec197d 100644 --- a/minecraft-codev-remapper/src/main/kotlin/net/msrandom/minecraftcodev/remapper/task/RemapTask.kt +++ b/minecraft-codev-remapper/src/main/kotlin/net/msrandom/minecraftcodev/remapper/task/RemapTask.kt @@ -1,12 +1,16 @@ package net.msrandom.minecraftcodev.remapper.task +import net.msrandom.minecraftcodev.core.utils.cacheExpensiveOperation import net.msrandom.minecraftcodev.core.utils.getAsPath +import net.msrandom.minecraftcodev.core.utils.getGlobalCacheDirectoryProvider import net.msrandom.minecraftcodev.remapper.JarRemapper import net.msrandom.minecraftcodev.remapper.MinecraftCodevRemapperPlugin import net.msrandom.minecraftcodev.remapper.loadMappings import org.gradle.api.DefaultTask import org.gradle.api.file.ConfigurableFileCollection +import org.gradle.api.file.DirectoryProperty import org.gradle.api.file.RegularFileProperty +import org.gradle.api.model.ObjectFactory import org.gradle.api.provider.MapProperty import org.gradle.api.provider.Property import org.gradle.api.tasks.* @@ -44,6 +48,12 @@ abstract class RemapTask : DefaultTask() { @Input get + abstract val cacheDirectory: DirectoryProperty + @Internal get + + abstract val objectFactory: ObjectFactory + @Inject get + abstract val execOperations: ExecOperations @Inject get @@ -63,20 +73,33 @@ abstract class RemapTask : DefaultTask() { ) targetNamespace.convention(MinecraftCodevRemapperPlugin.NAMED_MAPPINGS_NAMESPACE) + + cacheDirectory.set(getGlobalCacheDirectoryProvider(project)) } } @TaskAction fun remap() { - val mappings = loadMappings(mappings, execOperations, extraFiles.getOrElse(emptyMap())) - - JarRemapper.remap( - mappings, - sourceNamespace.get(), - targetNamespace.get(), - inputFile.getAsPath(), - outputFile.getAsPath(), - classpath, - ) + val extraFiles = extraFiles.getOrElse(emptyMap()) + + val cacheKey = objectFactory.fileCollection() + + cacheKey.from(classpath) + cacheKey.from(extraFiles.values) + cacheKey.from(mappings) + cacheKey.from(inputFile.get().asFile) + + cacheExpensiveOperation(cacheDirectory.getAsPath(), "remap", cacheKey, outputFile.getAsPath()) { + val mappings = loadMappings(mappings, execOperations, extraFiles) + + JarRemapper.remap( + mappings, + sourceNamespace.get(), + targetNamespace.get(), + inputFile.getAsPath(), + it, + classpath, + ) + } } } diff --git a/minecraft-codev-runs/src/main/kotlin/net/msrandom/minecraftcodev/runs/MinecraftCodevRunsPlugin.kt b/minecraft-codev-runs/src/main/kotlin/net/msrandom/minecraftcodev/runs/MinecraftCodevRunsPlugin.kt index dcbfc90..76fdb03 100644 --- a/minecraft-codev-runs/src/main/kotlin/net/msrandom/minecraftcodev/runs/MinecraftCodevRunsPlugin.kt +++ b/minecraft-codev-runs/src/main/kotlin/net/msrandom/minecraftcodev/runs/MinecraftCodevRunsPlugin.kt @@ -2,10 +2,9 @@ package net.msrandom.minecraftcodev.runs import net.msrandom.minecraftcodev.core.utils.applyPlugin import net.msrandom.minecraftcodev.core.utils.createSourceSetElements -import net.msrandom.minecraftcodev.core.utils.getCacheDirectoryProvider +import net.msrandom.minecraftcodev.core.utils.getGlobalCacheDirectoryProvider import net.msrandom.minecraftcodev.runs.task.DownloadAssets import net.msrandom.minecraftcodev.runs.task.ExtractNatives -import org.apache.commons.lang3.StringUtils import org.gradle.api.Plugin import org.gradle.api.plugins.ApplicationPlugin import org.gradle.api.plugins.PluginAware @@ -20,7 +19,7 @@ class MinecraftCodevRunsPlugin : Plugin { override fun apply(target: T) = applyPlugin(target) { // Log4j configs - val cache = getCacheDirectoryProvider(this) + val cache = getGlobalCacheDirectoryProvider(this) // val logging: Path = cache.resolve("logging") fun addSourceElements(