add mod dependency remapping (using mod* configurations)

- move loader to the minecraft dependencies to stop it from polluting mod poms
- add AW validation, fix aw bug
- add tasks to clear caches
This commit is contained in:
moehreag 2024-07-02 14:08:11 +02:00
parent 3883c9cafd
commit f7ea37bf1a
5 changed files with 296 additions and 57 deletions

View file

@ -26,6 +26,8 @@ repositories {
dependencies { dependencies {
implementation("dev.frogmc:thyroxine:0.0.1-alpha.6") implementation("dev.frogmc:thyroxine:0.0.1-alpha.6")
implementation("org.ow2.asm:asm:9.7") implementation("org.ow2.asm:asm:9.7")
implementation("org.ow2.asm:asm-commons:9.7")
implementation("org.ow2.asm:asm-tree:9.7")
implementation("com.google.code.gson:gson:2.10.1") implementation("com.google.code.gson:gson:2.10.1")
implementation("org.vineflower:vineflower:1.10.1") implementation("org.vineflower:vineflower:1.10.1")
testImplementation(kotlin("test")) testImplementation(kotlin("test"))

View file

@ -12,4 +12,6 @@ object Constants {
const val GEN_RUN_CONFIGS_TASK = "genRunConfigs" const val GEN_RUN_CONFIGS_TASK = "genRunConfigs"
const val RUN_CLIENT_TASK = "runClient" const val RUN_CLIENT_TASK = "runClient"
const val RUNT_SERVER_TASK = "runServer" const val RUNT_SERVER_TASK = "runServer"
const val CLEAR_LOCAL_CACHE_TASK = "clearLocalCache"
const val CLEAR_GLOBAL_CACHE_TASK = "clearGlobalCache"
} }

View file

@ -2,8 +2,15 @@ package dev.frogmc.phytotelma
import dev.frogmc.phytotelma.ext.PhytotelmaGradleExtension import dev.frogmc.phytotelma.ext.PhytotelmaGradleExtension
import dev.frogmc.phytotelma.ext.PhytotelmaGradleExtensionImpl import dev.frogmc.phytotelma.ext.PhytotelmaGradleExtensionImpl
import groovy.util.Node
import org.gradle.api.Plugin import org.gradle.api.Plugin
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.artifacts.ExcludeRule
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.maven.tasks.PublishToMavenRepository
import org.gradle.configurationcache.extensions.capitalized
import java.net.URI import java.net.URI
import java.nio.file.Path import java.nio.file.Path
import kotlin.io.path.createDirectories import kotlin.io.path.createDirectories
@ -26,6 +33,10 @@ class PhytotelmaPlugin : Plugin<Project> {
} }
project.repositories.apply { project.repositories.apply {
maven {
it.name = "Remapped Mod Dependencies"
it.url = project.layout.buildDirectory.asFile.get().resolve("remappedMods").toURI()
}
maven { maven {
it.name = "Minecraft/Local" it.name = "Minecraft/Local"
it.url = localCacheDir.toUri() it.url = localCacheDir.toUri()
@ -50,9 +61,84 @@ class PhytotelmaPlugin : Plugin<Project> {
"phytotelma", "phytotelma",
PhytotelmaGradleExtensionImpl::class.java PhytotelmaGradleExtensionImpl::class.java
) )
remappedConfigurationNames.forEach { conf ->
project.configurations.create("mod" + conf.key.capitalized()) { c ->
c.isCanBeResolved = true
c.isCanBeConsumed = false
project.configurations.getByName(conf.key).extendsFrom(c)
}
}
project.tasks.filterIsInstance<PublishToMavenRepository>()
.forEach {
it.actions.addFirst {
}
}
/*project.extensions.findByType(PublishingExtension::class.java)
.takeIf { it != null }.let { it!! }
.publications.filterIsInstance<MavenPublication>().forEach { p ->
p.pom {
it.withXml {
val project = it.asNode().get("project") as Node
val dependencies = project.get("dependencies") as Node
dependencies.appendNode("dependency")
.setValue(
"<groupId>dev.frogmc</groupId>\n" +
"<artifactId>thyroxine</artifactId>\n" +
"<version>0.0.1-alpha.6</version>\n" +
"<scope>runtime</scope>"
)
}
}
}*/
project.configurations.register(Constants.INCLUDE_CONFIGURATION) {
it.isCanBeResolved = true
it.isCanBeConsumed = false
}
project.configurations.register(Constants.MINECRAFT_CONFIGURATION) {
project.configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
project.configurations.getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
project.configurations.getByName(JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
project.configurations.getByName(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
it.isCanBeResolved = false
it.isCanBeConsumed = false
it.isTransitive = false
}
} }
companion object { companion object {
lateinit var globalCacheDir: Path lateinit var globalCacheDir: Path
val remappedConfigurationNames = mapOf(
JavaPlugin.IMPLEMENTATION_CONFIGURATION_NAME to listOf(
JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME,
JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME,
JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME,
JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME
),
JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME to listOf(
JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME,
JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME
),
JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME to listOf(
JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME,
JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME
),
JavaPlugin.TEST_COMPILE_ONLY_CONFIGURATION_NAME to listOf(
JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME
),
JavaPlugin.RUNTIME_ONLY_CONFIGURATION_NAME to listOf(
JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME,
JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME,
),
JavaPlugin.TEST_RUNTIME_ONLY_CONFIGURATION_NAME to listOf(
JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME,
)
)
} }
} }

View file

@ -9,6 +9,7 @@ import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.plugins.JavaPlugin import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginExtension import org.gradle.api.plugins.JavaPluginExtension
import org.objectweb.asm.* import org.objectweb.asm.*
import org.objectweb.asm.tree.ClassNode
import java.nio.charset.StandardCharsets import java.nio.charset.StandardCharsets
import java.nio.file.FileSystems import java.nio.file.FileSystems
import java.nio.file.Path import java.nio.file.Path
@ -45,18 +46,20 @@ object AccessWidener {
private fun findDependencyAWs(project: Project): Stream<String> { private fun findDependencyAWs(project: Project): Stream<String> {
val conf = project.configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME) val conf = project.configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)
val projectDeps = conf.dependencies.filterIsInstance<ProjectDependency>() val projectDeps = conf.dependencies.filterIsInstance<ProjectDependency>()
.mapNotNull { getAWFile(it.dependencyProject) }.stream().flatMap { readTransitiveAW(it) } .mapNotNull { getAWFile(it.dependencyProject) }.flatMap { readTransitiveAW(it) }
val dependencies = conf.resolvedConfiguration.files.map { it.toPath() }.filter { it.exists() && it.isRegularFile() }.stream().flatMap { val dependencies =
conf.resolvedConfiguration.files.map { it.toPath() }.filter { it.exists() && it.isRegularFile() }.stream()
.flatMap {
FileSystems.newFileSystem(it).use { fs -> FileSystems.newFileSystem(it).use { fs ->
val metadata = fs.getPath(Constants.MOD_METADATA_FILE) val metadata = fs.getPath(Constants.MOD_METADATA_FILE)
PARSER.parse(metadata, FileNotFoundAction.READ_NOTHING) PARSER.parse(metadata, FileNotFoundAction.READ_NOTHING)
.get<String>("frog.extensions.accesswidener")?.let { name -> .get<String>("frog.extensions.accesswidener")?.let { name ->
return@flatMap readTransitiveAW(metadata.resolveSibling(name)) return@flatMap readTransitiveAW(metadata.resolveSibling(name)).stream()
} }
} }
return@flatMap null return@flatMap null
}.filter { it != null } }.filter { it != null }
return Stream.concat(projectDeps, dependencies) return Stream.concat(projectDeps.stream(), dependencies)
} }
fun needsUpdate(project: Project): Boolean { fun needsUpdate(project: Project): Boolean {
@ -70,24 +73,75 @@ object AccessWidener {
return false return false
} }
private fun readAW(project: Project): Stream<String> { fun checkAW(path: Path, gamePath: Path) {
val reader = path.bufferedReader(StandardCharsets.UTF_8)
if (!HEADER.test(reader.readLine() ?: "")) {
error("AccessWidener validation failed (invalid header)")
}
FileSystems.newFileSystem(gamePath).use { fs ->
reader.lines().toList().forEachIndexed { index, line ->
val checkString = line.substring(0, line.indexOf("#"))
if (checkString.isNotEmpty()) {
val parts = checkString.split(SEPARATOR)
if (parts.size < 3) {
error("AccessWidener validation failed in line ${index + 2}: $line")
}
if (parts[1] == "class") {
val target = parts[2]
if (fs.getPath(target).notExists()) {
error("AccessWidener validation failed in line ${index + 2}: $line (Invalid target)")
}
}
if (parts.size < 5) {
error("AccessWidener validation failed in line ${index + 2}: $line (Declaration missing)")
}
val owner = parts[2]
val name = parts[3]
val desc = parts[4]
when (parts[1]) {
"method" -> {
val classReader = ClassReader(fs.getPath(owner).readBytes())
val node = ClassNode()
classReader.accept(node, 0)
if (node.methods.none { it.name.equals(name) && it.desc.equals(desc) }) {
error("AccessWidener validation failed in line ${index + 2}: $line (Could not find target method)")
}
}
"field" -> {
val classReader = ClassReader(fs.getPath(owner).readBytes())
val node = ClassNode()
classReader.accept(node, 0)
if (node.fields.none { it.name.equals(name) && it.desc.equals(desc) }) {
error("AccessWidener validation failed in line ${index + 2}: $line (Could not find target field)")
}
}
}
}
}
}
}
private fun readAW(project: Project): List<String> {
val awFile = getAWFile(project) val awFile = getAWFile(project)
println("Found accesswidener in project: $awFile") println("Found accesswidener in project: $awFile")
return awFile?.bufferedReader(StandardCharsets.UTF_8) return awFile?.bufferedReader(StandardCharsets.UTF_8)
.takeIf { HEADER.test(it?.readLine() ?: "") }?.lines() .takeIf { HEADER.test(it?.readLine() ?: "") }?.lines()
?.map { it.replace("transitive-", "") } ?.map { it.replace("transitive-", "") }?.toList()
?: Stream.empty() ?: emptyList()
} }
private fun readTransitiveAW(path: Path): Stream<String> { private fun readTransitiveAW(path: Path): List<String> {
return path.bufferedReader(StandardCharsets.UTF_8).takeIf { HEADER.test(it.readLine() ?: "") }?.lines()?.filter { it.startsWith("transitive-") }?: Stream.empty() return path.bufferedReader(StandardCharsets.UTF_8).takeIf { HEADER.test(it.readLine() ?: "") }?.lines()
?.filter { it.startsWith("transitive-") }?.toList() ?: emptyList()
} }
private fun readAllAWs(project: Project): Stream<Entry> { private fun readAllAWs(project: Project): Stream<Entry> {
return Stream.concat( return Stream.concat(
findDependencyAWs(project), findDependencyAWs(project),
readAW(project) readAW(project).stream()
) )
.filter { it.isNotBlank() } .filter { it.isNotBlank() }
.map { if (it.contains("#")) it.split("#")[0] else it }.filter { !HEADER.test(it) } .map { if (it.contains("#")) it.split("#")[0] else it }.filter { !HEADER.test(it) }

View file

@ -1,5 +1,7 @@
package dev.frogmc.phytotelma.ext package dev.frogmc.phytotelma.ext
import com.electronwill.nightconfig.core.file.FileNotFoundAction
import com.electronwill.nightconfig.toml.TomlParser
import dev.frogmc.phytotelma.Constants import dev.frogmc.phytotelma.Constants
import dev.frogmc.phytotelma.PhytotelmaPlugin import dev.frogmc.phytotelma.PhytotelmaPlugin
import dev.frogmc.phytotelma.ProjectStorage import dev.frogmc.phytotelma.ProjectStorage
@ -13,28 +15,28 @@ import dev.frogmc.phytotelma.run.RunConfigGenerator
import dev.frogmc.phytotelma.run.task.RunGameTask import dev.frogmc.phytotelma.run.task.RunGameTask
import dev.frogmc.phytotelma.vineflower.FrogJavadocProvider import dev.frogmc.phytotelma.vineflower.FrogJavadocProvider
import dev.frogmc.thyroxine.Thyroxine import dev.frogmc.thyroxine.Thyroxine
import dev.frogmc.thyroxine.api.Mapper
import dev.frogmc.thyroxine.api.data.MappingBundle import dev.frogmc.thyroxine.api.data.MappingBundle
import dev.frogmc.thyroxine.provider.MojmapProvider import dev.frogmc.thyroxine.provider.MojmapProvider
import net.fabricmc.fernflower.api.IFabricJavadocProvider import net.fabricmc.fernflower.api.IFabricJavadocProvider
import org.gradle.api.Action import org.gradle.api.Action
import org.gradle.api.Project import org.gradle.api.Project
import org.gradle.api.artifacts.Configuration
import org.gradle.api.model.ObjectFactory import org.gradle.api.model.ObjectFactory
import org.gradle.api.plugins.JavaBasePlugin import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.plugins.JavaPlugin import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin
import org.gradle.configurationcache.extensions.capitalized
import org.jetbrains.java.decompiler.main.Fernflower import org.jetbrains.java.decompiler.main.Fernflower
import org.jetbrains.java.decompiler.main.decompiler.PrintStreamLogger import org.jetbrains.java.decompiler.main.decompiler.PrintStreamLogger
import org.jetbrains.java.decompiler.main.decompiler.SingleFileSaver import org.jetbrains.java.decompiler.main.decompiler.SingleFileSaver
import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences import org.jetbrains.java.decompiler.main.extern.IFernflowerPreferences
import java.io.PrintStream import java.io.PrintStream
import java.nio.file.FileSystems
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.StandardCopyOption import java.nio.file.StandardCopyOption
import javax.inject.Inject import javax.inject.Inject
import kotlin.io.path.createParentDirectories import kotlin.io.path.*
import kotlin.io.path.deleteExisting
import kotlin.io.path.exists
import kotlin.io.path.notExists
abstract class PhytotelmaGradleExtensionImpl @Inject constructor( abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
private val project: Project, private val project: Project,
@ -104,24 +106,10 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
} }
} }
project.configurations.register(Constants.INCLUDE_CONFIGURATION) {
it.isCanBeResolved = true
it.isCanBeConsumed = false
}
project.configurations.register(Constants.MINECRAFT_CONFIGURATION) {
project.configurations.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
project.configurations.getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
project.configurations.getByName(JavaPlugin.TEST_COMPILE_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
project.configurations.getByName(JavaPlugin.TEST_RUNTIME_CLASSPATH_CONFIGURATION_NAME).extendsFrom(it)
it.isCanBeResolved = false
it.isCanBeConsumed = false
it.isTransitive = false
}
val buildTask = project.tasks.register(Constants.BUILD_TASK, PhytotelmaBuildTask::class.java) val buildTask = project.tasks.register(Constants.BUILD_TASK, PhytotelmaBuildTask::class.java)
project.tasks.getByName(JavaBasePlugin.BUILD_TASK_NAME).dependsOn(buildTask) project.tasks.getByName(JavaBasePlugin.BUILD_TASK_NAME).dependsOn(buildTask)
project.tasks.getByName(JavaPlugin.JAR_TASK_NAME).actions.addLast {
project.tasks.getByName(JavaPlugin.JAR_TASK_NAME).actions.addLast { task ->
val storage = ProjectStorage.get(project) val storage = ProjectStorage.get(project)
if (storage.targetNamespace != "mojmap") { if (storage.targetNamespace != "mojmap") {
val mappings = MappingBundle.merge( val mappings = MappingBundle.merge(
@ -130,9 +118,52 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
PhytotelmaPlugin.globalCacheDir.resolve("net/minecraft/client/${storage.minecraftVersion}/client-${storage.minecraftVersion}.txt") PhytotelmaPlugin.globalCacheDir.resolve("net/minecraft/client/${storage.minecraftVersion}/client-${storage.minecraftVersion}.txt")
).orElseThrow().reverse().renameDstNamespace("mojmap") ).orElseThrow().reverse().renameDstNamespace("mojmap")
).forNamespaces(storage.targetNamespace, "mojmap") ).forNamespaces(storage.targetNamespace, "mojmap")
it.outputs.files.forEach { file -> val parser = TomlParser()
task.outputs.files.forEach { file ->
val temp = Files.createTempFile("", file.name) val temp = Files.createTempFile("", file.name)
Files.copy(file.toPath(), temp, StandardCopyOption.REPLACE_EXISTING) Files.copy(file.toPath(), temp, StandardCopyOption.REPLACE_EXISTING)
FileSystems.newFileSystem(temp).use { fs ->
val metadata = fs.getPath(Constants.MOD_METADATA_FILE)
parser.parse(metadata, FileNotFoundAction.READ_NOTHING)
.get<String>("frog.extensions.accesswidener")?.let { name ->
val aw = metadata.resolveSibling(name)
AccessWidener.checkAW(aw, ProjectStorage.get(project).remappedGameJarPath!!)
val mapper = Mapper(mappings) { listOf() }
val buffer = buildString {
aw.forEachLine {
if (it.contains("\\t") && !it.startsWith("#")) {
val parts = it.split("[\\t #]+".toRegex()).toMutableList()
if (parts.size > 2) {
val type = parts[1]
when (type) {
"class" -> {
parts[2] = mapper.map(parts[2])
}
"fields" -> {
parts[3] = mapper.mapFieldName(parts[2], parts[3], parts[4])
parts[4] = mapper.mapDesc(parts[4])
parts[3] = mapper.map(parts[2])
}
"methods" -> {
parts[3] = mapper.mapMethodName(parts[2], parts[3], parts[4])
parts[4] = mapper.mapMethodDesc(parts[4])
parts[2] = mapper.map(parts[2])
}
}
appendLine(parts.joinToString("\\t"))
return@forEachLine
}
}
appendLine(it)
}
}
aw.writeText(buffer)
}
}
Thyroxine.remap(mappings, temp, file.toPath(), false, false) Thyroxine.remap(mappings, temp, file.toPath(), false, false)
Files.deleteIfExists(temp) Files.deleteIfExists(temp)
} }
@ -146,28 +177,90 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
} }
} }
val configuration = project.configurations.create("modImplemenation") { project.tasks.register(Constants.CLEAR_LOCAL_CACHE_TASK) { task ->
it.isCanBeResolved = true task.group = Constants.TASK_GROUP
it.isCanBeConsumed = false task.actions.add {
} clearLocalCache()
project.afterEvaluate {
//remapModDependencies(configuration)
} }
} }
private fun remapModDependencies(configuration: Configuration) { project.tasks.register(Constants.CLEAR_GLOBAL_CACHE_TASK) { task ->
// TODO task.group = Constants.TASK_GROUP
val mappings = task.actions.add {
ProjectStorage.get(project).mappings!!.forNamespaces("mojmap", ProjectStorage.get(project).targetNamespace) clearGlobalCache()
val targetPath = ProjectStorage.get(project).localCacheDir!! }
}
}
@OptIn(ExperimentalPathApi::class)
private fun clearLocalCache() {
ProjectStorage.get(project).localCacheDir?.deleteRecursively()
}
@OptIn(ExperimentalPathApi::class)
private fun clearGlobalCache() {
PhytotelmaPlugin.globalCacheDir.deleteRecursively()
}
private fun remapModDependencies() {
PhytotelmaPlugin.remappedConfigurationNames.forEach { conf ->
val artifacts = project.configurations.getByName("mod" + conf.key.capitalized())
.resolvedConfiguration.resolvedArtifacts
if (artifacts.isEmpty()) {
return
}
val target = project.configurations.create("mod" + conf.key.capitalized()+"Mapped") { c ->
c.isTransitive = false // TODO while this configuration should not be transitive, the original dependency should be!
conf.value.forEach {
project.configurations.getByName(it).extendsFrom(c)
}
}
val storage = ProjectStorage.get(project)
val mappings = MappingBundle.merge(
storage.mappings!!.reverse(), MojmapProvider.get(
storage.minecraftVersion!!,
PhytotelmaPlugin.globalCacheDir.resolve("net/minecraft/client/${storage.minecraftVersion}/client-${storage.minecraftVersion}.txt")
).orElseThrow().reverse().renameDstNamespace("mojmap")
).forNamespaces("mojmap", storage.targetNamespace)
val targetPath = project.layout.buildDirectory.asFile.get().toPath().resolve("remappedMods")
.resolve("dev/frogmc/phytotelma/remapped_mods")
val remappedPaths = mutableListOf<Path>() val remappedPaths = mutableListOf<Path>()
configuration.resolvedConfiguration.resolvedArtifacts.forEach { artifacts.forEach { artifact ->
val remappedPath = targetPath.resolve(it.id.toString().replace(":", "/").replace(".", "/")) println(artifact.file)
val id = artifact.id.componentIdentifier.toString().split(":")
val group = artifact.moduleVersion.id.group
val name = artifact.moduleVersion.id.name
val groupname = (group + "_" + name).replace(".", "_")
val version = artifact.moduleVersion.id.version
val classifier = artifact.classifier
val remappedPath = targetPath.resolve(groupname).resolve(version).resolve(artifact.file.name)
/*val remappedPath = targetPath.resolve(group.replace(".", "/"))
.resolve(name).resolve(version).resolve(artifact.file.name)*/
remappedPath.createParentDirectories()
remappedPaths.add(remappedPath) remappedPaths.add(remappedPath)
configuration.dependencies.removeIf { d -> d.group + ":" + d.name + ":" + d.version == it.id.toString() } val pom = remappedPath.resolveSibling(artifact.file.name.removeSuffix(".jar")+".pom")
} //val pom = remappedPath.resolveSibling(artifact.file.name.substring(0, artifact.file.name.lastIndexOf("."))+".pom")
pom.writeText(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<project xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\" xmlns=\"http://maven.apache.org/POM/4.0.0\"\n" +
"\t\t xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n" +
"\t<modelVersion>4.0.0</modelVersion>\n" +
//"\t<groupId>$group</groupId>\n" +
//"\t<artifactId>$name</artifactId>\n" +
"\t<groupId>dev.frogmc.phytotelma.remapped_mods</groupId>\n" +
"\t<artifactId>$groupname</artifactId>\n" +
"\t<version>$version</version>\n" +
"</project>"
)
remappedPaths.add(pom)
Thyroxine.remap(mappings, artifact.file.toPath(), remappedPath, false, false)
//project.dependencies.add(conf.key, group+":"+name+":"+version+(classifier?:""))
project.dependencies.add(target.name, "dev.frogmc.phytotelma.remapped_mods:$groupname:$version"+(classifier?.let { ":$it" }?:""))
}
}
} }
override fun minecraft(action: Action<MinecraftConfiguration>) { override fun minecraft(action: Action<MinecraftConfiguration>) {
@ -227,6 +320,8 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
AccessWidener.apply(project, remappedJar) AccessWidener.apply(project, remappedJar)
} }
} }
remapModDependencies()
} }
} }
@ -236,7 +331,7 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
if (conf.version == null) { if (conf.version == null) {
error("No loader version provided!") error("No loader version provided!")
} }
project.dependencies.add("implementation", "dev.frogmc:frogloader:${conf.version!!}") project.dependencies.add(Constants.MINECRAFT_CONFIGURATION, "dev.frogmc:frogloader:${conf.version!!}")
} }
override fun froglib(action: Action<VersionConfiguration>) { override fun froglib(action: Action<VersionConfiguration>) {
@ -245,7 +340,7 @@ abstract class PhytotelmaGradleExtensionImpl @Inject constructor(
if (conf.version == null) { if (conf.version == null) {
error("No froglib version provided!") error("No froglib version provided!")
} }
project.dependencies.add("implementation", "dev.frogmc:froglib:${conf.version!!}") project.dependencies.add("modImplementation", "dev.frogmc:froglib:${conf.version!!}")
} }