Support for Eclipse #2

Merged
kode merged 2 commits from TheKodeToad/run-config-adapter into mistress 2024-05-18 10:55:07 -04:00
9 changed files with 207 additions and 99 deletions
Showing only changes of commit d52b263280 - Show all commits

View file

@ -1,4 +1,4 @@
# bad gradle # i love gradle
# bad gradle # i love gradle
# bad gradle # i love gradle
# bad gradle # i love gradle

View file

@ -1,94 +0,0 @@
package org.ecorous.esnesnon.gradle
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.tasks.SourceSet
import java.nio.file.Files
import java.util.*
import kotlin.io.path.absolute
import kotlin.io.path.createParentDirectories
import kotlin.io.path.notExists
private const val LOG4J_CONFIG_PATH = ".gradle/nonsense/log4j.xml"
private const val ASSET_DIR = "caches/nonsense-gradle/assets"
object RunConfigGenerator {
fun generate(project: Project) {
val log4jPath = project.rootDir.resolve(LOG4J_CONFIG_PATH).toPath().absolute()
if (log4jPath.notExists()) {
log4jPath.createParentDirectories()
RunConfigGenerator::class.java.getResourceAsStream("/log4j.xml").let {
it.use { s ->
Files.copy(s!!, log4jPath)
}
}
}
val runConfigPath = project.rootDir.resolve(".idea").resolve("runConfigurations")
runConfigPath.mkdirs()
val envs = listOf("client", "server")
for (s in envs) {
val name = "Minecraft_${capitalize(s)}.xml"
if (!runConfigPath.resolve(name).exists()) {
val config = RunConfig(s, project)
runConfigPath.resolve(name).writeText(config.getXml())
}
}
}
}
fun capitalize(s: String): String {
if (s.isEmpty()) {
return s
}
return s.substring(0, 1).uppercase(Locale.ROOT) + s.substring(1).replace("([^A-Z])([A-Z])".toRegex(), "$1 $2")
}
class RunConfig(private val env: String, private val project: Project) {
private fun getAssetIndex(): String {
val index = project.gradle.gradleUserHomeDir.toPath().resolve(ASSET_DIR).resolve("indexes").resolve(NonsenseGradlePlugin.minecraftVersion+".json").absolute()
if (index.notExists()) {
index.createParentDirectories()
VersionChecker.downloadAssetIndex(NonsenseGradlePlugin.minecraftVersion, index)
}
return index.fileName.toString()
}
fun getXml(): String {
var modulePath = project.name
var parent = project.parent
while (parent != null) {
modulePath = parent.name + "." + modulePath
parent = project.parent!!
}
val moduleName =
"$modulePath." + project.extensions.getByType(JavaPluginExtension::class.java).sourceSets.getByName(
SourceSet.MAIN_SOURCE_SET_NAME
).name
val args =
"--assetDir ${project.gradle.gradleUserHomeDir.resolve(ASSET_DIR).toPath().absolute()} --version Nonsense --assetIndex ${getAssetIndex()}"
val parameters = "-Dnonsense.development=true -Dlog4j.configurationFile=${project.rootDir.resolve(
LOG4J_CONFIG_PATH).toPath().absolute()} -Dlog4j2.formatMsgNoLookups=true"
val xml = """
<component name="ProjectRunConfigurationManager">
<configuration default="false" factoryName="Application" name="Minecraft ${capitalize(env)}" type="Application">
<option name="MAIN_CLASS_NAME" value="org.ecorous.esnesnon.nonsense.loader.impl.launch.client.Nonsense${capitalize(env)}"/>
<module name="$moduleName"/>
<option name="PROGRAM_PARAMETERS" value="$args"/>
<option name="VM_PARAMETERS" value="$parameters"/>
<option name="WORKING_DIRECTORY" value="${project.rootDir}/run/"/>
<method v="2">
<option enabled="true" name="Make"/>
</method>
<envs>
</envs>
<shortenClasspath name="ARGS_FILE"/>
<classpathModifications/></configuration>
</component>
""".trimIndent()
return xml
}
}

