diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..3597edc --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @powercasgamer \ No newline at end of file diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..09f11ed --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,133 @@ + +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[INSERT CONTACT METHOD]. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations \ No newline at end of file diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..46ab584 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +github: powercasgamer +#patreon: # Replace with a single Patreon username +ko_fi: powercasgamer \ No newline at end of file diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index ab15f8d..ae662af 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -59,7 +59,7 @@ jobs: fi - name: Publish - if: ${{ runner.os == 'Linux' && env.STATUS != 'release' && github.event_name == 'push' && startsWith(github.ref, 'refs/heads/master/') && false }} + if: ${{ runner.os == 'Linux' && env.STATUS != 'release' && github.event_name == 'push' && startsWith(github.ref, 'refs/heads/master/') }} run: ./gradlew publish -x requireClean -x signMavenPublication env: ORG_GRADLE_PROJECT_mizuleUsername: ${{ secrets.MAVEN_USERNAME }} diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 01c3ebc..39a4926 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -1,24 +1,11 @@ -import com.diffplug.gradle.spotless.FormatExtension -import net.kyori.indra.licenser.spotless.HeaderFormat import java.util.* plugins { - id("org.jetbrains.kotlin.jvm") version "1.9.20" - id("com.github.johnrengelman.shadow") version "8.1.1" - id("net.kyori.indra") version "3.1.3" - id("net.kyori.indra.licenser.spotless") version "3.1.3" - id("net.kyori.indra.git") version "3.1.3" - id("org.jetbrains.gradle.plugin.idea-ext") version "1.1.7" - `java-library` + id("common-conventions") + id("kotlin-conventions") application } -repositories { - mavenCentral() - sonatype.s01Snapshots() - sonatype.ossSnapshots() -} - dependencies { implementation(kotlin("stdlib")) implementation(kotlin("reflect")) @@ -41,46 +28,6 @@ indra { mitLicense() } -spotless { - fun FormatExtension.applyCommon() { - trimTrailingWhitespace() - endWithNewline() - encoding("UTF-8") - toggleOffOn() - } - java { - importOrderFile(rootProject.file(".spotless/mizule.importorder")) - removeUnusedImports() - formatAnnotations() - applyCommon() - target("*/src/*/java/**/*.java") - } - kotlinGradle { - applyCommon() - ktlint("0.50.0") - } - kotlin { - applyCommon() - ktlint("0.50.0") - } -} - -indraSpotlessLicenser { - headerFormat(HeaderFormat.starSlash()) - licenseHeaderFile(rootProject.projectDir.resolve("HEADER")) - - val currentYear = Calendar.getInstance().apply { - time = Date() - }.get(Calendar.YEAR) - val createdYear = providers.gradleProperty("createdYear").map { it.toInt() }.getOrElse(currentYear) - val year = if (createdYear == currentYear) createdYear.toString() else "$createdYear-$currentYear" - - property("name", providers.gradleProperty("projectName").getOrElse("template")) - property("year", year) - property("description", project.description ?: "A template project") - property("author", providers.gradleProperty("projectAuthor").getOrElse("template")) -} - application { mainClass.set("dev.mizule.imagery.app.launcher.Launcher") } diff --git a/app/src/main/kotlin/dev/mizule/imagery/app/App.kt b/app/src/main/kotlin/dev/mizule/imagery/app/App.kt index 96d5be4..620aa43 100644 --- a/app/src/main/kotlin/dev/mizule/imagery/app/App.kt +++ b/app/src/main/kotlin/dev/mizule/imagery/app/App.kt @@ -53,7 +53,7 @@ import kotlin.io.path.outputStream private val logger = KotlinLogging.logger {} -class App(private val config: Config, usersConfigOption: String) { +class App(val config: Config, usersConfigOption: String) { private val scheduler = ConcurrencyUtil.executorService("Imagery Scheduler", true) private val storageDir = Path(config.storagePath) private val dataLoader = JacksonConfigurationLoader.builder() @@ -79,7 +79,7 @@ class App(private val config: Config, usersConfigOption: String) { it.router.ignoreTrailingSlashes = true it.useVirtualThreads = true it.contextResolver.ip = { ctx -> - ctx.header("CF-Connecting-IP") ?: ctx.req().remoteAddr + ctx.header(config.addressHeader) ?: ctx.req().remoteAddr } } @@ -161,12 +161,12 @@ class App(private val config: Config, usersConfigOption: String) { logger.info { "Shutting down..." } } + private fun getRandomString(length: Int = config.pathLength): String = + generateSequence(ALLOWED_CHARS::random).take(length).joinToString("") + companion object { private val MAPPER = jacksonObjectMapper() private val ALLOWED_CHARS = ('A'..'Z') + ('a'..'z') + ('0'..'9') - - fun getRandomString(length: Int = 8): String = - generateSequence(ALLOWED_CHARS::random).take(length).joinToString("") } data class FileCacheEntry(val file: UploadedFile, val path: Path) diff --git a/app/src/main/kotlin/dev/mizule/imagery/app/auth/AuthHandler.kt b/app/src/main/kotlin/dev/mizule/imagery/app/auth/AuthHandler.kt index ce2ac55..113f38a 100644 --- a/app/src/main/kotlin/dev/mizule/imagery/app/auth/AuthHandler.kt +++ b/app/src/main/kotlin/dev/mizule/imagery/app/auth/AuthHandler.kt @@ -1,3 +1,27 @@ +/* + * This file is part of Imagery, licensed under the MIT License. + * + * Copyright (c) 2023 powercas_gamer + * Copyright (c) 2023 contributors + * + * 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. + */ package dev.mizule.imagery.app.auth import dev.mizule.imagery.app.config.UserConfig diff --git a/app/src/main/kotlin/dev/mizule/imagery/app/auth/User.kt b/app/src/main/kotlin/dev/mizule/imagery/app/auth/User.kt index 80085a4..9a7fdd8 100644 --- a/app/src/main/kotlin/dev/mizule/imagery/app/auth/User.kt +++ b/app/src/main/kotlin/dev/mizule/imagery/app/auth/User.kt @@ -1,3 +1,27 @@ +/* + * This file is part of Imagery, licensed under the MIT License. + * + * Copyright (c) 2023 powercas_gamer + * Copyright (c) 2023 contributors + * + * 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. + */ package dev.mizule.imagery.app.auth import org.spongepowered.configurate.objectmapping.ConfigSerializable diff --git a/app/src/main/kotlin/dev/mizule/imagery/app/config/Config.kt b/app/src/main/kotlin/dev/mizule/imagery/app/config/Config.kt index 03bc228..9b7162e 100644 --- a/app/src/main/kotlin/dev/mizule/imagery/app/config/Config.kt +++ b/app/src/main/kotlin/dev/mizule/imagery/app/config/Config.kt @@ -40,4 +40,17 @@ data class Config( @Comment("The path to the uploaded file storage directory.") val storagePath: String = "./storage", + + @Comment("The length of the random generated path.") + val pathLength: Int = 8, + + @Comment(""" +Any kind of proxy services change real ip. +The origin ip should be available in one of the headers. +Nginx: X-Forwarded-For +Cloudflare: CF-Connecting-IP +Popular: X-Real-IP + """, + ) + val addressHeader: String = "CF-Connecting-IP", ) diff --git a/app/src/main/kotlin/dev/mizule/imagery/app/config/UserConfig.kt b/app/src/main/kotlin/dev/mizule/imagery/app/config/UserConfig.kt index 806f643..06449db 100644 --- a/app/src/main/kotlin/dev/mizule/imagery/app/config/UserConfig.kt +++ b/app/src/main/kotlin/dev/mizule/imagery/app/config/UserConfig.kt @@ -1,3 +1,27 @@ +/* + * This file is part of Imagery, licensed under the MIT License. + * + * Copyright (c) 2023 powercas_gamer + * Copyright (c) 2023 contributors + * + * 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. + */ package dev.mizule.imagery.app.config import dev.mizule.imagery.app.auth.User diff --git a/app/src/main/kotlin/dev/mizule/imagery/app/exceptions/FileNotFoundResponse.kt b/app/src/main/kotlin/dev/mizule/imagery/app/exceptions/FileNotFoundResponse.kt index c1e293c..04e8292 100644 --- a/app/src/main/kotlin/dev/mizule/imagery/app/exceptions/FileNotFoundResponse.kt +++ b/app/src/main/kotlin/dev/mizule/imagery/app/exceptions/FileNotFoundResponse.kt @@ -1,3 +1,27 @@ +/* + * This file is part of Imagery, licensed under the MIT License. + * + * Copyright (c) 2023 powercas_gamer + * Copyright (c) 2023 contributors + * + * 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. + */ package dev.mizule.imagery.app.exceptions import io.javalin.http.HttpResponseException diff --git a/app/src/main/kotlin/dev/mizule/imagery/app/model/ImageLookupResult.kt b/app/src/main/kotlin/dev/mizule/imagery/app/model/ImageLookupResult.kt index 61df8de..55b87c0 100644 --- a/app/src/main/kotlin/dev/mizule/imagery/app/model/ImageLookupResult.kt +++ b/app/src/main/kotlin/dev/mizule/imagery/app/model/ImageLookupResult.kt @@ -1,3 +1,27 @@ +/* + * This file is part of Imagery, licensed under the MIT License. + * + * Copyright (c) 2023 powercas_gamer + * Copyright (c) 2023 contributors + * + * 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. + */ package dev.mizule.imagery.app.model data class ImageLookupResult( diff --git a/app/src/main/kotlin/dev/mizule/imagery/app/model/Roles.kt b/app/src/main/kotlin/dev/mizule/imagery/app/model/Roles.kt index 9f28774..4698abb 100644 --- a/app/src/main/kotlin/dev/mizule/imagery/app/model/Roles.kt +++ b/app/src/main/kotlin/dev/mizule/imagery/app/model/Roles.kt @@ -1,3 +1,27 @@ +/* + * This file is part of Imagery, licensed under the MIT License. + * + * Copyright (c) 2023 powercas_gamer + * Copyright (c) 2023 contributors + * + * 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. + */ package dev.mizule.imagery.app.model import io.javalin.security.RouteRole diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts new file mode 100644 index 0000000..3ba36a4 --- /dev/null +++ b/build-logic/build.gradle.kts @@ -0,0 +1,36 @@ +plugins { + `kotlin-dsl` +} + +repositories { + gradlePluginPortal() + mavenCentral() +} + +dependencies { + compileOnly(files(libs::class.java.protectionDomain.codeSource.location)) + implementation(libs.indra.common) + implementation(libs.indra.git) + implementation(libs.indra.spotless) + implementation(libs.shadow) + implementation(libs.kotlin.gradle) + implementation(libs.kotlin.std) + implementation(libs.idea.gradle) + implementation(libs.gremlin.gradle) + implementation(libs.blossom) +} + +java { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 +} + +kotlin { + target { + compilations.configureEach { + kotlinOptions { + jvmTarget = "17" + } + } + } +} \ No newline at end of file diff --git a/build-logic/settings.gradle.kts b/build-logic/settings.gradle.kts new file mode 100644 index 0000000..b5a0fab --- /dev/null +++ b/build-logic/settings.gradle.kts @@ -0,0 +1,7 @@ +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../gradle/libs.versions.toml")) + } + } +} diff --git a/build-logic/src/main/kotlin/base-conventions.gradle.kts b/build-logic/src/main/kotlin/base-conventions.gradle.kts new file mode 100644 index 0000000..2ac76b9 --- /dev/null +++ b/build-logic/src/main/kotlin/base-conventions.gradle.kts @@ -0,0 +1,52 @@ +import net.kyori.indra.IndraExtension + +plugins { + id("net.kyori.indra") + id("org.jetbrains.gradle.plugin.idea-ext") + id("eclipse") + id("visual-studio") +} + +val libs = extensions.getByType(org.gradle.accessors.dm.LibrariesForLibs::class) + +group = rootProject.group +version = rootProject.version +description = rootProject.description + +repositories { + mavenCentral() + sonatype.s01Snapshots() + sonatype.ossSnapshots() +} + +extensions.configure(IndraExtension::class) { + gpl3OnlyLicense() + github(providers.gradleProperty("githubOrg").get(), providers.gradleProperty("githubRepo").get()) { + ci(true) + issues(true) + scm(true) + } + + configurePublications { + pom { + developers { + developer { + id.set("powercas_gamer") + name.set("Cas") + url.set("https://mizule.dev") + email.set("cas [at] mizule [dot] dev") + timezone.set("Europe/Amsterdam") + } + } + } + } +} + +tasks { + named("idea") { + notCompatibleWithConfigurationCache("https://github.com/gradle/gradle/issues/13480") + } + register("cleanAll", Delete::class) { + dependsOn("clean", "cleanIdea", "cleanVisualStudio", "cleanEclipse") + } +} \ No newline at end of file diff --git a/build-logic/src/main/kotlin/common-conventions.gradle.kts b/build-logic/src/main/kotlin/common-conventions.gradle.kts new file mode 100644 index 0000000..6d78aa7 --- /dev/null +++ b/build-logic/src/main/kotlin/common-conventions.gradle.kts @@ -0,0 +1,115 @@ +import com.diffplug.gradle.spotless.FormatExtension +import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCacheFileTransformer +import net.kyori.indra.licenser.spotless.HeaderFormat +import java.util.* + +plugins { + id("base-conventions") + id("net.kyori.indra") + id("net.kyori.indra.git") + id("net.kyori.indra.licenser.spotless") + id("com.github.johnrengelman.shadow") + id("java-library") +} + +//val libs = extensions.getByType(org.gradle.accessors.dm.LibrariesForLibs::class) + +//extensions.getByType(BasePluginExtension::class.java).archivesName.set(project.nameString()) + +indra { + javaVersions { + minimumToolchain(17) + target(17) + } + + publishSnapshotsTo("mizule", "https://repo.mizule.dev/snapshots") + publishReleasesTo("mizule", "https://repo.mizule.dev/releases") +} + +java { + withSourcesJar() + withJavadocJar() +} + +spotless { + fun FormatExtension.applyCommon() { + trimTrailingWhitespace() + endWithNewline() + encoding("UTF-8") + toggleOffOn() + } + java { + importOrderFile(rootProject.file(".spotless/mizule.importorder")) + removeUnusedImports() + formatAnnotations() + applyCommon() + target("*/src/*/java/**/*.java") + } + kotlinGradle { + applyCommon() + ktlint("0.50.0") + } + kotlin { + applyCommon() + ktlint("0.50.0") + } +} + +indraSpotlessLicenser { + headerFormat(HeaderFormat.starSlash()) + licenseHeaderFile(rootProject.projectDir.resolve("HEADER")) + + val currentYear = Calendar.getInstance().apply { + time = Date() + }.get(Calendar.YEAR) + val createdYear = providers.gradleProperty("createdYear").map { it.toInt() }.getOrElse(currentYear) + val year = if (createdYear == currentYear) createdYear.toString() else "$createdYear-$currentYear" + + property("name", providers.gradleProperty("projectName").getOrElse("template")) + property("year", year) + property("description", project.description ?: "A template project") + property("author", providers.gradleProperty("projectAuthor").getOrElse("template")) + +} + +tasks { + assemble { + dependsOn(shadowJar) + } + + shadowJar { + archiveClassifier.set("") + + mergeServiceFiles() + + transform(Log4j2PluginsCacheFileTransformer::class.java) + } + + jar { + archiveClassifier.set("unshaded") + from(rootProject.projectDir.resolve("LICENSE")) { + rename { "LICENSE_${providers.gradleProperty("projectName").getOrElse("template")}" } + } + } + + withType().configureEach { + options.isFork = true + options.isIncremental = true + options.encoding = "UTF-8" + options.compilerArgs.add("-parameters") + options.compilerArgs.add("-Xlint:-processing") + } + + withType().configureEach { + filteringCharset = "UTF-8" + duplicatesStrategy = DuplicatesStrategy.INCLUDE + } + + javadoc { + val options = options as? StandardJavadocDocletOptions ?: return@javadoc + options.isAuthor = true + options.encoding = "UTF-8" + options.charSet = "UTF-8" + options.linkSource(true) + } +} \ No newline at end of file diff --git a/build-logic/src/main/kotlin/kotlin-conventions.gradle.kts b/build-logic/src/main/kotlin/kotlin-conventions.gradle.kts new file mode 100644 index 0000000..85277de --- /dev/null +++ b/build-logic/src/main/kotlin/kotlin-conventions.gradle.kts @@ -0,0 +1,23 @@ +import org.jetbrains.kotlin.gradle.dsl.JvmTarget +import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension +import org.jetbrains.kotlin.gradle.dsl.KotlinVersion +import org.jetbrains.kotlin.gradle.dsl.kotlinExtension +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +plugins { + id("common-conventions") + kotlin("jvm") +} + +tasks { + withType(KotlinCompile::class).configureEach { + compilerOptions { + jvmTarget.set(JvmTarget.JVM_17) + languageVersion.set(KotlinVersion.KOTLIN_1_9) + } + } +} + +extensions.configure(KotlinProjectExtension::class) { + jvmToolchain(17) +} \ No newline at end of file diff --git a/build-logic/src/main/kotlin/parent-conventions.gradle.kts b/build-logic/src/main/kotlin/parent-conventions.gradle.kts new file mode 100644 index 0000000..9f7b6c7 --- /dev/null +++ b/build-logic/src/main/kotlin/parent-conventions.gradle.kts @@ -0,0 +1,3 @@ +plugins { + base +} \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..d33cdf0 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,3 @@ +plugins { + id("parent-conventions") +} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 0000000..81d8bc6 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,23 @@ +[plugins] + +[libraries] +# build-logic stuff +blossom = { module = "net.kyori:blossom", version.ref = "blossom" } +indra-common = { module = "net.kyori:indra-common", version.ref = "indra" } +indra-crossdoc = { module = "net.kyori:indra-crossdoc", version.ref = "indra" } +indra-spotless = { module = "net.kyori:indra-licenser-spotless", version.ref = "indra" } +indra-git = { module = "net.kyori:indra-git", version.ref = "indra" } +shadow = { module = "com.github.johnrengelman:shadow", version.ref = "shadow" } +kotlin-gradle = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } +kotlin-std = { module = "org.jetbrains.kotlin:kotlin-stdlib-jdk8", version.ref = "kotlin" } +idea-gradle = { module = "gradle.plugin.org.jetbrains.gradle.plugin.idea-ext:gradle-idea-ext", version.ref = "idea-gradle" } +gremlin-gradle = { module = "xyz.jpenilla:gremlin-gradle", version.ref = "gremlin" } +gremlin-runtime = { module = "xyz.jpenilla:gremlin-runtime", version.ref = "gremlin" } + +[versions] +indra = "3.1.3" +blossom = "2.1.0" +shadow = "8.1.1" +kotlin = "1.9.20" +gremlin = "0.0.3" +idea-gradle = "1.1.7" \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 8159ee0..1ad0c0e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,6 +1,12 @@ +pluginManagement { + includeBuild("build-logic") +} + plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" } +enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") + rootProject.name = "Imagery" include("app")