commit 0cceecdd39702196e0d78489b3753abf71ae7210 Author: Siphalor Date: Mon Mar 23 11:14:33 2026 +0100 Initial commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..f91f646 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,12 @@ +# +# https://help.github.com/articles/dealing-with-line-endings/ +# +# Linux start script should use lf +/gradlew text eol=lf + +# These are Windows script files and should use crlf +*.bat text eol=crlf + +# Binary files should be left untouched +*.jar binary + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c05324 --- /dev/null +++ b/.gitignore @@ -0,0 +1,42 @@ +.gradle +build/ +!gradle/wrapper/gradle-wrapper.jar +!**/src/main/**/build/ +!**/src/test/**/build/ + +### IntelliJ IDEA ### +.idea/ +*.iws +*.iml +*.ipr +out/ +!**/src/main/**/out/ +!**/src/test/**/out/ + +### Kotlin ### +.kotlin + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache +bin/ +!**/src/main/**/bin/ +!**/src/test/**/bin/ + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store diff --git a/README.md b/README.md new file mode 100644 index 0000000..8886938 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +# Siphalor's Minecraft Modding Toolkit (SMCMTK) + +A custom Gradle plugin for developing my Minecaft mods in a cross-version way. + diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..145db24 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,2 @@ +group = "de.siphalor.minecraft-modding-toolkit" +version = "0.1.0" diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 0000000..b6413e3 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,7 @@ +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() +} diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts new file mode 100644 index 0000000..9e67e79 --- /dev/null +++ b/buildSrc/settings.gradle.kts @@ -0,0 +1,3 @@ +plugins { + id("dev.panuszewski.typesafe-conventions") version "0.9.0" +} diff --git a/buildSrc/src/main/kotlin/de.siphalor.smcmtk.plugin.gradle.kts b/buildSrc/src/main/kotlin/de.siphalor.smcmtk.plugin.gradle.kts new file mode 100644 index 0000000..98d8ce8 --- /dev/null +++ b/buildSrc/src/main/kotlin/de.siphalor.smcmtk.plugin.gradle.kts @@ -0,0 +1,43 @@ +plugins { + `java-gradle-plugin` + alias(libs.plugins.kotlin.jvm) + `maven-publish` +} + +group = rootProject.group +version = rootProject.version + +components { + java { withSourcesJar() } +} + +tasks.jar { + manifest { + attributes["Implementation-Version"] = project.version + } +} + +val siphalorMavenUser = project.property("siphalor.maven.user") as String? +val siphalorMavenPassword = project.property("siphalor.maven.password") as String? +publishing { + publications.withType() { + pom { + name = "Siphalor's Minecraft Modding Toolkit" + description = "Provides some general abstraction for easing the development of cross-version (Fabric) mod development.\n" + + "${project.description}" + url = "https://gitea.siphalor.de/Siphalor/smcmtk" + } + } + repositories { + if (siphalorMavenUser != null && siphalorMavenPassword != null) { + maven { + name = "siphalor" + url = uri("https://maven.siphalor.de/upload.php") + credentials { + username = siphalorMavenUser + password = siphalorMavenPassword + } + } + } + } +} diff --git a/gradle-project-plugin/build.gradle.kts b/gradle-project-plugin/build.gradle.kts new file mode 100644 index 0000000..3be6f83 --- /dev/null +++ b/gradle-project-plugin/build.gradle.kts @@ -0,0 +1,12 @@ +plugins { + id("de.siphalor.smcmtk.plugin") +} + +description = "This is the main plugin providing utilities through a Gradle extension." + +gradlePlugin { + val projectPlugin by plugins.creating { + id = "de.siphalor.minecraft-modding-toolkit.project-plugin" + implementationClass = "de.siphalor.minecraft_modding_toolkit.gradle.project_plugin.SmcmtkProjectPlugin" + } +} diff --git a/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkLoomProxy.kt b/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkLoomProxy.kt new file mode 100644 index 0000000..1fafbc7 --- /dev/null +++ b/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkLoomProxy.kt @@ -0,0 +1,35 @@ +package de.siphalor.minecraft_modding_toolkit.gradle.project_plugin + +import net.fabricmc.loom.api.LoomGradleExtensionAPI +import org.gradle.api.Project +import org.gradle.api.artifacts.MinimalExternalModuleDependency +import org.gradle.api.file.RegularFile +import org.gradle.api.logging.Logging +import org.gradle.api.provider.Provider +import org.gradle.api.tasks.SourceSet +import org.jetbrains.annotations.ApiStatus + +@ApiStatus.Internal +class SmcmtkLoomProxy(val project: Project, loomGradleExtensionApi: Any) { + val logger = lazy { Logging.getLogger(javaClass) } + val loom = loomGradleExtensionApi as LoomGradleExtensionAPI + + fun configureOfficialMojangMappings(parchment: Provider?) { + if (parchment == null) { + project.dependencies.add("mappings", loom.officialMojangMappings()) + } else { + project.dependencies.add("mappings", loom.layered { layered -> + layered.officialMojangMappings() + layered.parchment(parchment.map { it.artifact { artifact -> artifact.type = "zip" } }) + }) + } + } + + fun createRemapConfiguration(sourceSet: SourceSet) { + loom.createRemapConfigurations(sourceSet) + } + + fun setAccessWidenerPath(file: RegularFile) { + loom.accessWidenerPath.set(file) + } +} diff --git a/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkProjectExtension.kt b/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkProjectExtension.kt new file mode 100644 index 0000000..bbc105c --- /dev/null +++ b/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkProjectExtension.kt @@ -0,0 +1,14 @@ +package de.siphalor.minecraft_modding_toolkit.gradle.project_plugin + +import org.gradle.api.file.RegularFile +import org.gradle.api.provider.MapProperty +import org.gradle.api.tasks.SourceSet + +abstract class SmcmtkProjectExtension(private val smcmtkProjectPlugin: SmcmtkProjectPlugin) { + abstract val mcProps: MapProperty + + fun useMojangMappings() = smcmtkProjectPlugin.configureMojangMappings() + fun createModConfigurations(sourceSets: List) = smcmtkProjectPlugin.createModConfigurations(sourceSets) + + fun useAccessWidener(file: RegularFile) = smcmtkProjectPlugin.configureAccessWidener(file) +} diff --git a/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkProjectPlugin.kt b/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkProjectPlugin.kt new file mode 100644 index 0000000..17b5acd --- /dev/null +++ b/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/SmcmtkProjectPlugin.kt @@ -0,0 +1,128 @@ +package de.siphalor.minecraft_modding_toolkit.gradle.project_plugin + +import de.siphalor.minecraft_modding_toolkit.gradle.project_plugin.util.joinCamelCase +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.api.file.ProjectLayout +import org.gradle.api.file.RegularFile +import org.gradle.api.logging.Logging +import org.gradle.api.provider.ProviderFactory +import org.gradle.api.tasks.SourceSet +import org.gradle.language.jvm.tasks.ProcessResources +import java.util.* +import javax.inject.Inject + +abstract class SmcmtkProjectPlugin : Plugin { + companion object { + private const val LOOM_PLAIN_PLUGIN_ID = "net.fabricmc.fabric-loom" + private const val LOOM_REMAP_PLUGIN_ID = "net.fabricmc.fabric-loom-remap" + + private val MOD_BASE_CONFIGURATION_NAMES = arrayOf("api", "implementation", "compileOnly", "runtimeOnly", "localRuntime") + + private val ACCESS_WIDENER_DECLARATION_PATTERN = Regex("^accessWidener\\s+v\\d+\\s+") + } + + @get:Inject + protected abstract val providers: ProviderFactory + + @get:Inject + protected abstract val projectLayout: ProjectLayout + + private val logger = lazy { Logging.getLogger(javaClass) } + + private lateinit var project: Project + private lateinit var extension: SmcmtkProjectExtension + + private var loomProxy = lazy { project.extensions.findByName("loom")?.let { SmcmtkLoomProxy(project, it)} } + + override fun apply(project: Project) { + this.project = project + this.extension = project.extensions.create("smcmtk", SmcmtkProjectExtension::class.java, this) + + val minecraftVersionDescriptor = providers.gradleProperty("minecraft.version.descriptor") + val minecraftProperties = minecraftVersionDescriptor + .flatMap { providers.fileContents(projectLayout.settingsDirectory.file("gradle/mc-$it/gradle.properties")).asBytes } + .map { Properties().apply { load(it.inputStream())} } + + extension.mcProps.convention(minecraftProperties.map { mapOf(*it.entries.map { entry -> entry.key.toString() to entry.value.toString() }.toTypedArray()) }) + + project.plugins.withId(LOOM_PLAIN_PLUGIN_ID) { + project.configurations.maybeCreate("namedElements") + .extendsFrom(project.configurations.getByName("apiElements")) + } + } + + fun configureMojangMappings() { + project.plugins.withId(LOOM_REMAP_PLUGIN_ID) { + val versionCatalogs = project.extensions.getByType(VersionCatalogsExtension::class.java) + val mcLibsCatalog = versionCatalogs.find("mcLibs").orElse(null) + val parchment = mcLibsCatalog?.findLibrary("parchment")?.orElse(null) + + loomProxy.value?.configureOfficialMojangMappings(parchment) + } + project.plugins.withId(LOOM_PLAIN_PLUGIN_ID) { + project.tasks.withType(ProcessResources::class.java).findByName("processResources")?.apply { + filesMatching("*.accesswidener") { + it.filter { line -> + if (line.startsWith("accessWidener")) { + line.replace("named", "official") + } else { + line + } + } + } + } + } + } + + fun createModConfigurations(sourceSets: Collection) { + project.plugins.withId(LOOM_REMAP_PLUGIN_ID) { + sourceSets.filter { it.name != "main" } + .forEach { sourceSet -> loomProxy.value?.createRemapConfiguration(sourceSet) } + } + project.plugins.withId(LOOM_PLAIN_PLUGIN_ID) { + sourceSets.forEach { sourceSet -> + val prefix = if (sourceSet.name == "main") "" else sourceSet.name + + MOD_BASE_CONFIGURATION_NAMES.forEach { baseConfigurationName -> + val configurationName = joinCamelCase(prefix, baseConfigurationName) + project.configurations.findByName(configurationName)?.let { baseConfiguration -> + val configuration = project.configurations + .maybeCreate(joinCamelCase("mod", configurationName)) + baseConfiguration.extendsFrom(configuration) + } + } + } + } + } + + fun configureAccessWidener(file: RegularFile) { + logger.value.debug("Configuring access widener {}", file) + if (!file.asFile.isFile) { + logger.value.debug("Skipping access widener configuration for non-existing file {}", file) + return + } + + val accessWidenerNamesType = if (project.plugins.hasPlugin(LOOM_PLAIN_PLUGIN_ID)) { + "official" + } else if (project.plugins.hasPlugin(LOOM_REMAP_PLUGIN_ID)) { + "named" + } else { + null + } + + if (accessWidenerNamesType != null) { + logger.value.info("Changing access widener names type of $file to $accessWidenerNamesType") + file.asFile.writeText(file.asFile.readText(Charsets.UTF_8).lines().joinToString("\n") { line -> + ACCESS_WIDENER_DECLARATION_PATTERN.matchAt(line, 0) + ?.let { match -> line.substring(match.range) + accessWidenerNamesType } + ?: line + }) + } else { + logger.value.warn("Could not determine access widener names type for $file") + } + + loomProxy.value?.setAccessWidenerPath(file) + } +} diff --git a/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/filter/JsonMergeFilterReader.kt b/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/filter/JsonMergeFilterReader.kt new file mode 100644 index 0000000..8820a06 --- /dev/null +++ b/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/filter/JsonMergeFilterReader.kt @@ -0,0 +1,73 @@ +package de.siphalor.minecraft_modding_toolkit.gradle.project_plugin.filter + +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import java.io.FilterReader +import java.io.Reader +import java.io.StringReader +import java.nio.CharBuffer + +class JsonMergeFilterReader(input: Reader) : FilterReader(input) { + companion object { + val GSON: Gson = GsonBuilder().setPrettyPrinting().disableHtmlEscaping().create() + } + + var merge: MutableMap = LinkedHashMap() + + val result = lazy { + val inputJson = GSON.fromJson(input, Any::class.java) + StringReader(GSON.toJson(update(inputJson, merge))) + } + + private fun update(input: Any?, update: Any?): Any? { + return if (input is Collection<*> && update is Collection<*>) { + ArrayList(input).apply { addAll(update) } + } else if (input is Map<*, *> && update is Map<*, *>) { + LinkedHashMap(input).apply { + update.forEach { (key, value) -> put(key, update(input[key], value)) } + } + } else { + update + } + } + + override fun read(): Int { + return result.value.read() + } + + override fun read(cbuf: CharArray?): Int { + return result.value.read(cbuf) + } + + override fun read(cbuf: CharArray?, off: Int, len: Int): Int { + return result.value.read(cbuf, off, len) + } + + override fun read(target: CharBuffer): Int { + return result.value.read(target) + } + + override fun skip(n: Long): Long { + return result.value.skip(n) + } + + override fun ready(): Boolean { + return result.value.ready() + } + + override fun markSupported(): Boolean { + return result.value.markSupported() + } + + override fun mark(readAheadLimit: Int) { + result.value.mark(readAheadLimit) + } + + override fun reset() { + result.value.reset() + } + + override fun close() { + result.value.close() + } +} diff --git a/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/util/GradleNameUtils.kt b/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/util/GradleNameUtils.kt new file mode 100644 index 0000000..c42c091 --- /dev/null +++ b/gradle-project-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/project_plugin/util/GradleNameUtils.kt @@ -0,0 +1,6 @@ +package de.siphalor.minecraft_modding_toolkit.gradle.project_plugin.util + +fun joinCamelCase(vararg words: String) = words + .joinToString("") { word -> word.replaceFirstChar { if (it.isLowerCase()) it.uppercaseChar() else it } } + .replaceFirstChar { it.lowercaseChar() } + diff --git a/gradle-settings-plugin/build.gradle.kts b/gradle-settings-plugin/build.gradle.kts new file mode 100644 index 0000000..adc5a19 --- /dev/null +++ b/gradle-settings-plugin/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + id("de.siphalor.smcmtk.plugin") +} + +description = "This is the settings plugin that serves as the main entrypoint for development with SMCMTK. " + + "It configures the cross-version structure, properties and dependencies." + +gradlePlugin { + val settingPlugin by plugins.creating { + id = "de.siphalor.minecraft-modding-toolkit.settings-plugin" + implementationClass = "de.siphalor.minecraft_modding_toolkit.gradle.settings_plugin.SmcmtkSettingsPlugin" + } +} diff --git a/gradle-settings-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/settings_plugin/SmcmtkManifest.kt b/gradle-settings-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/settings_plugin/SmcmtkManifest.kt new file mode 100644 index 0000000..866530b --- /dev/null +++ b/gradle-settings-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/settings_plugin/SmcmtkManifest.kt @@ -0,0 +1,12 @@ +package de.siphalor.minecraft_modding_toolkit.gradle.settings_plugin + +import org.jetbrains.annotations.ApiStatus + +@ApiStatus.Internal +class SmcmtkManifest private constructor(val version: String) { + companion object { + fun resolve(): SmcmtkManifest { + return SmcmtkManifest(javaClass.`package`.implementationVersion ?: "0.0.0") + } + } +} diff --git a/gradle-settings-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/settings_plugin/SmcmtkSettingsExtension.kt b/gradle-settings-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/settings_plugin/SmcmtkSettingsExtension.kt new file mode 100644 index 0000000..c6d5da8 --- /dev/null +++ b/gradle-settings-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/settings_plugin/SmcmtkSettingsExtension.kt @@ -0,0 +1,8 @@ +package de.siphalor.minecraft_modding_toolkit.gradle.settings_plugin + +import org.gradle.api.provider.Property + +abstract class SmcmtkSettingsExtension { + abstract val fabricLoomVersion: Property + abstract val jcyoVersion: Property +} diff --git a/gradle-settings-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/settings_plugin/SmcmtkSettingsPlugin.kt b/gradle-settings-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/settings_plugin/SmcmtkSettingsPlugin.kt new file mode 100644 index 0000000..3486713 --- /dev/null +++ b/gradle-settings-plugin/src/main/kotlin/de/siphalor/minecraft_modding_toolkit/gradle/settings_plugin/SmcmtkSettingsPlugin.kt @@ -0,0 +1,78 @@ +package de.siphalor.minecraft_modding_toolkit.gradle.settings_plugin + +import org.gradle.api.Plugin +import org.gradle.api.initialization.Settings +import org.gradle.api.logging.Logging +import org.gradle.api.model.ObjectFactory +import org.gradle.api.plugins.ExtraPropertiesExtension +import java.io.File +import java.util.* +import javax.inject.Inject + +abstract class SmcmtkSettingsPlugin : Plugin { + companion object { + private const val PROJECT_PLUGIN_ID = "de.siphalor.minecraft-modding-toolkit.project-plugin" + } + + @get:Inject + protected abstract val objectFactory: ObjectFactory + + private val logger = lazy { Logging.getLogger(javaClass) } + + override fun apply(settings: Settings) { + val gradleProperties = loadProperties(settings.rootDir.resolve("gradle.properties")) + val minecraftVersionDescriptor = gradleProperties["minecraft.version.descriptor"] + ?: error("Missing minecraft.version.descriptor in gradle.properties") + + val minecraftVersionDir = settings.rootDir.resolve("gradle/mc-$minecraftVersionDescriptor") + val minecraftVersionProperties = loadProperties(minecraftVersionDir.resolve("gradle.properties")) + val fabricLoom = minecraftVersionProperties["fabric.loom"] + + val extension = settings.extensions.create("smcmtk", SmcmtkSettingsExtension::class.java) + + val smcmtkManifest = SmcmtkManifest.resolve() + + val fabricLoomModule = when (fabricLoom) { + "plain" -> "net.fabricmc.fabric-loom" + "remap" -> "net.fabricmc.fabric-loom-remap" + else -> null + } + + if (fabricLoomModule != null) { + logger.value.info("Choosing Fabric Loom $fabricLoomModule") + } + + settings.pluginManagement.plugins { + it.id(PROJECT_PLUGIN_ID).version(smcmtkManifest.version) + } + settings.gradle.settingsEvaluated { + settings.dependencyResolutionManagement.versionCatalogs.create("mcLibs") { + it.from(objectFactory.fileCollection().from(minecraftVersionDir.resolve("mc.versions.toml"))) + + it.plugin("smcmtk", PROJECT_PLUGIN_ID) + .version(smcmtkManifest.version) + + fabricLoomModule?.let { loomModule -> + it.plugin("fabric-loom", loomModule).version(extension.fabricLoomVersion.get()) + } + } + } + if (fabricLoom == "plain") { + settings.gradle.allprojects { project -> + project.extensions.findByType(ExtraPropertiesExtension::class.java)?.apply { + // Loom uses the same jar for both plugin variants (plain and remap) and tries to determine + // which one is in use by checking the plugin manager. + // This doesn't seem to work when using convention plugins, so we're forcing the remapping off here. + project.extensions.extraProperties.set("fabric.loom.disableObfuscation", "true") + project.extensions.extraProperties.set("fabric.loom.dontRemap", "true") + } + } + } + } + + private fun loadProperties(file: File): Properties { + return Properties().apply { + load(file.inputStream()) + } + } +} diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..b06a80a --- /dev/null +++ b/gradle.properties @@ -0,0 +1,7 @@ +# Enable the build cache to save time by reusing outputs produced by other successful builds. +# https://docs.gradle.org/current/userguide/build_cache.html +org.gradle.caching=true +# Enable the configuration cache to reuse the build configuration and enable parallel task execution. +# (Note that some plugins may not yet be compatible with the configuration cache.) +# https://docs.gradle.org/current/userguide/configuration_cache.html +org.gradle.configuration-cache=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..c032dc7 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,11 @@ +[versions] +fabric-loom = "1.15-SNAPSHOT" +gson = "2.13.2" +kotlin = "2.3.20" + +[plugins] +kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } + +[libraries] +fabric-loom-remap = { group = "net.fabricmc.fabric-loom", name = "net.fabricmc.fabric-loom.gradle.plugin", version.ref = "fabric-loom" } +gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..d997cfc Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..dbc3ce4 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,7 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.0-bin.zip +networkTimeout=10000 +validateDistributionUrl=true +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..0262dcb --- /dev/null +++ b/gradlew @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright © 2015 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 +# + +############################################################################## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/b631911858264c0b6e4d6603d677ff5218766cee/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/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# 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 -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD=$JAVA_HOME/jre/sh/java + else + JAVACMD=$JAVA_HOME/bin/java + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD=java + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..c4bdd3a --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,93 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@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 ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..224488d --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1,14 @@ +dependencyResolutionManagement { + repositories { + mavenCentral() + maven { + name = "Fabric" + url = uri("https://maven.fabricmc.net/") + } + } +} + +include(":gradle-project-plugin") +include(":gradle-settings-plugin") + +rootProject.name = "smcmtk"