commit 6c404a1b20ee37789f1686748928cd0aec702108 Author: shedaniel Date: Sat Oct 30 22:46:21 2021 +0800 Initial Commit diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..ccfa4a4 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,2 @@ +patreon: shedaniel +github: MaxNeedsSnacks \ No newline at end of file diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..fdcb1bb --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,40 @@ +name: Build and Release (1.17) + +on: + workflow_dispatch: + branches: + - master + +jobs: + validate-gradle: + name: "Validate Gradle wrapper" + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - uses: gradle/wrapper-validation-action@v1 + build: + name: "Build" + strategy: + matrix: + java: [ 16 ] # Build on Java 16 + runs-on: ubuntu-20.04 + steps: + - uses: actions/checkout@v2 + + - name: Set up JDK ${{ matrix.java }} + uses: actions/setup-java@v2 + with: + java-version: ${{ matrix.java }} + distribution: 'adopt' + + - name: Make gradlew executable + run: chmod +x ./gradlew + + - name: Build with Gradle + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + ./gradlew run --stacktrace --no-daemon diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ccb0c56 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +build/ +*.ipr +run/ +*.iws +out/ +*.iml +.gradle/ +output/ +bin/ +libs/ + +.classpath +.project +.idea/ +classes/ +.metadata +.vscode +.settings +*.launch \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..bc320a6 --- /dev/null +++ b/README.md @@ -0,0 +1,2 @@ +# Architectury Templates +Download the templates from the [GitHub Releases]() \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..3f81069 --- /dev/null +++ b/build.gradle @@ -0,0 +1,33 @@ +plugins { + id "org.jetbrains.kotlin.jvm" version "1.5.31" + id "org.jetbrains.kotlin.plugin.serialization" version "1.5.31" +} + +repositories { + mavenCentral() +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:1.5.31" + implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.0" + implementation "org.kohsuke:github-api:1.135" + implementation "org.dom4j:dom4j:2.1.3" +} + +task run(type: JavaExec, dependsOn: jar) { + mainClass = "dev.architectury.templates.GenerateTemplatesKt" + environment "CONFIG_PATH", file("generator.config.json").absolutePath + environment "OUTPUT_PATH", file("build/templates").absolutePath + environment "PUBLISH", "true" + environment "GITHUB_TOKEN", System.getenv("GITHUB_TOKEN") + environment "GITHUB_REPOSITORY", System.getenv("GITHUB_REPOSITORY") + classpath configurations.runtimeClasspath.files + jar.archiveFile +} + +task runLocal(type: JavaExec, dependsOn: jar) { + mainClass = "dev.architectury.templates.GenerateTemplatesKt" + environment "CONFIG_PATH", file("generator.config.json").absolutePath + environment "OUTPUT_PATH", file("build/templates").absolutePath + environment "PUBLISH", "false" + classpath configurations.runtimeClasspath.files + jar.archiveFile +} diff --git a/generator.config.json b/generator.config.json new file mode 100644 index 0000000..80c1a0f --- /dev/null +++ b/generator.config.json @@ -0,0 +1,96 @@ +{ + "global_tokens": { + "COMPILE_JAVA_8": "\n // The Minecraft launcher currently installs Java 8 for users, so your mod probably wants to target Java 8 too\n // JDK 9 introduced a new way of specifying this that will make sure no newer classes or methods are used.\n // We'll use that if it's available, but otherwise we'll use the older option.\n def targetVersion = 8\n if (JavaVersion.current().isJava9Compatible()) {\n options.release = targetVersion\n }", + "COMPILE_JAVA_16": " options.release = 16", + "FABRIC_LOADER": { + "filter": ".*", + "pom": "https://maven.fabricmc.net/net/fabricmc/fabric-loader/maven-metadata.xml" + } + }, + "versions": { + "1.16": { + "templates": [ + "templates/simple", + "templates/api_old" + ], + "tokens": { + "MINECRAFT": "1.16.5", + "COMPILE_JAVA": "#COMPILE_JAVA_8", + "FABRIC_LOADER": "#FABRIC_LOADER", + "LOOM_FORGE_EXT": "", + "MCMETA_FORMAT": "6", + "ARCHITECTURY_API": { + "filter": "1\\..*", + "pom": "https://maven.architectury.dev/me/shedaniel/architectury/maven-metadata.xml" + }, + "YARN_MAPPINGS": { + "filter": "1\\.16\\.5\\+build\\..*", + "pom": "https://maven.fabricmc.net/net/fabricmc/yarn/maven-metadata.xml" + }, + "FABRIC_API": { + "filter": ".*\\+1\\.16", + "pom": "https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api/maven-metadata.xml" + }, + "FORGE": { + "filter": "1\\.16\\.5-.*", + "pom": "https://maven.minecraftforge.net/net/minecraftforge/forge/maven-metadata.xml" + }, + "FORGE_LOADER_MAJOR": "36" + } + }, + "1.16-mixin": { + "templates": [ + "templates/simple", + "templates/api_old", + "templates/mixin" + ], + "inherit_tokens": "1.16", + "tokens": { + "MIXIN_COMPAT_LEVEL": "JAVA_8", + "LOOM_FORGE_EXT": "loom {\n forge {\n mixinConfig \"examplemod-common.mixins.json\"\n mixinConfig \"examplemod.mixins.json\"\n }\n}\n" + } + }, + "1.17": { + "templates": [ + "templates/simple", + "templates/api_new" + ], + "tokens": { + "MINECRAFT": "1.17.1", + "COMPILE_JAVA": "#COMPILE_JAVA_16", + "FABRIC_LOADER": "#FABRIC_LOADER", + "LOOM_FORGE_EXT": "", + "MCMETA_FORMAT": "7", + "ARCHITECTURY_API": { + "filter": "2\\..*", + "pom": "https://maven.architectury.dev/dev/architectury/architectury/maven-metadata.xml" + }, + "YARN_MAPPINGS": { + "filter": "1\\.17\\.1\\+build\\..*", + "pom": "https://maven.fabricmc.net/net/fabricmc/yarn/maven-metadata.xml" + }, + "FABRIC_API": { + "filter": ".*\\+1\\.17", + "pom": "https://maven.fabricmc.net/net/fabricmc/fabric-api/fabric-api/maven-metadata.xml" + }, + "FORGE": { + "filter": "1\\.17\\.1-.*", + "pom": "https://maven.minecraftforge.net/net/minecraftforge/forge/maven-metadata.xml" + }, + "FORGE_LOADER_MAJOR": "37" + } + }, + "1.17-mixin": { + "templates": [ + "templates/simple", + "templates/api_new", + "templates/mixin" + ], + "inherit_tokens": "1.17", + "tokens": { + "MIXIN_COMPAT_LEVEL": "JAVA_16", + "LOOM_FORGE_EXT": "loom {\n forge {\n mixinConfig \"examplemod-common.mixins.json\"\n mixinConfig \"examplemod.mixins.json\"\n }\n}\n" + } + } + } +} \ No newline at end of file diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..29e08e8 --- /dev/null +++ b/gradle.properties @@ -0,0 +1 @@ +kotlin.code.style=official \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..7454180 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..69a9715 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..744e882 --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or 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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# 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"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# 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 + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# 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" + which java >/dev/null 2>&1 || 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 + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@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 + +@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=. +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%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="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! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..fa752f8 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = "architectury-templates" + diff --git a/src/main/kotlin/dev/architectury/templates/GenerateTemplates.kt b/src/main/kotlin/dev/architectury/templates/GenerateTemplates.kt new file mode 100644 index 0000000..46fc442 --- /dev/null +++ b/src/main/kotlin/dev/architectury/templates/GenerateTemplates.kt @@ -0,0 +1,198 @@ +package dev.architectury.templates + +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonElement +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.JsonPrimitive +import kotlinx.serialization.json.jsonPrimitive +import org.dom4j.io.SAXReader +import org.kohsuke.github.GHRelease +import org.kohsuke.github.GitHubBuilder +import java.net.URL +import java.nio.file.Files +import java.nio.file.Paths +import java.util.zip.ZipEntry +import java.util.zip.ZipOutputStream +import kotlin.math.max + +val json = Json { + ignoreUnknownKeys = true + isLenient = true +} + +fun main() { + val configPath = Paths.get(System.getenv("CONFIG_PATH")) + val outputPath = Paths.get(System.getenv("OUTPUT_PATH")) + val publish = System.getenv("PUBLISH").toBooleanStrict() + outputPath.toFile().mkdirs() + outputPath.toFile().deleteRecursively() + outputPath.toFile().mkdirs() + val config = json.decodeFromString(TemplateConfig.serializer(), Files.readString(configPath)) + val cache = mutableMapOf() + var githubRelease: GHRelease? = null + if (publish) { + val github = GitHubBuilder().withOAuthToken(System.getenv("GITHUB_TOKEN")).build() + val repository = github.getRepository(System.getenv("GITHUB_REPOSITORY")) + githubRelease = repository.createRelease("release_" + System.getenv("GITHUB_JOB")) + .name("Architectury Templates") + .body(""" + |Architectury Templates can be used for setting your own architectury projects, for converting your existing projects to architectury projects, please refer to [Architectury Example Mod](https://github.com/architectury/architectury-example-mod) instead. + | + |The following templates are offered in [Creative Commons Zero v1.0 Universal](https://github.com/architectury/architectury-example-mod/blob/1.17.1/LICENSE), TL;DR: You can do anything with these templates. + | + |Architectury API is added to the templates by default, there are instructions on how to remove them within the buildscripts, depending on the API is **not required** to use the Architectury toolchain. + """.trimMargin()) + .create() + } + config.versions.forEach { (id, entry) -> + val outputZip = outputPath.resolve("$id.zip") + val toTransform = transformTokens(config, entry, cache) + ZipOutputStream(Files.newOutputStream(outputZip)).use { zipOutputStream -> + val entries = mutableMapOf() + entry.templates.map { Paths.get(it) }.forEach { templateDirPath -> + Files.walk(templateDirPath).filter { Files.isRegularFile(it) }.forEach { path -> + val pathName = templateDirPath.relativize(path).toString() + if (pathName.isTextFile) { + entries[pathName] = Files.readString(path).let { + var out = it + toTransform.forEach { (from, to) -> + out = out.replace(from, to) + } + out + }.encodeToByteArray() + } else { + entries[pathName] = Files.readAllBytes(path) + } + } + } + entries.forEach { (path, bytes) -> + zipOutputStream.putNextEntry(ZipEntry(path)) + zipOutputStream.write(bytes) + } + } + githubRelease?.uploadAsset(outputZip.toFile(), "application/zip") + } +} + +fun transformTokens(config: TemplateConfig, entry: TemplateEntry, cache: MutableMap): Map { + val map = mutableMapOf() + entry.inherit_tokens?.let { config.versions[it]!!.tokens }?.forEach { (token, element) -> + val replacement = element.findReplacement(config, cache) + println("Replacing @$token@ with $replacement") + map["@$token@"] = replacement + } + entry.tokens.forEach { (token, element) -> + val replacement = element.findReplacement(config, cache) + println("Replacing @$token@ with $replacement") + map["@$token@"] = replacement + } + return map +} + +private val String.isTextFile: Boolean + get() = listOf(".txt", ".gradle", ".java", ".kt", ".kts", ".gradle", ".groovy", ".properties", ".json").any { ext -> + endsWith(ext) + } + +private fun JsonElement.findReplacement(config: TemplateConfig, cache: MutableMap): String { + if (this is JsonPrimitive) { + if (this.content.startsWith("#")) { + return (config.global_tokens[this.content.substring(1)] ?: throw NullPointerException("Failed to find global token: ${this.content.substring(1)}")) + .findReplacement(config, cache) + } + return this.content + } else if (this is JsonObject) { + val url = this["pom"]!!.jsonPrimitive.content + val filter = this["filter"]!!.jsonPrimitive.content.toRegex() + val content = cache.getOrPut(url) { URL(url).readText() } + return SAXReader().read(content.reader()).rootElement + .element("versioning") + .element("versions") + .elementIterator("version") + .asSequence() + .filter { it.text.matches(filter) } + .mapNotNull { it.text.version } + .maxOrNull()?.version ?: throw NullPointerException("Failed to find version, with filter $filter from $url") + } + throw IllegalArgumentException("Unknown element type: $this") +} + +@Serializable +data class TemplateConfig( + val global_tokens: Map, + val versions: Map, +) + +@Serializable +data class TemplateEntry( + val templates: List, + val inherit_tokens: String? = null, + val tokens: Map, +) + +val String.version: Version? + get() { + return try { + versionNonNull + } catch (ignored: IllegalArgumentException) { + null + } + } + +val String.versionNonNull: Version + get() = Version(this) + +@JvmInline +value class Version(val version: String) : Comparable { + init { + require(version.matches("(\\d+(?:\\.\\d+)*)-?((?:.*)?)\\+?((?:.*)?)".toRegex())) { "Invalid version format" } + } + + data class VersionParts( + val version: String, + val snapshot: String, + val metadata: String, + ) + + val parts: VersionParts + get() { + return "(\\d+(?:\\.\\d+)*)-?((?:.*)?)\\+?((?:.*)?)".toRegex().matchEntire(version)!!.let { + val (version, snapshot, metadata) = it.destructured + VersionParts(version, snapshot, metadata) + } + } + + override operator fun compareTo(other: Version): Int { + val (thisVersion, thisSnapshot, thisMetadata) = parts + val (otherVersion, otherSnapshot, otherMetadata) = other.parts + val compare = compare(thisVersion, otherVersion) + if (compare != 0) { + return compare + } + return if (thisSnapshot == "") { + if (otherSnapshot == "") { + compare(thisMetadata, otherMetadata) + } else 1 + } else if (otherSnapshot == "") { + -1 + } else { + compare(thisSnapshot, otherSnapshot) + } + } + + fun compare(first: String, second: String): Int { + if (first.isEmpty() || second.isEmpty()) return 0 + fun String.toIntSafe(): Int = toIntOrNull() ?: 0 + val thisParts = first.split('.').toTypedArray() + val thatParts = second.split('.').toTypedArray() + val length = max(thisParts.size, thatParts.size) + for (i in 0 until length) { + val thisPart = if (i < thisParts.size) thisParts[i].toIntSafe() else 0 + val thatPart = if (i < thatParts.size) thatParts[i].toIntSafe() else 0 + if (thisPart < thatPart) return -1 + if (thisPart > thatPart) return 1 + } + return 0 + } +} diff --git a/src/test/kotlin/VersionTest.kt b/src/test/kotlin/VersionTest.kt new file mode 100644 index 0000000..0e415f7 --- /dev/null +++ b/src/test/kotlin/VersionTest.kt @@ -0,0 +1,6 @@ +import dev.architectury.templates.versionNonNull + +fun main() { + require("1.16.5".versionNonNull > "1.16.4".versionNonNull) + require("1.16.5+build.16".versionNonNull > "1.16.5+build.15".versionNonNull) +} \ No newline at end of file diff --git a/templates/api_new/common/src/main/java/net/examplemod/ExampleMod.java b/templates/api_new/common/src/main/java/net/examplemod/ExampleMod.java new file mode 100644 index 0000000..62a6ec7 --- /dev/null +++ b/templates/api_new/common/src/main/java/net/examplemod/ExampleMod.java @@ -0,0 +1,33 @@ +package net.examplemod; + +import com.google.common.base.Suppliers; +import dev.architectury.registry.CreativeTabRegistry; +import dev.architectury.registry.registries.DeferredRegister; +import dev.architectury.registry.registries.Registries; +import dev.architectury.registry.registries.RegistrySupplier; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; + +import java.util.function.Supplier; + +public class ExampleMod { + public static final String MOD_ID = "examplemod"; + // We can use this if we don't want to use DeferredRegister + public static final Supplier REGISTRIES = Suppliers.memoize(() -> Registries.get(MOD_ID)); + // Registering a new creative tab + public static final CreativeModeTab EXAMPLE_TAB = CreativeTabRegistry.create(new ResourceLocation(MOD_ID, "example_tab"), () -> + new ItemStack(ExampleMod.EXAMPLE_ITEM.get())); + + public static final DeferredRegister ITEMS = DeferredRegister.create(MOD_ID, Registry.ITEM_REGISTRY); + public static final RegistrySupplier EXAMPLE_ITEM = ITEMS.register("example_item", () -> + new Item(new Item.Properties().tab(ExampleMod.EXAMPLE_TAB))); + + public static void init() { + ITEMS.register(); + + System.out.println(ExampleExpectPlatform.getConfigDirectory().toAbsolutePath().normalize().toString()); + } +} diff --git a/templates/api_old/common/src/main/java/net/examplemod/ExampleMod.java b/templates/api_old/common/src/main/java/net/examplemod/ExampleMod.java new file mode 100644 index 0000000..1ffca2f --- /dev/null +++ b/templates/api_old/common/src/main/java/net/examplemod/ExampleMod.java @@ -0,0 +1,33 @@ +package net.examplemod; + +import me.shedaniel.architectury.registry.CreativeTabs; +import me.shedaniel.architectury.registry.DeferredRegister; +import me.shedaniel.architectury.registry.Registries; +import me.shedaniel.architectury.registry.RegistrySupplier; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.LazyLoadedValue; +import net.minecraft.world.item.CreativeModeTab; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; + +import java.util.function.Supplier; + +public class ExampleMod { + public static final String MOD_ID = "examplemod"; + // We can use this if we don't want to use DeferredRegister + public static final LazyLoadedValue REGISTRIES = new LazyLoadedValue<>(() -> Registries.get(MOD_ID)); + // Registering a new creative tab + public static final CreativeModeTab EXAMPLE_TAB = CreativeTabs.create(new ResourceLocation(MOD_ID, "example_tab"), () -> + new ItemStack(ExampleMod.EXAMPLE_ITEM.get())); + + public static final DeferredRegister ITEMS = DeferredRegister.create(MOD_ID, Registry.ITEM_REGISTRY); + public static final RegistrySupplier EXAMPLE_ITEM = ITEMS.register("example_item", () -> + new Item(new Item.Properties().tab(ExampleMod.EXAMPLE_TAB))); + + public static void init() { + ITEMS.register(); + + System.out.println(ExampleExpectPlatform.getConfigDirectory().toAbsolutePath().normalize().toString()); + } +} \ No newline at end of file diff --git a/templates/mixin/common/src/main/resources/examplemod-common.mixins.json b/templates/mixin/common/src/main/resources/examplemod-common.mixins.json new file mode 100644 index 0000000..9c4edb2 --- /dev/null +++ b/templates/mixin/common/src/main/resources/examplemod-common.mixins.json @@ -0,0 +1,12 @@ +{ + "required": true, + "package": "net.examplemod.mixin", + "compatibilityLevel": "@MIXIN_COMPAT_LEVEL@", + "client": [ + ], + "mixins": [ + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/templates/mixin/fabric/src/main/resources/examplemod.mixins.json b/templates/mixin/fabric/src/main/resources/examplemod.mixins.json new file mode 100644 index 0000000..810ff04 --- /dev/null +++ b/templates/mixin/fabric/src/main/resources/examplemod.mixins.json @@ -0,0 +1,13 @@ + +{ + "required": true, + "package": "net.examplemod.mixin.fabric", + "compatibilityLevel": "@MIXIN_COMPAT_LEVEL@", + "client": [ + ], + "mixins": [ + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/templates/mixin/forge/src/main/resources/examplemod.mixins.json b/templates/mixin/forge/src/main/resources/examplemod.mixins.json new file mode 100644 index 0000000..810ff04 --- /dev/null +++ b/templates/mixin/forge/src/main/resources/examplemod.mixins.json @@ -0,0 +1,13 @@ + +{ + "required": true, + "package": "net.examplemod.mixin.fabric", + "compatibilityLevel": "@MIXIN_COMPAT_LEVEL@", + "client": [ + ], + "mixins": [ + ], + "injectors": { + "defaultRequire": 1 + } +} \ No newline at end of file diff --git a/templates/simple/.gitignore b/templates/simple/.gitignore new file mode 100644 index 0000000..ccb0c56 --- /dev/null +++ b/templates/simple/.gitignore @@ -0,0 +1,19 @@ +build/ +*.ipr +run/ +*.iws +out/ +*.iml +.gradle/ +output/ +bin/ +libs/ + +.classpath +.project +.idea/ +classes/ +.metadata +.vscode +.settings +*.launch \ No newline at end of file diff --git a/templates/simple/build.gradle b/templates/simple/build.gradle new file mode 100644 index 0000000..2770a76 --- /dev/null +++ b/templates/simple/build.gradle @@ -0,0 +1,51 @@ +plugins { + id "architectury-plugin" version "3.4-SNAPSHOT" + id "dev.architectury.loom" version "0.10.0-SNAPSHOT" apply false +} + +architectury { + minecraft = rootProject.minecraft_version +} + +subprojects { + apply plugin: "dev.architectury.loom" + + loom { + silentMojangMappingsLicense() + } + + dependencies { + minecraft "com.mojang:minecraft:${rootProject.minecraft_version}" + // The following line declares the mojmap mappings, you may use other mappings as well + mappings loom.officialMojangMappings() + // The following line declares the yarn mappings you may select this one as well. + // mappings "net.fabricmc:yarn:@YARN_MAPPINGS@:v2" + } +} + +allprojects { + apply plugin: "java" + apply plugin: "architectury-plugin" + apply plugin: "maven-publish" + + archivesBaseName = rootProject.archives_base_name + version = rootProject.mod_version + group = rootProject.maven_group + + repositories { + // Add repositories to retrieve artifacts from in here. + // You should only use this when depending on other mods because + // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. + // See https://docs.gradle.org/current/userguide/declaring_repositories.html + // for more information about repositories. + } + + tasks.withType(JavaCompile) { + options.encoding = "UTF-8" +@COMPILE_JAVA@ + } + + java { + withSourcesJar() + } +} diff --git a/templates/simple/common/build.gradle b/templates/simple/common/build.gradle new file mode 100644 index 0000000..c253f86 --- /dev/null +++ b/templates/simple/common/build.gradle @@ -0,0 +1,25 @@ +dependencies { + // We depend on fabric loader here to use the fabric @Environment annotations and get the mixin dependencies + // Do NOT use other classes from fabric loader + modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + // Remove the next line if you don't want to depend on the API + modApi "dev.architectury:architectury:${rootProject.architectury_version}" +} + +architectury { + common() +} + +publishing { + publications { + mavenCommon(MavenPublication) { + artifactId = rootProject.archives_base_name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + } +} diff --git a/templates/simple/common/src/main/java/net/examplemod/ExampleExpectPlatform.java b/templates/simple/common/src/main/java/net/examplemod/ExampleExpectPlatform.java new file mode 100644 index 0000000..218cdd2 --- /dev/null +++ b/templates/simple/common/src/main/java/net/examplemod/ExampleExpectPlatform.java @@ -0,0 +1,25 @@ +package net.examplemod; + +import dev.architectury.injectables.annotations.ExpectPlatform; +import dev.architectury.platform.Platform; + +import java.nio.file.Path; + +public class ExampleExpectPlatform { + /** + * We can use {@link Platform#getConfigFolder()} but this is just an example of {@link ExpectPlatform}. + *