View file

@ -0,0 +1,6 @@
package org.ecorous.esnesnon.gradle.common
enum class Env(val id: String, val pascalName: String) {
SERVER("server", "Server"),
CLIENT("client", "Client"),
}

View file

@ -0,0 +1,21 @@
package org.ecorous.esnesnon.gradle.common
fun sanitizeXmlValue(value: String): String {
return value.replace("&", "&amp;").replace("\"", "&quot;")
}
fun formatXmlList(arg: Array<String>): String {
return sanitizeXmlValue(
arg
.asSequence()
.map {
var result = it
result = result.replace("\\", "\\\\")
result = result.replace("\"", "\\\"")
if (result.contains(" "))
result = "\"$result\""
result
}.joinToString(" ")
)
}

View file

@ -1,7 +1,7 @@
package org.ecorous.esnesnon.gradle.ext package org.ecorous.esnesnon.gradle.ext
import org.ecorous.esnesnon.gradle.NonsenseGradlePlugin import org.ecorous.esnesnon.gradle.NonsenseGradlePlugin
import org.ecorous.esnesnon.gradle.RunConfigGenerator import org.ecorous.esnesnon.gradle.run.RunConfigGenerator
import org.ecorous.esnesnon.gradle.VersionChecker import org.ecorous.esnesnon.gradle.VersionChecker
import org.ecorous.esnesnon.nonsense_remapper.NonsenseRemapper import org.ecorous.esnesnon.nonsense_remapper.NonsenseRemapper
import org.ecorous.esnesnon.nonsense_remapper.api.Mapper import org.ecorous.esnesnon.nonsense_remapper.api.Mapper

View file

@ -0,0 +1,16 @@
package org.ecorous.esnesnon.gradle.run
import org.gradle.api.Project
interface RunConfigAdapter {
fun generate(
project: Project,
name: String,
mainClass: String,
vmArgs: Array<String>,
programArgs: Array<String>
)
/** Typically, return whether we are running within the IDE which makes use of this format. */
fun shouldGenerate(): Boolean;
}

View file

@ -0,0 +1,58 @@
package org.ecorous.esnesnon.gradle.run
import org.ecorous.esnesnon.gradle.NonsenseGradlePlugin
import org.ecorous.esnesnon.gradle.VersionChecker
import org.ecorous.esnesnon.gradle.common.Env
import org.ecorous.esnesnon.gradle.run.adapter.EclipseAdapter
import org.ecorous.esnesnon.gradle.run.adapter.IdeaAdapter
import org.gradle.api.Project
import java.nio.file.Files
import java.nio.file.Path
import kotlin.io.path.absolute
import kotlin.io.path.createParentDirectories
import kotlin.io.path.notExists
object RunConfigGenerator {
private const val LOG4J_CONFIG_PATH = ".gradle/nonsense/log4j.xml"
private const val ASSET_DIR = "caches/nonsense-gradle/assets"
private val ADAPTERS = arrayOf(EclipseAdapter(), IdeaAdapter())
fun generate(project: Project) {
val log4jPath = project.rootDir.resolve(LOG4J_CONFIG_PATH).toPath().absolute()
if (log4jPath.notExists()) {
log4jPath.createParentDirectories()
RunConfigGenerator::class.java.getResourceAsStream("/log4j.xml").use { input ->
Files.copy(input!!, log4jPath)
}
}
val assetPath = project.gradle.gradleUserHomeDir.resolve(ASSET_DIR).toPath().absolute()
val assetIndexPath = assetPath.resolve("indexes").resolve(NonsenseGradlePlugin.minecraftVersion + ".json")
if (assetIndexPath.notExists()) {
assetIndexPath.createParentDirectories()
VersionChecker.downloadAssetIndex(NonsenseGradlePlugin.minecraftVersion, assetIndexPath)
}
val runConfigPath = project.rootDir.resolve(".idea").resolve("runConfigurations")
runConfigPath.mkdirs()
for (adapter in ADAPTERS) {
if (!adapter.shouldGenerate())
continue
for (env in Env.values()) {
adapter.generate(
project,
"Minecraft ${env.pascalName}",
"org.ecorous.esnesnon.nonsense.loader.impl.launch.client.Nonsense${env.pascalName}",
arrayOf("-Dnonsense.development=true", "-Dlog4j.configurationFile=" + assetPath),
arrayOf(
"--assetDir", assetPath.toString(),
"--version", "Nonsense",
"--assetIndex", assetIndexPath.toString()
)
)
}
}
}
}

