diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..0ed2aba --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,67 @@ +# This workflow will build a Java project with Gradle +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle + +name: Testing CI with Gradle + +on: + push: + pull_request: + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Build with Gradle + run: ./gradlew clean checkLicenses build + +# This workflow will build a Java project with Gradle +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle + +name: Build +on: + push: + branches: + - master + paths: + - 'gradle/**' + - 'src/**' + - 'build.gradle.kts' + - 'settings.gradle.kts' + - 'gradlew' + - 'gradlew.bat' + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + if: "!contains(github.event.commits[0].message, '[no-build]')" + steps: + - uses: "actions/checkout@v3.1.0" + - uses: "gradle/wrapper-validation-action@v1.0.5" + - name: Set up JDK + uses: "actions/setup-java@v3.9.0" + with: + distribution: temurin + java-version: 17 + cache: gradle + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Test with Gradle + run: ./gradlew test + - name: Build jar with Gradle + run: ./gradlew build + - name: Upload artifacts + uses: "actions/upload-artifact@v3.1.1" + with: + name: Gradle Galaxy + path: build/libs diff --git a/.github/workflows/build_pr.yml b/.github/workflows/build_pr.yml new file mode 100644 index 0000000..07e0c58 --- /dev/null +++ b/.github/workflows/build_pr.yml @@ -0,0 +1,39 @@ +# This workflow will build a Java project with Gradle +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-gradle + +name: Build [PR] +on: + pull_request: + paths: + - 'gradle/**' + - 'src/**' + - 'build.gradle.kts' + - 'settings.gradle.kts' + - 'gradlew' + - 'gradlew.bat' + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + if: "!contains(github.event.commits[0].message, '[no-build]')" + steps: + - uses: "actions/checkout@v3.1.0" + - uses: "gradle/wrapper-validation-action@v1.0.5" + - name: Set up JDK + uses: "actions/setup-java@v3.9.0" + with: + distribution: temurin + java-version: 17 + cache: gradle + - name: Grant execute permission for gradlew + run: chmod +x gradlew + - name: Test with Gradle + run: ./gradlew test + - name: Build jar with Gradle + run: ./gradlew build + - name: Upload artifacts + uses: "actions/upload-artifact@v3.1.1" + with: + name: Gradle Galaxy + path: build/libs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cb88fbc --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +# Intellij +.idea/ + +# Gradle +.gradle/ +build/ \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..05d2d70 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 srnyx + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..f72caff --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# Gradle Galaxy + +**WIP** A Gradle plugin to simplify the process of creating projects diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..a17c27b --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,98 @@ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + `kotlin-dsl` + `maven-publish` + `java-gradle-plugin` + kotlin("jvm") version "1.8.22" + id("org.jetbrains.dokka") version "1.8.20" + id("com.gradle.plugin-publish") version "1.2.0" +} + +group = "xyz.srnyx" +version = "1.0.0" +val pluginDescription: String = "A Gradle plugin to simplify the process of creating projects" +val vcs: String = "github.com/srnyx/${project.name}" + +tasks.withType { + sourceCompatibility = "1.8" + targetCompatibility = "1.8" + options.encoding = "UTF-8" +} + +tasks.withType { + kotlinOptions { + jvmTarget = "1.8" + } +} + +repositories { + mavenCentral() + gradlePluginPortal() +} + +dependencies { + implementation(gradleApi()) + implementation(kotlin("stdlib-jdk8")) + + // Plugins + compileOnly("io.github.gradle-nexus", "publish-plugin", "1.3.0") + compileOnly("org.jetbrains.dokka", "dokka-gradle-plugin", "1.8.20") + compileOnly("com.github.jengelman.gradle.plugins", "shadow", "6.1.0") + compileOnly("org.jetbrains.kotlin", "kotlin-gradle-plugin", "1.8.22") +} + +@Suppress("UnstableApiUsage") +gradlePlugin { + isAutomatedPublishing = true + website.set("https://${vcs}") + vcsUrl.set("https://${vcs}") + plugins { + create(project.name) { + id = "${project.group}.${project.name}" + implementationClass = "${project.group}.gradlegalaxy.GradleGalaxy" + version = project.version + displayName = "Gradle Galaxy Plugin" + description = pluginDescription + tags.set(listOf("srnyx", "minecraft", "spigot")) + } + } +} + +publishing { + publications { + create("pluginMaven") { + pom { + name.set("Gradle Galaxy") + description.set(pluginDescription) + url.set("https://${vcs}") + packaging = "jar" + + licenses { + license { + name.set("MIT License") + url.set("https://opensource.org/licenses/MIT") + } + } + + developers { + developer { + id.set("srnyx") + name.set("srnyx") + email.set("contact@srnyx.com") + url.set("https://srnyx.com") + organization.set("Venox Network") + organizationUrl.set("https://venox.network") + timezone.set("America/New_York") + } + } + + scm { + connection.set("scm:git:git://${vcs}git") + developerConnection.set("scm:git:ssh://${vcs}.git") + url.set("https://${vcs}") + } + } + } + } +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..ccebba7 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..37aef8d --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +networkTimeout=10000 +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..79a61d4 --- /dev/null +++ b/gradlew @@ -0,0 +1,244 @@ +#!/bin/sh + +# +# Copyright © 2015-2021 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. +# + +############################################################################## +# +# 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/HEAD/subprojects/plugins/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##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit + +# 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 "$*" +} >&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 + +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" && ! "$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=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=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" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + 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 + +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# 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..93e3f59 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,92 @@ +@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=. +@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. +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% 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..4eedf24 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "gradle-galaxy" diff --git a/src/main/kotlin/xyz/srnyx/gradlegalaxy/GradleGalaxy.kt b/src/main/kotlin/xyz/srnyx/gradlegalaxy/GradleGalaxy.kt new file mode 100644 index 0000000..cca9ac9 --- /dev/null +++ b/src/main/kotlin/xyz/srnyx/gradlegalaxy/GradleGalaxy.kt @@ -0,0 +1,9 @@ +package xyz.srnyx.gradlegalaxy + +import org.gradle.api.Plugin +import org.gradle.api.Project + +@Suppress("unused") +class GradleGalaxy : Plugin { + override fun apply(target: Project) = Unit +} \ No newline at end of file diff --git a/src/main/kotlin/xyz/srnyx/gradlegalaxy/annotations/Ignore.kt b/src/main/kotlin/xyz/srnyx/gradlegalaxy/annotations/Ignore.kt new file mode 100644 index 0000000..8b85d08 --- /dev/null +++ b/src/main/kotlin/xyz/srnyx/gradlegalaxy/annotations/Ignore.kt @@ -0,0 +1,17 @@ +package xyz.srnyx.gradlegalaxy.annotations + +/** + * Lets the IDE know that whatever this annotation is applied to is going to be used + */ +@Target( + AnnotationTarget.CLASS, + AnnotationTarget.PROPERTY, + AnnotationTarget.FIELD, + AnnotationTarget.CONSTRUCTOR, + AnnotationTarget.FUNCTION, + AnnotationTarget.FILE, + AnnotationTarget.VALUE_PARAMETER +) +@Retention(AnnotationRetention.SOURCE) +@Ignore +annotation class Ignore \ No newline at end of file diff --git a/src/main/kotlin/xyz/srnyx/gradlegalaxy/enums/PaperVersion.kt b/src/main/kotlin/xyz/srnyx/gradlegalaxy/enums/PaperVersion.kt new file mode 100644 index 0000000..364bd42 --- /dev/null +++ b/src/main/kotlin/xyz/srnyx/gradlegalaxy/enums/PaperVersion.kt @@ -0,0 +1,37 @@ +package xyz.srnyx.gradlegalaxy.enums + +import xyz.srnyx.gradlegalaxy.utility.SemanticVersion + + +/** + * An enum to represent the different group and artifact IDs for Paper versions + */ +enum class PaperVersion(val groupId: String, val artifactId: String) { + /** + * Minecraft versions below 1.9 + */ + BELOW_1_9("org.github.paperspigot", "paperspigot-api"), + /** + * Minecraft versions below 1.17 + */ + BELOW_1_17("com.destroystokyo.paper", "paper-api"), + /** + * Minecraft versions 1.17 and above + */ + REST("io.papermc.paper", "paper-api"); + + companion object { + /** + * Parses a version string to a [PaperVersion] + */ + fun parse(versionString: String): PaperVersion { + val version = SemanticVersion(versionString) + return when { + version.major != 1 -> REST + version.minor < 9 -> BELOW_1_9 + version.minor < 17 -> BELOW_1_17 + else -> REST + } + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/xyz/srnyx/gradlegalaxy/enums/Repository.kt b/src/main/kotlin/xyz/srnyx/gradlegalaxy/enums/Repository.kt new file mode 100644 index 0000000..0e175ee --- /dev/null +++ b/src/main/kotlin/xyz/srnyx/gradlegalaxy/enums/Repository.kt @@ -0,0 +1,140 @@ +package xyz.srnyx.gradlegalaxy.enums + +import org.gradle.api.artifacts.ArtifactRepositoryContainer +import org.gradle.api.artifacts.dsl.RepositoryHandler +import org.gradle.api.artifacts.repositories.MavenArtifactRepository + +import org.gradle.kotlin.dsl.maven + + +/** + * Enum class for popular repositories. Use with [mavenQuick] + */ +enum class Repository(internal val url: String) { + /** + * [ArtifactRepositoryContainer.MAVEN_CENTRAL_URL] + */ + MAVEN_CENTRAL(ArtifactRepositoryContainer.MAVEN_CENTRAL_URL), + /** + * [https://hub.spigotmc.org/nexus/content/repositories/snapshots/](https://hub.spigotmc.org/nexus/content/repositories/snapshots/) + */ + SPIGOT("https://hub.spigotmc.org/nexus/content/repositories/snapshots/"), + /** + * [https://repo.papermc.io/repository/maven-public/](https://repo.papermc.io/repository/maven-public/) + */ + PAPER("https://repo.papermc.io/repository/maven-public/"), + /** + * [https://jitpack.io/](https://jitpack.io/) + */ + JITPACK("https://jitpack.io/"), + /** + * [https://repo.clojars.org/](https://repo.clojars.org/) + */ + CLOJARS("https://repo.clojars.org/"), + /** + * [https://m2.dv8tion.net/releases/](https://m2.dv8tion.net/releases/) + */ + DV8TION("https://m2.dv8tion.net/releases/"), + /** + * [https://repo.triumphteam.dev/releases/](https://repo.triumphteam.dev/releases/) + */ + TRIUMPH_RELEASES("https://repo.triumphteam.dev/releases/"), + /** + * [https://repo.triumphteam.dev/snapshots/](https://repo.triumphteam.dev/snapshots/) + */ + TRIUMPH_SNAPSHOTS("https://repo.triumphteam.dev/snapshots/"), + /** + * [https://repo.viaversion.com/everything/](https://repo.viaversion.com/everything/) + */ + VIA_VERSION("https://repo.viaversion.com/everything/"), + /** + * [https://repo.dmulloy2.net/repository/public/](https://repo.dmulloy2.net/repository/public/) + */ + PROTOCOL_LIB("https://repo.dmulloy2.net/repository/public/"), + /** + * [https://nexus.scarsz.me/content/groups/public/](https://nexus.scarsz.me/content/groups/public/) + */ + SCARSZ("https://nexus.scarsz.me/content/groups/public/"), + /** + * [https://repo.codemc.org/repository/maven-public/](https://repo.codemc.org/repository/maven-public/) + */ + CODE_MC("https://repo.codemc.org/repository/maven-public/"), + /** + * [https://oss.sonatype.org/content/repositories/releases/](https://oss.sonatype.org/content/repositories/releases/) + */ + SONATYPE_RELEASES_OLD("https://oss.sonatype.org/content/repositories/releases/"), + /** + * [https://oss.sonatype.org/content/repositories/snapshots/](https://oss.sonatype.org/content/repositories/snapshots/) + */ + SONATYPE_SNAPSHOTS_OLD("https://oss.sonatype.org/content/repositories/snapshots/"), + /** + * [https://s01.oss.sonatype.org/content/repositories/releases/](https://s01.oss.sonatype.org/content/repositories/releases/) + */ + SONATYPE_RELEASES("https://s01.oss.sonatype.org/content/repositories/releases/"), + /** + * [https://s01.oss.sonatype.org/content/repositories/snapshots/](https://s01.oss.sonatype.org/content/repositories/snapshots/) + */ + SONATYPE_SNAPSHOTS("https://s01.oss.sonatype.org/content/repositories/snapshots/"), + /** + * [https://nexus.umbcraft.online/repository/umbcraft-pub/](https://nexus.umbcraft.online/repository/umbcraft-pub/) + */ + UMB_CRAFT("https://nexus.umbcraft.online/repository/umbcraft-pub/"), + /** + * [https://repo.extendedclip.com/content/repositories/placeholderapi/](https://repo.extendedclip.com/content/repositories/placeholderapi/) + */ + PLACEHOLDER_API("https://repo.extendedclip.com/content/repositories/placeholderapi/"), + /** + * [https://repo.alessiodp.com/releases/](https://repo.alessiodp.com/releases/) + */ + ALESSIO_DP("https://repo.alessiodp.com/releases/"), + /** + * [https://repo.onarandombox.com/content/groups/public/](https://repo.onarandombox.com/content/groups/public/) + */ + MULTIVERSE("https://repo.onarandombox.com/content/groups/public/"), + /** + * [https://repo.extendedclip.com/content/repositories/public/](https://repo.extendedclip.com/content/repositories/public/) + */ + EXTENDED_CLIP("https://repo.extendedclip.com/content/repositories/public/"), + /** + * [https://maven.enginehub.org/repo/](https://maven.enginehub.org/repo/) + */ + ENGINE_HUB("https://maven.enginehub.org/repo/"), + /** + * [https://redempt.dev/](https://redempt.dev/) + */ + REDEMPT("https://redempt.dev/"), + /** + * [https://repo.kryptonmc.org/releases/](https://repo.kryptonmc.org/releases/) + */ + KRYPTON_RELEASES("https://repo.kryptonmc.org/releases/"), + /** + * [https://repo.kryptonmc.org/snapshots/](https://repo.kryptonmc.org/snapshots/) + */ + KRYPTON_SNAPSHOTS("https://repo.kryptonmc.org/snapshots/"), + + // Keep these at the bottom as they include other dependencies of other repositories + /** + * [https://repo.essentialsx.net/releases/](https://repo.essentialsx.net/releases/) + */ + ESSENTIALS_RELEASES("https://repo.essentialsx.net/releases/"), + /** + * [https://repo.essentialsx.net/snapshots/](https://repo.essentialsx.net/snapshots/) + */ + ESSENTIALS_SNAPSHOTS("https://repo.essentialsx.net/snapshots/"), +} + +/** + * Quickly add a maven repository using the [Repository] enum + */ +fun RepositoryHandler.mavenQuick(vararg repositories: Repository): Map = + repositories.associateWith { + maven(it.url) + } + +/** + * Add all maven repositories in the [Repository] enum + */ +fun RepositoryHandler.mavenAll(vararg exclude: Repository): Map = + Repository.values().filterNot(exclude::contains).associateWith { + maven(it.url) + } \ No newline at end of file diff --git a/src/main/kotlin/xyz/srnyx/gradlegalaxy/enums/ShadowVersion.kt b/src/main/kotlin/xyz/srnyx/gradlegalaxy/enums/ShadowVersion.kt new file mode 100644 index 0000000..dedfbd0 --- /dev/null +++ b/src/main/kotlin/xyz/srnyx/gradlegalaxy/enums/ShadowVersion.kt @@ -0,0 +1,29 @@ +package xyz.srnyx.gradlegalaxy.enums + +import xyz.srnyx.gradlegalaxy.utility.SemanticVersion + + +/** + * An enum to represent the different group and artifact IDs for Shadow plugin versions + */ +enum class ShadowVersion(val groupId: String) { + BELOW_7_0_0("com.github.jengelman.gradle.plugins"), + BELOW_7_1_0("gradle.plugin.com.github.jengelman.gradle.plugins"), + BELOW_8_1_0("gradle.plugin.com.github.johnrengelman"), + REST("com.github.johnrengelman"); + + companion object { + /** + * Parses a version string to a [ShadowVersion] + */ + fun parse(versionString: String): ShadowVersion { + val version = SemanticVersion(versionString) + return when { + version.major < 7 -> BELOW_7_0_0 + version.minor < 1 -> BELOW_7_1_0 + version.major < 8 -> BELOW_8_1_0 + else -> REST + } + } + } +} diff --git a/src/main/kotlin/xyz/srnyx/gradlegalaxy/utility/Dependencies.kt b/src/main/kotlin/xyz/srnyx/gradlegalaxy/utility/Dependencies.kt new file mode 100644 index 0000000..a49f8ef --- /dev/null +++ b/src/main/kotlin/xyz/srnyx/gradlegalaxy/utility/Dependencies.kt @@ -0,0 +1,78 @@ +package xyz.srnyx.gradlegalaxy.utility + +import org.gradle.api.JavaVersion +import org.gradle.api.Project +import org.gradle.api.artifacts.dsl.DependencyHandler + +import xyz.srnyx.gradlegalaxy.annotations.Ignore +import xyz.srnyx.gradlegalaxy.enums.PaperVersion +import xyz.srnyx.gradlegalaxy.enums.Repository +import xyz.srnyx.gradlegalaxy.enums.mavenQuick + + +/** + * 1. Sets the Java version for the project depending on the version + * 2. Adds the [Repository.SONATYPE_SNAPSHOTS_OLD] repository if the version is 1.15 or below + * 3. Adds the [Repository.MAVEN_CENTRAL] and [Repository.SPIGOT] repositories + * 4. Adds the dependency (org.spigotmc:spigot-api:[getVersionString]) + */ +fun DependencyHandler.spigotAPI(project: Project? = null, versionString: String): String { + if (project != null) { + // Java version + getJavaVersionForMC(versionString)?.let { project.setJavaVersion(it) } + // Repositories + val version = SemanticVersion(versionString) + if (version.major <= 1 && version.minor <= 15) project.repositories.mavenQuick(Repository.SONATYPE_SNAPSHOTS_OLD) + project.repositories.mavenQuick(Repository.MAVEN_CENTRAL, Repository.SPIGOT) + } + // Dependency + return "org.spigotmc:spigot-api:${getVersionString(versionString)}" +} + +/** + * 1. Adds the [Repository.MAVEN_CENTRAL], maven local, and [Repository.SPIGOT] repositories + * 2. Adds the dependency (org.spigotmc:spigot:[getVersionString]) + */ +@Ignore +fun DependencyHandler.spigotNMS(project: Project? = null, versionString: String): String { + if (project != null) { + // Java version + getJavaVersionForMC(versionString)?.let { project.setJavaVersion(it) } + // Repositories + project.repositories.mavenQuick(Repository.MAVEN_CENTRAL, Repository.SPIGOT) + project.repositories.mavenLocal() + } + // Dependency + return "org.spigotmc:spigot:${getVersionString(versionString)}" +} + +/** + * 1. Adds the [Repository.MAVEN_CENTRAL], [Repository.SONATYPE_SNAPSHOTS_OLD], and [Repository.PAPER] repositories + * 2. Adds the dependency ([PaperVersion.groupId]:[PaperVersion.artifactId]:[version]-R0.1-SNAPSHOT) + */ +@Ignore +fun DependencyHandler.paper(version: String, project: Project? = null): String { + if (project != null) { + // Java version + getJavaVersionForMC(version)?.let { project.setJavaVersion(it) } + // Repositories + project.repositories.mavenQuick(Repository.MAVEN_CENTRAL, Repository.SONATYPE_SNAPSHOTS_OLD, Repository.PAPER) + } + // Dependency + val paperVersion: PaperVersion = PaperVersion.parse(version) + return "${paperVersion.groupId}:${paperVersion.artifactId}:${getVersionString(version)}" +} + +/** + * Returns the version string with `-R0.1-SNAPSHOT` appended to it + */ +fun getVersionString(version: String): String = "${version}-R0.1-SNAPSHOT" + +/** + * Returns the correct Java version that is required for the Minecraft version + */ +fun getJavaVersionForMC(minecraftVersion: String): JavaVersion? { + val version = SemanticVersion(minecraftVersion) + if (version.major != 1 || version.minor >= 18) return null + return JavaVersion.VERSION_1_8 +} \ No newline at end of file diff --git a/src/main/kotlin/xyz/srnyx/gradlegalaxy/utility/Scripts.kt b/src/main/kotlin/xyz/srnyx/gradlegalaxy/utility/Scripts.kt new file mode 100644 index 0000000..8346ebf --- /dev/null +++ b/src/main/kotlin/xyz/srnyx/gradlegalaxy/utility/Scripts.kt @@ -0,0 +1,237 @@ +package xyz.srnyx.gradlegalaxy.utility + +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + +import org.gradle.api.DefaultTask +import org.gradle.api.JavaVersion +import org.gradle.api.Project +import org.gradle.api.Task +import org.gradle.api.component.SoftwareComponent +import org.gradle.api.plugins.JavaPluginExtension +import org.gradle.api.publish.PublishingExtension +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.api.tasks.Copy +import org.gradle.api.tasks.compile.JavaCompile +import org.gradle.jvm.tasks.Jar +import org.gradle.kotlin.dsl.* + +import xyz.srnyx.gradlegalaxy.annotations.Ignore +import xyz.srnyx.gradlegalaxy.enums.Repository +import xyz.srnyx.gradlegalaxy.enums.ShadowVersion +import xyz.srnyx.gradlegalaxy.enums.mavenQuick + + +/** + * Checks if the Shadow plugin is applied + */ +fun Project.hasShadowPlugin(): Boolean = plugins.hasPlugin("com.github.johnrengelman.shadow") + +/** + * Gets the Java plugin extension + */ +fun Project.getJavaExtension(): JavaPluginExtension { + return extensions["java"] as JavaPluginExtension +} + +/** + * Sets the text encoding for the project + * + * @param encoding The encoding to set + */ +fun Project.setTextEncoding(encoding: String = "UTF-8") { + tasks.withType { options.encoding = encoding } +} + +/** + * Sets the Java version for the project + * + * @param javaVersion The java version to set (example: [JavaVersion.VERSION_1_8]) + */ +fun Project.setJavaVersion(javaVersion: JavaVersion = JavaVersion.VERSION_1_8) { + val java: JavaPluginExtension = getJavaExtension() + java.sourceCompatibility = javaVersion + java.targetCompatibility = javaVersion +} + +/** + * Sets the artifact/archive classifier for the JAR and Shadow JAR tasks + * + * @param classifier The classifier to set + */ +fun Project.setShadowArchiveClassifier(classifier: String = "") { + check(hasShadowPlugin()) { "Shadow plugin is not applied!" } + tasks.named("shadowJar") { archiveClassifier.set(classifier) } +} + +/** + * Adds the task that makes `gradle build` run `gradle shadowJar` + */ +fun Project.addBuildShadowTask() { + check(hasShadowPlugin()) { "Shadow plugin is not applied!" } + tasks.named("build") { dependsOn("shadowJar") } +} + +/** + * Adds the task that generates the Javadoc and sources jar files + * + * @param javadocClassifier The classifier for the Javadoc jar file + * @param sourcesClassifier The classifier for the sources jar file + */ +@Ignore +fun Project.addJavadocSourcesJars(javadocClassifier: String? = null, sourcesClassifier: String? = null) { + val java: JavaPluginExtension = getJavaExtension() + java.withJavadocJar() + java.withSourcesJar() + javadocClassifier?.let { tasks.named("javadocJar") { archiveClassifier.set(it) } } + sourcesClassifier?.let { tasks.named("sourcesJar") { archiveClassifier.set(it) } } +} + +/** + * Configures the ProcessResources [Task] to add replacements + * + * @param replacements A [Map] of all the replacements + */ +fun Project.addReplacementsTask(replacements: Map String> = mapOf( + "name" to name::toString, + "version" to version::toString +)) { + tasks.named("processResources") { + outputs.upToDateWhen { false } + filesMatching("**/*.yml") { expand(replacements) } + } +} + +/** + * Adds the specified compiler arguments to the project + */ +@Ignore +fun Project.addCompilerArgs(vararg args: String) { + tasks.withType { options.compilerArgs.addAll(args) } +} + +/** + * Relocates the specified package to the specified package + * + * @param from The package to relocate + * @param to The package to relocate to + */ +@Ignore +fun Project.relocate( + from: String, + to: String = "${project.group}.${project.name.lowercase().filter { char -> char.isLetterOrDigit() || char in "._" }}.libs.${from.split(".").last()}", +) { + check(hasShadowPlugin()) { "Shadow plugin is not applied!" } + tasks.named("shadowJar") { relocate(from, to) } +} + +/** + * Sets up a simple publishing configuration + * + * 1. Applies the `maven-publish` plugin + * 2. Creates a [MavenPublication] with the specified parameters + * 3. Configures the [MavenPublication] with the specified [configuration] + * + * @param groupId The group ID + * @param artifactId The artifact ID + * @param version The version + * @param component The [SoftwareComponent] to publish + * @param artifacts The artifacts to publish + * @param configuration The configuration of the [MavenPublication] + * + * @return The [MavenPublication] that was created + */ +@Ignore +inline fun Project.setupPublishing( + groupId: String? = null, + artifactId: String? = null, + version: String? = null, + component: SoftwareComponent? = components["java"], + artifacts: Collection = emptyList(), + crossinline configuration: MavenPublication.() -> Unit +): MavenPublication { + apply(plugin = "maven-publish") + return (extensions["publishing"] as PublishingExtension).publications.create("maven") { + groupId?.let { this.groupId = it } + artifactId?.let { this.artifactId = it } + version?.let { this.version = it } + component?.let { this.from(component) } + artifacts.forEach(this::artifact) + configuration() + } +} + +/** + * Sets up the project with the specified [group] and [version] for a simple Minecraft project + * + * Adds the text encoding, replacements, and build shadow task (if the Shadow plugin is applied) + * + * @param group The group of the project (example: `me.dkim19375`) + * @param version The version of the project (example: `1.0.0`) + * @param dependency The dependency to add to the project (using `compileOnly`) + * @param javaVersion The java version of the project (example: [JavaVersion.VERSION_1_8]) + * @param replacements The replacements for the [replacements task][addReplacementsTask] + * @param textEncoding The text encoding for the [text encoding task][setTextEncoding] + */ +@Ignore +fun Project.setupMC( + group: String, + version: String = "1.0.0", + dependency: String? = null, + javaVersion: JavaVersion? = null, + replacements: Map String>? = mapOf( + "name" to name::toString, + "version" to version::toString + ), + textEncoding: String? = "UTF-8", + artifactClassifier: String? = "", +) { + apply(plugin = "java") + this.group = group + this.version = version + dependency?.let { dependencies.add("compileOnly", it) } + javaVersion?.let(::setJavaVersion) + replacements?.let(::addReplacementsTask) + textEncoding?.let(::setTextEncoding) + if (hasShadowPlugin()) { + artifactClassifier?.let(::setShadowArchiveClassifier) + addBuildShadowTask() + } +} + +/** + * Sets up the project using Annoying API + * + * 1. Applies the shadow plugin with the specified [shadowVersion] + * 2. Calls [setupMC] with the specified parameters + * 3. Adds the [Repository.JITPACK] repository + * 4. Adds the Annoying API dependency (`implementation`) + * 5. Relocates Annoying API using [relocate] + */ +@Ignore +fun Project.setupAnnoyingAPI( + shadowVersion: String, + annoyingAPIVersion: String, + group: String, + version: String = "1.0.0", + dependency: String? = null, + javaVersion: JavaVersion? = null, + replacements: Map String>? = mapOf( + "name" to name::toString, + "version" to version::toString + ), + textEncoding: String? = "UTF-8", + artifactClassifier: String? = "", +) { + //TODO Apply the shadow plugin + buildscript { + repositories { gradlePluginPortal() } + dependencies { add("classpath", "${ShadowVersion.parse(shadowVersion).groupId}:shadow:$shadowVersion") } + } + apply(plugin = "com.github.johnrengelman.shadow") + + // Everything else + setupMC(group, version, dependency, javaVersion, replacements, textEncoding, artifactClassifier) + repositories { mavenQuick(Repository.JITPACK) } + dependencies { add("implementation", "xyz.srnyx:annoying-api:$annoyingAPIVersion") } + relocate("xyz.srnyx.annoyingapi") +} diff --git a/src/main/kotlin/xyz/srnyx/gradlegalaxy/utility/SemanticVersion.kt b/src/main/kotlin/xyz/srnyx/gradlegalaxy/utility/SemanticVersion.kt new file mode 100644 index 0000000..4297005 --- /dev/null +++ b/src/main/kotlin/xyz/srnyx/gradlegalaxy/utility/SemanticVersion.kt @@ -0,0 +1,68 @@ +package xyz.srnyx.gradlegalaxy.utility + +import java.lang.NumberFormatException + + +/** + * A class to represent a semantic version (example: `1.19.2`) + */ +class SemanticVersion(version: String) : Comparable { + /** + * The major version + */ + val major: Int + /** + * The minor version + */ + val minor: Int + /** + * The patch version + */ + val patch: Int + + init { + val versionSplit = version.split('.') + require(versionSplit.size >= 2) { "Failed to parse Minecraft version (invalid version string): $version" } + + // Get patch + try { + major = versionSplit[0].toInt() + minor = versionSplit[1].toInt() + patch = versionSplit.getOrElse(2) { "0" }.toInt() + } catch (e: NumberFormatException) { + throw IllegalArgumentException("Failed to parse Minecraft version (invalid values): $version") + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as SemanticVersion + + if (major != other.major) return false + if (minor != other.minor) return false + return patch == other.patch + } + + override fun hashCode(): Int { + var result = major + result = 31 * result + minor + result = 31 * result + patch + return result + } + + override fun toString(): String = "major.minor.patch" + + operator fun component1(): Int = major + + operator fun component2(): Int = minor + + operator fun component3(): Int = patch + + override operator fun compareTo(other: SemanticVersion): Int { + if (major != other.minor) return major.compareTo(other.major) + if (minor != other.minor) return minor.compareTo(other.minor) + return patch.compareTo(other.patch) + } +} \ No newline at end of file