+ * This must be a public static method. The platform-implemented solution must be placed under a + * platform sub-package, with its class suffixed with {@code Impl}. + *

+ * Example: + * Expect: net.examplemod.ExampleExpectPlatform#getConfigDirectory() + * Actual Fabric: net.examplemod.fabric.ExampleExpectPlatformImpl#getConfigDirectory() + * Actual Forge: net.examplemod.forge.ExampleExpectPlatformImpl#getConfigDirectory() + */ + @ExpectPlatform + public static Path getConfigDirectory() { + // Just throw an error, the content should get replaced at runtime. + throw new AssertionError(); + } +} diff --git a/templates/simple/common/src/main/resources/assets/examplemod/lang/en_us.json b/templates/simple/common/src/main/resources/assets/examplemod/lang/en_us.json new file mode 100644 index 0000000..6bcd60e --- /dev/null +++ b/templates/simple/common/src/main/resources/assets/examplemod/lang/en_us.json @@ -0,0 +1,3 @@ +{ + "item.examplemod.example_item": "Example Item" +} \ No newline at end of file diff --git a/templates/simple/fabric/build.gradle b/templates/simple/fabric/build.gradle new file mode 100644 index 0000000..849f005 --- /dev/null +++ b/templates/simple/fabric/build.gradle @@ -0,0 +1,75 @@ +plugins { + id "com.github.johnrengelman.shadow" version "7.0.0" +} + +architectury { + platformSetupLoomIde() + fabric() +} + +configurations { + common + shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. + compileClasspath.extendsFrom common + runtimeClasspath.extendsFrom common + developmentFabric.extendsFrom common +} + +dependencies { + modImplementation "net.fabricmc:fabric-loader:${rootProject.fabric_loader_version}" + modApi "net.fabricmc.fabric-api:fabric-api:${rootProject.fabric_api_version}" + // Remove the next line if you don't want to depend on the API + modApi "dev.architectury:architectury-fabric:${rootProject.architectury_version}" + + common(project(path: ":common", configuration: "namedElements")) { transitive false } + shadowCommon(project(path: ":common", configuration: "transformProductionFabric")) { transitive false } +} + +processResources { + inputs.property "version", project.version + + filesMatching("fabric.mod.json") { + expand "version": project.version + } +} + +shadowJar { + configurations = [project.configurations.shadowCommon] + classifier "dev-shadow" +} + +remapJar { + input.set shadowJar.archiveFile + dependsOn shadowJar + classifier null +} + +jar { + classifier "dev" +} + +sourcesJar { + def commonSources = project(":common").sourcesJar + dependsOn commonSources + from commonSources.archiveFile.map { zipTree(it) } +} + +components.java { + withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + skip() + } +} + +publishing { + publications { + mavenFabric(MavenPublication) { + artifactId = rootProject.archives_base_name + "-" + project.name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + } +} diff --git a/templates/simple/fabric/src/main/java/net/examplemod/fabric/ExampleExpectPlatformImpl.java b/templates/simple/fabric/src/main/java/net/examplemod/fabric/ExampleExpectPlatformImpl.java new file mode 100644 index 0000000..29ba544 --- /dev/null +++ b/templates/simple/fabric/src/main/java/net/examplemod/fabric/ExampleExpectPlatformImpl.java @@ -0,0 +1,15 @@ +package net.examplemod.fabric; + +import net.examplemod.ExampleExpectPlatform; +import net.fabricmc.loader.api.FabricLoader; + +import java.nio.file.Path; + +public class ExampleExpectPlatformImpl { + /** + * This is our actual method to {@link ExampleExpectPlatform#getConfigDirectory()}. + */ + public static Path getConfigDirectory() { + return FabricLoader.getInstance().getConfigDir(); + } +} diff --git a/templates/simple/fabric/src/main/java/net/examplemod/fabric/ExampleModFabric.java b/templates/simple/fabric/src/main/java/net/examplemod/fabric/ExampleModFabric.java new file mode 100644 index 0000000..cd7e82e --- /dev/null +++ b/templates/simple/fabric/src/main/java/net/examplemod/fabric/ExampleModFabric.java @@ -0,0 +1,11 @@ +package net.examplemod.fabric; + +import net.examplemod.ExampleMod; +import net.fabricmc.api.ModInitializer; + +public class ExampleModFabric implements ModInitializer { + @Override + public void onInitialize() { + ExampleMod.init(); + } +} diff --git a/templates/simple/fabric/src/main/resources/fabric.mod.json b/templates/simple/fabric/src/main/resources/fabric.mod.json new file mode 100644 index 0000000..e58375d --- /dev/null +++ b/templates/simple/fabric/src/main/resources/fabric.mod.json @@ -0,0 +1,30 @@ +{ + "schemaVersion": 1, + "id": "examplemod", + "version": "${version}", + "name": "Example Mod", + "description": "This is an example description! Tell everyone what your mod is about!", + "authors": [ + "Me!" + ], + "contact": { + "homepage": "https://fabricmc.net/", + "sources": "https://github.com/FabricMC/fabric-example-mod" + }, + "license": "Insert License Here", + "icon": "assets/examplemod/icon.png", + "environment": "*", + "entrypoints": { + "main": [ + "net.examplemod.fabric.ExampleModFabric" + ] + }, + "depends": { + "fabric": "*", + "minecraft": ">=@MINECRAFT@", + "architectury": ">=@ARCHITECTURY_API@" + }, + "suggests": { + "flamingo": "*" + } +} \ No newline at end of file diff --git a/templates/simple/forge/build.gradle b/templates/simple/forge/build.gradle new file mode 100644 index 0000000..bc811b2 --- /dev/null +++ b/templates/simple/forge/build.gradle @@ -0,0 +1,76 @@ +plugins { + id "com.github.johnrengelman.shadow" version "7.0.0" +} +@LOOM_FORGE_EXT@ +architectury { + platformSetupLoomIde() + forge() +} + +configurations { + common + shadowCommon // Don't use shadow from the shadow plugin because we don't want IDEA to index this. + compileClasspath.extendsFrom common + runtimeClasspath.extendsFrom common + developmentForge.extendsFrom common +} + +dependencies { + forge "net.minecraftforge:forge:${rootProject.minecraft_version}-${rootProject.forge_version}" + // Remove the next line if you don't want to depend on the API + modApi "dev.architectury:architectury-forge:${rootProject.architectury_version}" + + common(project(path: ":common", configuration: "namedElements")) { transitive false } + shadowCommon(project(path: ":common", configuration: "transformProductionForge")) { transitive = false } +} + +processResources { + inputs.property "version", project.version + + filesMatching("META-INF/mods.toml") { + expand "version": project.version + } +} + +shadowJar { + exclude "fabric.mod.json" + + configurations = [project.configurations.shadowCommon] + classifier "dev-shadow" +} + +remapJar { + input.set shadowJar.archiveFile + dependsOn shadowJar + classifier null +} + +jar { + classifier "dev" +} + +sourcesJar { + def commonSources = project(":common").sourcesJar + dependsOn commonSources + from commonSources.archiveFile.map { zipTree(it) } +} + +components.java { + withVariantsFromConfiguration(project.configurations.shadowRuntimeElements) { + skip() + } +} + +publishing { + publications { + mavenForge(MavenPublication) { + artifactId = rootProject.archives_base_name + "-" + project.name + from components.java + } + } + + // See https://docs.gradle.org/current/userguide/publishing_maven.html for information on how to set up publishing. + repositories { + // Add repositories to publish to here. + } +} diff --git a/templates/simple/forge/gradle.properties b/templates/simple/forge/gradle.properties new file mode 100644 index 0000000..32f842a --- /dev/null +++ b/templates/simple/forge/gradle.properties @@ -0,0 +1 @@ +loom.platform=forge \ No newline at end of file diff --git a/templates/simple/forge/src/main/java/net/examplemod/forge/ExampleExpectPlatformImpl.java b/templates/simple/forge/src/main/java/net/examplemod/forge/ExampleExpectPlatformImpl.java new file mode 100644 index 0000000..9a64212 --- /dev/null +++ b/templates/simple/forge/src/main/java/net/examplemod/forge/ExampleExpectPlatformImpl.java @@ -0,0 +1,15 @@ +package net.examplemod.forge; + +import net.examplemod.ExampleExpectPlatform; +import net.minecraftforge.fml.loading.FMLPaths; + +import java.nio.file.Path; + +public class ExampleExpectPlatformImpl { + /** + * This is our actual method to {@link ExampleExpectPlatform#getConfigDirectory()}. + */ + public static Path getConfigDirectory() { + return FMLPaths.CONFIGDIR.get(); + } +} diff --git a/templates/simple/forge/src/main/java/net/examplemod/forge/ExampleModForge.java b/templates/simple/forge/src/main/java/net/examplemod/forge/ExampleModForge.java new file mode 100644 index 0000000..1d3329c --- /dev/null +++ b/templates/simple/forge/src/main/java/net/examplemod/forge/ExampleModForge.java @@ -0,0 +1,15 @@ +package net.examplemod.forge; + +import dev.architectury.platform.forge.EventBuses; +import net.examplemod.ExampleMod; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; + +@Mod(ExampleMod.MOD_ID) +public class ExampleModForge { + public ExampleModForge() { + // Submit our event bus to let architectury register our content on the right time + EventBuses.registerModEventBus(ExampleMod.MOD_ID, FMLJavaModLoadingContext.get().getModEventBus()); + ExampleMod.init(); + } +} diff --git a/templates/simple/forge/src/main/resources/META-INF/mods.toml b/templates/simple/forge/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..96d689e --- /dev/null +++ b/templates/simple/forge/src/main/resources/META-INF/mods.toml @@ -0,0 +1,35 @@ +modLoader = "javafml" +loaderVersion = "[@FORGE_LOADER_MAJOR@,)" +#issueTrackerURL = "" +license = "Insert License Here" + +[[mods]] +modId = "examplemod" +version = "${version}" +displayName = "Example Mod" +authors = "Me!" +description = ''' +This is an example description! Tell everyone what your mod is about! +''' +#logoFile = "" + +[[dependencies.examplemod]] +modId = "forge" +mandatory = true +versionRange = "[@FORGE_LOADER_MAJOR@,)" +ordering = "NONE" +side = "BOTH" + +[[dependencies.examplemod]] +modId = "minecraft" +mandatory = true +versionRange = "[@MINECRAFT@,)" +ordering = "NONE" +side = "BOTH" + +[[dependencies.examplemod]] +modId = "architectury" +mandatory = true +versionRange = "[@ARCHITECTURY_API@,)" +ordering = "AFTER" +side = "BOTH" \ No newline at end of file diff --git a/templates/simple/forge/src/main/resources/pack.mcmeta b/templates/simple/forge/src/main/resources/pack.mcmeta new file mode 100644 index 0000000..c1d8c85 --- /dev/null +++ b/templates/simple/forge/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "description": "Example Mod", + "pack_format": @MCMETA_FORMAT@ + } +} diff --git a/templates/simple/gradle.properties b/templates/simple/gradle.properties new file mode 100644 index 0000000..904db82 --- /dev/null +++ b/templates/simple/gradle.properties @@ -0,0 +1,14 @@ +org.gradle.jvmargs=-Xmx2048M + +minecraft_version=@MINECRAFT@ + +archives_base_name=examplemod +mod_version=1.0.0 +maven_group=net.examplemod + +architectury_version=@ARCHITECTURY_API@ + +fabric_loader_version=@FABRIC_LOADER@ +fabric_api_version=@FABRIC_API@ + +forge_version=@FORGE@ diff --git a/templates/simple/gradle/wrapper/gradle-wrapper.jar b/templates/simple/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..e708b1c Binary files /dev/null and b/templates/simple/gradle/wrapper/gradle-wrapper.jar differ diff --git a/templates/simple/gradle/wrapper/gradle-wrapper.properties b/templates/simple/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..0f80bbf --- /dev/null +++ b/templates/simple/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/templates/simple/gradlew b/templates/simple/gradlew new file mode 100755 index 0000000..4f906e0 --- /dev/null +++ b/templates/simple/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or 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. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# 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"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# 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 + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# 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" + which java >/dev/null 2>&1 || 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 + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/templates/simple/gradlew.bat b/templates/simple/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/templates/simple/gradlew.bat @@ -0,0 +1,89 @@ +@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 + +@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=. +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%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="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! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/templates/simple/settings.gradle b/templates/simple/settings.gradle new file mode 100644 index 0000000..ef13d26 --- /dev/null +++ b/templates/simple/settings.gradle @@ -0,0 +1,14 @@ +pluginManagement { + repositories { + maven { url "https://maven.fabricmc.net/" } + maven { url "https://maven.architectury.dev/" } + maven { url "https://maven.minecraftforge.net/" } + gradlePluginPortal() + } +} + +include("common") +include("fabric") +include("forge") + +rootProject.name = "architectury-example-mod"