1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-02-02 12:19:13 +00:00

Improve our version tooling

- Add a check to ensure declared dependencies in the :core project, and
   those inherited from Minecraft are the same.
 - Compute the next Cobalt version, rather than specifying it manually.
 - Add the gradle versions plugin (and version catalog update), and
   update some versions.
This commit is contained in:
Jonathan Coates 2023-12-19 18:12:21 +00:00
parent 39a5e40c92
commit 78bb3da58c
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
8 changed files with 162 additions and 26 deletions

View File

@ -13,6 +13,8 @@ plugins {
publishing publishing
alias(libs.plugins.taskTree) alias(libs.plugins.taskTree)
alias(libs.plugins.githubRelease) alias(libs.plugins.githubRelease)
alias(libs.plugins.gradleVersions)
alias(libs.plugins.versionCatalogUpdate)
id("org.jetbrains.gradle.plugin.idea-ext") id("org.jetbrains.gradle.plugin.idea-ext")
id("cc-tweaked") id("cc-tweaked")
} }
@ -102,3 +104,9 @@ idea.project.settings.compiler.javac {
} }
.toMap() .toMap()
} }
versionCatalogUpdate {
sortByKey.set(false)
pin { versions.addAll("fastutil", "guava", "netty", "slf4j") }
keep { keepUnusedLibraries.set(true) }
}

View File

@ -5,6 +5,8 @@
plugins { plugins {
`java-gradle-plugin` `java-gradle-plugin`
`kotlin-dsl` `kotlin-dsl`
alias(libs.plugins.gradleVersions)
alias(libs.plugins.versionCatalogUpdate)
} }
// Duplicated in settings.gradle.kts // Duplicated in settings.gradle.kts
@ -75,3 +77,9 @@ gradlePlugin {
} }
} }
} }
versionCatalogUpdate {
sortByKey.set(false)
keep { keepUnusedLibraries.set(true) }
catalogFile.set(file("../gradle/libs.versions.toml"))
}

View File