View file

@ -0,0 +1,51 @@
package org.ecorous.esnesnon.gradle.run.adapter
import org.ecorous.esnesnon.gradle.common.formatXmlList
import org.ecorous.esnesnon.gradle.common.sanitizeXmlValue
import org.ecorous.esnesnon.gradle.run.RunConfigAdapter
import org.gradle.api.Project
import org.gradle.plugins.ide.eclipse.model.EclipseModel
import java.nio.charset.StandardCharsets
class EclipseAdapter : RunConfigAdapter {
override fun generate(
project: Project,
name: String,
mainClass: String,
vmArgs: Array<String>,
programArgs: Array<String>
) {
val projectName = project.extensions.findByType(EclipseModel::class.java)?.project?.name ?: project.name
val file = project.rootDir.resolve("$name.launch")
file.writer(StandardCharsets.UTF_8).use {
// @formatter:off
it.write(
"""
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication">
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
<listEntry value="/${sanitizeXmlValue(projectName)}"/>
</listAttribute>
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
<listEntry value="4"/>
</listAttribute>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_USE_START_ON_FIRST_THREAD" value="true"/>
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.buildship.core.classpathprovider"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="${sanitizeXmlValue(mainClass)}"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="${formatXmlList(programArgs)}"/>
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="${sanitizeXmlValue(projectName)}"/>
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="${formatXmlList(vmArgs)}"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${'$'}{workspace_loc:${sanitizeXmlValue(projectName)}}/%RUN_DIRECTORY%"/>
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="true"/>
</launchConfiguration>
""".trimIndent()
)
// @formatter:on
}
}
override fun shouldGenerate(): Boolean {
return System.getProperty("eclipse.version") != null
}
}

View file

@ -0,0 +1,50 @@
package org.ecorous.esnesnon.gradle.run.adapter
import org.ecorous.esnesnon.gradle.common.formatXmlList
import org.ecorous.esnesnon.gradle.common.sanitizeXmlValue
import org.ecorous.esnesnon.gradle.run.RunConfigAdapter
import org.gradle.api.Project
import java.nio.charset.StandardCharsets
import kotlin.io.path.createDirectories
import kotlin.io.path.isDirectory
import kotlin.io.path.writer
class IdeaAdapter : RunConfigAdapter {
override fun generate(
project: Project,
name: String,
mainClass: String,
vmArgs: Array<String>,
programArgs: Array<String>
) {
val folder = project.projectDir.toPath().resolve(".idea/runConfigurations")
if (!folder.isDirectory())
folder.createDirectories()
val file = folder.resolve("$name.xml")
file.writer(StandardCharsets.UTF_8).use {
it.write(
"""
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="%NAME%" type="Application" factoryName="Application">
<option name="MAIN_CLASS_NAME" value="${sanitizeXmlValue(mainClass)}"/>
<module name="%IDEA_MODULE%"/>
<option name="PROGRAM_PARAMETERS" value="${formatXmlList(programArgs)}"/>
<option name="VM_PARAMETERS" value="${formatXmlList(vmArgs)}"/>
<option name="WORKING_DIRECTORY" value="${'$'}PROJECT_DIR${'$'}/%RUN_DIRECTORY%/"/>
<method v="2">
<option name="Make" enabled="true"/>
</method>
<shortenClasspath name="ARGS_FILE"/>
</configuration>
</component>
""".trimIndent()
)
}
}
override fun shouldGenerate(): Boolean {
return System.getProperty("idea.version") != null
}
}