@ -76,6 +76,12 @@ dependencies {
val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs") val libs = project.extensions.getByType<VersionCatalogsExtension>().named("libs")
checkstyle(libs.findLibrary("checkstyle").get()) checkstyle(libs.findLibrary("checkstyle").get())
constraints {
checkstyle("org.codehaus.plexus:plexus-container-default:2.1.1") {
because("2.1.0 depends on deprecated Google collections module")
}
}
errorprone(libs.findLibrary("errorProne-core").get()) errorprone(libs.findLibrary("errorProne-core").get())
errorprone(libs.findLibrary("nullAway").get()) errorprone(libs.findLibrary("nullAway").get())
} }
@ -201,6 +207,7 @@ spotless {
val ktlintConfig = mapOf( val ktlintConfig = mapOf(
"ktlint_standard_no-wildcard-imports" to "disabled", "ktlint_standard_no-wildcard-imports" to "disabled",
"ktlint_standard_class-naming" to "disabled", "ktlint_standard_class-naming" to "disabled",
"ktlint_standard_function-naming" to "disabled",
"ij_kotlin_allow_trailing_comma" to "true", "ij_kotlin_allow_trailing_comma" to "true",
"ij_kotlin_allow_trailing_comma_on_call_site" to "true", "ij_kotlin_allow_trailing_comma_on_call_site" to "true",
) )

View File

@ -0,0 +1,72 @@
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.component.ModuleComponentIdentifier
import org.gradle.api.artifacts.component.ModuleComponentSelector
import org.gradle.api.artifacts.component.ProjectComponentIdentifier
import org.gradle.api.artifacts.result.DependencyResult
import org.gradle.api.artifacts.result.ResolvedDependencyResult
import org.gradle.api.provider.ListProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
import org.gradle.language.base.plugins.LifecycleBasePlugin
abstract class DependencyCheck : DefaultTask() {
@get:Input
abstract val configuration: ListProperty<Configuration>
init {
description = "Check :core's dependencies are consistent with Minecraft's."
group = LifecycleBasePlugin.VERIFICATION_GROUP
}
@TaskAction
fun run() {
var ok = true
for (configuration in configuration.get()) {
configuration.incoming.resolutionResult.allDependencies {
if (!check(this@allDependencies)) ok = false
}
}
if (!ok) {
throw GradleException("Mismatched versions in Minecraft dependencies. gradle/libs.versions.toml may need updating.")
}
}
private fun check(dependency: DependencyResult): Boolean {
if (dependency !is ResolvedDependencyResult) {
logger.warn("Found unexpected dependency result {}", dependency)
return false
}
// Skip dependencies on non-modules.
val requested = dependency.requested
if (requested !is ModuleComponentSelector) return true
// If this dependency is specified within some project (so is non-transitive), or is pulled in via Minecraft,
// then check for consistency.
// It would be nice to be smarter about transitive dependencies, but avoiding false positives is hard.
val from = dependency.from.id
if (
from is ProjectComponentIdentifier ||
from is ModuleComponentIdentifier && (from.group == "net.minecraft" || from.group == "io.netty")
) {
// If the version is different between the requested and selected version, report an error.
val selected = dependency.selected.moduleVersion!!.version
if (requested.version != selected) {
logger.error("Requested dependency {} (via {}) but got version {}", requested, from, selected)
return false
}
return true
}
return true
}
}

View File

@ -6,7 +6,6 @@ package cc.tweaked.gradle
import org.gradle.api.artifacts.dsl.DependencyHandler import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.file.FileSystemLocation import org.gradle.api.file.FileSystemLocation
import org.gradle.api.file.FileSystemLocationProperty
import org.gradle.api.provider.Property import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider import org.gradle.api.provider.Provider
import org.gradle.api.tasks.JavaExec import org.gradle.api.tasks.JavaExec
@ -129,3 +128,30 @@ fun <T> Property<T>.setProvider(provider: Provider<out T>) = set(provider)
/** Short-cut method to get the absolute path of a [FileSystemLocation] provider. */ /** Short-cut method to get the absolute path of a [FileSystemLocation] provider. */
fun Provider<out FileSystemLocation>.getAbsolutePath(): String = get().asFile.absolutePath fun Provider<out FileSystemLocation>.getAbsolutePath(): String = get().asFile.absolutePath
/**
* Get the version immediately after the provided version.
*
* For example, given "1.2.3", this will return "1.2.4".
*/
fun getNextVersion(version: String): String {
// Split a version like x.y.z-SNAPSHOT into x.y.z and -SNAPSHOT
val dashIndex = version.indexOf('-')
val mainVersion = if (dashIndex < 0) version else version.substring(0, dashIndex)
// Find the last component in x.y.z and increment it.
val lastIndex = mainVersion.lastIndexOf('.')
if (lastIndex < 0) throw IllegalArgumentException("Cannot parse version format \"$version\"")
val lastVersion = try {
version.substring(lastIndex + 1).toInt()
} catch (e: NumberFormatException) {
throw IllegalArgumentException("Cannot parse version format \"$version\"", e)
}
// Then append all components together.
val out = StringBuilder()
out.append(version, 0, lastIndex + 1)
out.append(lastVersion + 1)
if (dashIndex >= 0) out.append(version, dashIndex, version.length)
return out.toString()
}

View File

@ -109,6 +109,15 @@ class MinecraftConfigurations private constructor(private val project: Project)
project.extensions.configure(CCTweakedExtension::class.java) { project.extensions.configure(CCTweakedExtension::class.java) {
sourceDirectories.add(SourceSetReference.internal(client)) sourceDirectories.add(SourceSetReference.internal(client))
} }
// Register a task to check there are no conflicts with the core project.
val checkDependencyConsistency =
project.tasks.register("checkDependencyConsistency", DependencyCheck::class.java) {
// We need to check both the main and client classpath *configurations*, as the actual configuration
configuration.add(configurations.named(main.runtimeClasspathConfigurationName))
configuration.add(configurations.named(client.runtimeClasspathConfigurationName))
}
project.tasks.named("check") { dependsOn(checkDependencyConsistency) }
} }
private fun setupOutgoing(sourceSet: SourceSet, suffix: String = "") { private fun setupOutgoing(sourceSet: SourceSet, suffix: String = "") {

View File

@ -10,28 +10,29 @@
fabric-api = "0.86.1+1.20.1" fabric-api = "0.86.1+1.20.1"
fabric-loader = "0.14.21" fabric-loader = "0.14.21"
forge = "47.1.0" forge = "47.1.0"
forgeSpi = "6.0.0" forgeSpi = "7.0.1"
mixin = "0.8.5" mixin = "0.8.5"
parchment = "2023.08.20" parchment = "2023.08.20"
parchmentMc = "1.20.1" parchmentMc = "1.20.1"
# Normal dependencies # Core dependencies (these versions are tied to the version Minecraft uses)
asm = "9.5"
autoService = "1.1.1"
checkerFramework = "3.32.0"
cobalt = "0.8.1"
cobalt-next = "0.8.2" # Not a real version, used to constrain the version we accept.
commonsCli = "1.3.1"
fastutil = "8.5.9" fastutil = "8.5.9"
guava = "31.1-jre" guava = "31.1-jre"
jetbrainsAnnotations = "24.0.1" netty = "4.1.82.Final"
slf4j = "2.0.1"
# Core dependencies (independent of Minecraft)
asm = "9.6"
autoService = "1.1.1"
checkerFramework = "3.42.0"
cobalt = "0.8.1"
commonsCli = "1.6.0"
jetbrainsAnnotations = "24.1.0"
jsr305 = "3.0.2" jsr305 = "3.0.2"
jzlib = "1.1.3" jzlib = "1.1.3"
kotlin = "1.8.10" kotlin = "1.9.21"
kotlin-coroutines = "1.6.4" kotlin-coroutines = "1.7.3"
netty = "4.1.82.Final"
nightConfig = "3.6.7" nightConfig = "3.6.7"
slf4j = "2.0.1"
# Minecraft mods # Minecraft mods
emi = "1.0.8+1.20.1" emi = "1.0.8+1.20.1"
@ -47,29 +48,31 @@ sodium = "mc1.20-0.4.10"
# Testing # Testing
hamcrest = "2.2" hamcrest = "2.2"
jqwik = "1.7.4" jqwik = "1.8.2"
junit = "5.10.0" junit = "5.10.1"
# Build tools # Build tools
cctJavadoc = "1.8.2" cctJavadoc = "1.8.2"
checkstyle = "10.12.3" checkstyle = "10.12.6"
curseForgeGradle = "1.0.14" curseForgeGradle = "1.0.14"
errorProne-core = "2.21.1" errorProne-core = "2.23.0"
errorProne-plugin = "3.1.0" errorProne-plugin = "3.1.0"
fabric-loom = "1.3.7" fabric-loom = "1.3.9"
forgeGradle = "6.0.8" forgeGradle = "6.0.8"
githubRelease = "2.4.1" githubRelease = "2.5.2"
gradleVersions = "0.50.0"
ideaExt = "1.1.7" ideaExt = "1.1.7"
illuaminate = "0.1.0-44-g9ee0055" illuaminate = "0.1.0-44-g9ee0055"
librarian = "1.+" librarian = "1.+"
lwjgl = "3.3.1" lwjgl = "3.3.3"
minotaur = "2.+" minotaur = "2.+"
mixinGradle = "0.7.+" mixinGradle = "0.7.38"
nullAway = "0.9.9" nullAway = "0.9.9"
spotless = "6.21.0" spotless = "6.23.3"
taskTree = "2.1.1" taskTree = "2.1.1"
teavm = "0.10.0-SQUID.2" teavm = "0.10.0-SQUID.2"
vanillaGradle = "0.2.1-SNAPSHOT" vanillaGradle = "0.2.1-SNAPSHOT"
versionCatalogUpdate = "0.8.1"
vineflower = "1.11.0" vineflower = "1.11.0"
[libraries] [libraries]
@ -162,10 +165,12 @@ vineflower = { module = "io.github.juuxel:loom-vineflower", version.ref = "vinef
[plugins] [plugins]
forgeGradle = { id = "net.minecraftforge.gradle", version.ref = "forgeGradle" } forgeGradle = { id = "net.minecraftforge.gradle", version.ref = "forgeGradle" }
githubRelease = { id = "com.github.breadmoirai.github-release", version.ref = "githubRelease" } githubRelease = { id = "com.github.breadmoirai.github-release", version.ref = "githubRelease" }
gradleVersions = { id = "com.github.ben-manes.versions", version.ref = "gradleVersions" }
kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
librarian = { id = "org.parchmentmc.librarian.forgegradle", version.ref = "librarian" } librarian = { id = "org.parchmentmc.librarian.forgegradle", version.ref = "librarian" }
mixinGradle = { id = "org.spongepowered.mixin", version.ref = "mixinGradle" } mixinGradle = { id = "org.spongepowered.mixin", version.ref = "mixinGradle" }
taskTree = { id = "com.dorongold.task-tree", version.ref = "taskTree" } taskTree = { id = "com.dorongold.task-tree", version.ref = "taskTree" }
versionCatalogUpdate = { id = "nl.littlerobots.version-catalog-update", version.ref = "versionCatalogUpdate" }
[bundles] [bundles]
annotations = ["jsr305", "checkerFramework", "jetbrainsAnnotations"] annotations = ["jsr305", "checkerFramework", "jetbrainsAnnotations"]
@ -184,5 +189,5 @@ test = ["junit-jupiter-api", "junit-jupiter-params", "hamcrest", "jqwik-api"]
testRuntime = ["junit-jupiter-engine", "jqwik-engine"] testRuntime = ["junit-jupiter-engine", "jqwik-engine"]
# Build tools # Build tools
teavm-api = [ "teavm-jso", "teavm-jso-apis", "teavm-platform", "teavm-classlib", "teavm-metaprogramming-api" ] teavm-api = ["teavm-jso", "teavm-jso-apis", "teavm-platform", "teavm-classlib", "teavm-metaprogramming-api"]
teavm-tooling = [ "teavm-tooling", "teavm-metaprogramming-impl", "teavm-jso-impl" ] teavm-tooling = ["teavm-tooling", "teavm-metaprogramming-impl", "teavm-jso-impl"]

View File

@ -136,7 +136,8 @@ dependencies {
implementation(project(":core")) { cct.exclude(this) } implementation(project(":core")) { cct.exclude(this) }
minecraftEmbed(libs.cobalt) { minecraftEmbed(libs.cobalt) {
jarJar.ranged(this, "[${libs.versions.cobalt.asProvider().get()},${libs.versions.cobalt.next.get()})") val version = libs.versions.cobalt.get()
jarJar.ranged(this, "[$version,${getNextVersion(version)})")
} }
minecraftEmbed(libs.jzlib) { minecraftEmbed(libs.jzlib) {
jarJar.ranged(this, "[${libs.versions.jzlib.get()},)") jarJar.ranged(this, "[${libs.versions.jzlib.get()},)")