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

More Gradle cleanup

Mostly configuration cache support. And an aborted attempt at updating
spotless, which just resulted in a bunch of ktlint issues :/.
This commit is contained in:
Jonathan Coates 2025-01-13 21:54:20 +00:00
parent ef0af67e96
commit 8204944b5f
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
16 changed files with 87 additions and 145 deletions

View File

@ -18,11 +18,6 @@ ij_any_if_brace_force = if_multiline
ij_any_for_brace_force = if_multiline
ij_any_spaces_within_array_initializer_braces = true
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = true
ij_kotlin_method_parameters_wrap = off
ij_kotlin_call_parameters_wrap = off
[*.md]
trim_trailing_whitespace = false
@ -31,3 +26,16 @@ indent_size = 2
[*.yml]
indent_size = 2
[{*.kt,*.kts}]
ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL
ij_kotlin_continuation_indent_size = 4
ij_kotlin_spaces_around_equality_operators = true
ij_kotlin_allow_trailing_comma = true
ij_kotlin_allow_trailing_comma_on_call_site = true
# Prefer to handle these manually
ij_kotlin_method_parameters_wrap = off
ij_kotlin_call_parameters_wrap = off
ij_kotlin_extends_list_wrap = off

1
.gitignore vendored
View File

@ -27,6 +27,7 @@
*.iml
.idea
.gradle
.kotlin
*.DS_Store
/.classpath

View File

@ -220,6 +220,5 @@ idea.module {
// Force Gradle to write to inherit the output directory from the parent, instead of writing to out/xxx/classes.
// This is required for Loom, and we patch Forge's run configurations to work there.
// TODO: Submit a patch to Forge to support ProjectRootManager.
inheritOutputDirs = true
}

View File

@ -11,13 +11,10 @@ import org.gradle.api.NamedDomainObjectProvider
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Dependency
import org.gradle.api.attributes.TestSuiteType
import org.gradle.api.file.FileSystemOperations
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.provider.ListProperty
import org.gradle.api.provider.Provider
import org.gradle.api.provider.SetProperty
import org.gradle.api.reporting.ReportingExtension
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.bundling.Jar
import org.gradle.api.tasks.compile.JavaCompile
@ -25,7 +22,6 @@ import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.language.base.plugins.LifecycleBasePlugin
import org.gradle.language.jvm.tasks.ProcessResources
import org.gradle.process.JavaForkOptions
import org.gradle.testing.jacoco.plugins.JacocoCoverageReport
import org.gradle.testing.jacoco.plugins.JacocoPluginExtension
import org.gradle.testing.jacoco.plugins.JacocoTaskExtension
import org.gradle.testing.jacoco.tasks.JacocoReport
@ -36,10 +32,7 @@ import java.io.IOException
import java.net.URI
import java.util.regex.Pattern
abstract class CCTweakedExtension(
private val project: Project,
private val fs: FileSystemOperations,
) {
abstract class CCTweakedExtension(private val project: Project) {
/** Get the current git branch. */
val gitBranch: Provider<String> =
gitProvider("<no git branch>", listOf("rev-parse", "--abbrev-ref", "HEAD")) { it.trim() }
@ -64,17 +57,11 @@ abstract class CCTweakedExtension(
*/
val sourceDirectories: SetProperty<SourceSetReference> = project.objects.setProperty(SourceSetReference::class.java)
/**
* Dependencies excluded from published artifacts.
*/
internal val excludedDeps: ListProperty<Dependency> = project.objects.listProperty(Dependency::class.java)
/** All source sets referenced by this project. */
val sourceSets = sourceDirectories.map { x -> x.map { it.sourceSet } }
init {
sourceDirectories.finalizeValueOnRead()
excludedDeps.finalizeValueOnRead()
project.afterEvaluate { sourceDirectories.disallowChanges() }
}
@ -169,23 +156,18 @@ abstract class CCTweakedExtension(
}
fun <T> jacoco(task: NamedDomainObjectProvider<T>) where T : Task, T : JavaForkOptions {
val classDump = project.layout.buildDirectory.dir("jacocoClassDump/${task.name}")
val reportTaskName = "jacoco${task.name.capitalise()}Report"
val jacoco = project.extensions.getByType(JacocoPluginExtension::class.java)
task.configure {
finalizedBy(reportTaskName)
doFirst("Clean class dump directory") { fs.delete { delete(classDump) } }
jacoco.applyTo(this)
extensions.configure(JacocoTaskExtension::class.java) {
includes = listOf("dan200.computercraft.*")
classDumpDir = classDump.get().asFile
// Older versions of modlauncher don't include a protection domain (and thus no code
// source). Jacoco skips such classes by default, so we need to explicitly include them.
isIncludeNoLocationClasses = true
extensions.configure(JacocoTaskExtension::class.java) {
excludes = listOf(
"dan200.computercraft.mixin.*", // Exclude mixins, as they're not executed at runtime.
"dan200.computercraft.shared.Capabilities$*", // Exclude capability tokens, as Forge rewrites them.
)
}
}
@ -194,15 +176,11 @@ abstract class CCTweakedExtension(
description = "Generates code coverage report for the ${task.name} task."
executionData(task.get())
classDirectories.from(classDump)
// Don't want to use sourceSets(...) here as we have a custom class directory.
for (ref in sourceSets.get()) sourceDirectories.from(ref.allSource.sourceDirectories)
}
project.extensions.configure(ReportingExtension::class.java) {
reports.register("${task.name}CodeCoverageReport", JacocoCoverageReport::class.java) {
testType.set(TestSuiteType.INTEGRATION_TEST)
// Don't want to use sourceSets(...) here as we don't use all class directories.
for (ref in this@CCTweakedExtension.sourceDirectories.get()) {
sourceDirectories.from(ref.sourceSet.allSource.sourceDirectories)
if (ref.classes) classDirectories.from(ref.sourceSet.output)
}
}
}
@ -242,13 +220,6 @@ abstract class CCTweakedExtension(
).resolve().single()
}
/**
* Exclude a dependency from being published in Maven.
*/
fun exclude(dep: Dependency) {
excludedDeps.add(dep)
}
private fun <T> gitProvider(default: T, command: List<String>, process: (String) -> T): Provider<T> {
val baseResult = project.providers.exec {
commandLine = listOf("git", "-C", project.rootDir.absolutePath) + command

View File

@ -8,9 +8,6 @@ import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.publish.PublishingExtension
import org.gradle.api.publish.maven.MavenPublication
import org.gradle.api.publish.plugins.PublishingPlugin
import org.gradle.jvm.toolchain.JavaLanguageVersion
import org.gradle.plugins.ide.idea.model.IdeaModel
import org.jetbrains.gradle.ext.IdeaExtPlugin
@ -29,13 +26,6 @@ class CCTweakedPlugin : Plugin<Project> {
cct.sourceDirectories.add(SourceSetReference.internal(sourceSets.getByName("main")))
}
project.plugins.withType(PublishingPlugin::class.java) {
val publishing = project.extensions.getByType(PublishingExtension::class.java)
publishing.publications.withType(MavenPublication::class.java) {
excludeMavenDependencies(project, this, cct.excludedDeps)
}
}
project.plugins.withType(IdeaExtPlugin::class.java) { extendIdea(project) }
}

View File

@ -22,19 +22,19 @@ import org.gradle.language.base.plugins.LifecycleBasePlugin
abstract class DependencyCheck : DefaultTask() {
@get:Input
abstract val configuration: ListProperty<Configuration>
protected abstract val dependencies: ListProperty<DependencyResult>
/**
* A mapping of module coordinates (`group:module`) to versions, overriding the requested version.
*/
@get:Input
abstract val overrides: MapProperty<String, String>
protected abstract val overrides: MapProperty<String, String>
init {
description = "Check :core's dependencies are consistent with Minecraft's."
group = LifecycleBasePlugin.VERIFICATION_GROUP
configuration.finalizeValueOnRead()
dependencies.finalizeValueOnRead()
overrides.finalizeValueOnRead()
}
@ -45,13 +45,19 @@ abstract class DependencyCheck : DefaultTask() {
overrides.putAll(project.provider { mutableMapOf(module.get().module.toString() to version) })
}
/**
* Add a configuration to check.
*/
fun configuration(configuration: Provider<Configuration>) {
// We can't store the Configuration in the cache, so store the resolved dependencies instead.
dependencies.addAll(configuration.map { it.incoming.resolutionResult.allDependencies })
}
@TaskAction
fun run() {
var ok = true
for (configuration in configuration.get()) {
configuration.incoming.resolutionResult.allDependencies {
if (!check(this@allDependencies)) ok = false
}
for (configuration in dependencies.get()) {
if (!check(configuration)) ok = false
}
if (!ok) {

View File

@ -1,46 +0,0 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.gradle
import org.gradle.api.Project
import org.gradle.api.artifacts.Dependency
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.plugins.BasePluginExtension
import org.gradle.api.provider.Provider
import org.gradle.api.publish.maven.MavenPublication
/**
* A dependency in a POM file.
*/
private data class MavenDependency(val groupId: String?, val artifactId: String?) {
constructor(project: Project, dep: Dependency) : this(
dep.group,
when (dep) {
is ProjectDependency -> project.project(dep.path).extensions.getByType(BasePluginExtension::class.java).archivesName.get()
else -> dep.name
},
)
}
/**
* Remove dependencies in a POM file based on a list of dependencies
*
* While this approach is very ugly, it's the easiest way to handle it!
*/
internal fun excludeMavenDependencies(project: Project, publication: MavenPublication, excluded: Provider<out List<Dependency>>) {
val excludedSpecs = excluded.map { xs -> xs.map { MavenDependency(project, it) } }
publication.pom.withXml {
val dependencies = XmlUtil.findChild(asNode(), "dependencies") ?: return@withXml
dependencies.children().map { it as groovy.util.Node }.forEach {
val dep = MavenDependency(
groupId = XmlUtil.findChild(it, "groupId")?.text(),
artifactId = XmlUtil.findChild(it, "artifactId")?.text(),
)
if (excludedSpecs.get().contains(dep)) it.parent().remove(it)
}
}
}

View File

@ -11,12 +11,10 @@ import org.gradle.api.artifacts.ModuleDependency
import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.plugins.BasePlugin
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.publish.tasks.GenerateModuleMetadata
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.bundling.Jar
import org.gradle.api.tasks.javadoc.Javadoc
import org.gradle.kotlin.dsl.get
import org.gradle.kotlin.dsl.withType
/**
* This sets up a separate client-only source set, and extends that and the main/common source set with additional
@ -97,18 +95,12 @@ class MinecraftConfigurations private constructor(private val project: Project)
sourceDirectories.add(SourceSetReference.internal(client))
}
// We can't create accurate module metadata for our additional capabilities,
// so disable module metadata.
project.tasks.withType(GenerateModuleMetadata::class.java).configureEach {
isEnabled = false
}
// 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))
configuration(configurations.named(main.runtimeClasspathConfigurationName))
configuration(configurations.named(client.runtimeClasspathConfigurationName))
}
project.tasks.named("check") { dependsOn(checkDependencyConsistency) }
}

View File

@ -52,7 +52,8 @@ create-fabric = "0.5.1-f-build.1467+mc1.20.1"
# Testing
hamcrest = "2.2"
jqwik = "1.8.2"
junit = "5.10.1"
junit = "5.11.4"
junitPlatform = "1.11.4"
jmh = "1.37"
# Build tools
@ -130,6 +131,7 @@ jqwik-engine = { module = "net.jqwik:jqwik-engine", version.ref = "jqwik" }
junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" }
junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" }
junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit" }
junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher", version.ref = "junitPlatform" }
slf4j-simple = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" }
jmh = { module = "org.openjdk.jmh:jmh-core", version.ref = "jmh" }
jmh-processor = { module = "org.openjdk.jmh:jmh-generator-annprocess", version.ref = "jmh" }
@ -188,7 +190,7 @@ externalMods-fabric-runtime = ["jei-fabric", "modmenu"]
# Testing
test = ["junit-jupiter-api", "junit-jupiter-params", "hamcrest", "jqwik-api"]
testRuntime = ["junit-jupiter-engine", "jqwik-engine"]
testRuntime = ["junit-jupiter-engine", "junit-platform-launcher", "jqwik-engine"]
# Build tools
teavm-api = ["teavm-jso", "teavm-jso-apis", "teavm-platform", "teavm-classlib", "teavm-metaprogramming-api"]

View File

@ -126,3 +126,8 @@ val runData by tasks.registering(MergeTrees::class) {
val runExampleData by tasks.registering(MergeTrees::class) {
configureForDatagen(sourceSets.examples.get(), "src/examples/generatedResources")
}
// We can't create accurate module metadata for our additional capabilities, so disable it.
project.tasks.withType(GenerateModuleMetadata::class.java).configureEach {
isEnabled = false
}

View File

@ -23,7 +23,8 @@ class Speaker_Test {
callPeripheral("right", "playSound", SoundEvents.NOTE_BLOCK_HARP.key().location().toString())
.assertArrayEquals(true)
tryMultipleTimes(2) { // We could technically call this a tick later, so try twice
tryMultipleTimes(2) {
// We could technically call this a tick later, so try twice
callPeripheral("right", "playSound", SoundEvents.NOTE_BLOCK_HARP.key().location().toString())
.assertArrayEquals(false)
}

View File

@ -40,9 +40,8 @@ dependencies {
}
tasks.processResources {
filesMatching("data/computercraft/lua/rom/help/credits.md") {
expand(mapOf("gitContributors" to cct.gitContributors.map { it.joinToString("\n") }.get()))
}
var props = mapOf("gitContributors" to cct.gitContributors.get().joinToString("\n"))
filesMatching("data/computercraft/lua/rom/help/credits.md") { expand(props) }
}
tasks.test {

View File

@ -14,8 +14,6 @@ import io.netty.buffer.CompositeByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
import java.io.Closeable;
@ -30,8 +28,6 @@ import java.util.Objects;
import static dan200.computercraft.core.apis.http.request.HttpRequest.getHeaderSize;
public final class HttpRequestHandler extends SimpleChannelInboundHandler<HttpObject> implements Closeable {
private static final Logger LOG = LoggerFactory.getLogger(HttpRequestHandler.class);
/**
* Same as {@link io.netty.handler.codec.MessageAggregator}.
*/

View File

@ -61,6 +61,16 @@ configurations {
include { extendsFrom(includeRuntimeOnly.get(), includeImplementation.get()) }
runtimeOnly { extendsFrom(includeRuntimeOnly.get()) }
implementation { extendsFrom(includeImplementation.get()) }
// Declare a configuration for projects which are on the compile and runtime classpath, but not treated as
// dependencies. This is used for our local projects.
val localImplementation by registering {
isCanBeResolved = false
isCanBeConsumed = false
isVisible = false
}
compileClasspath { extendsFrom(localImplementation.get()) }
runtimeClasspath { extendsFrom(localImplementation.get()) }
}
dependencies {
@ -90,9 +100,9 @@ dependencies {
"includeImplementation"(libs.nightConfig.toml)
// Pull in our other projects. See comments in MinecraftConfigurations on this nastiness.
api(commonClasses(project(":fabric-api"))) { cct.exclude(this) }
clientApi(clientClasses(project(":fabric-api"))) { cct.exclude(this) }
implementation(project(":core")) { cct.exclude(this) }
"localImplementation"(project(":core"))
"localImplementation"(commonClasses(project(":fabric-api")))
clientImplementation(clientClasses(project(":fabric-api")))
annotationProcessorEverywhere(libs.autoService)
@ -210,11 +220,9 @@ loom {
}
tasks.processResources {
inputs.property("version", modVersion)
var props = mapOf("version" to modVersion)
filesMatching("fabric.mod.json") {
expand(mapOf("version" to modVersion))
}
filesMatching("fabric.mod.json") { expand(props) }
}
tasks.jar {

View File

@ -136,6 +136,16 @@ configurations {
for (testConfig in listOf("testClientAdditionalRuntimeClasspath", "gametestAdditionalRuntimeClasspath")) {
named(testConfig) { extendsFrom(testAdditionalRuntimeClasspath.get()) }
}
// Declare a configuration for projects which are on the compile and runtime classpath, but not treated as
// dependencies. This is used for our local projects.
val localImplementation by registering {
isCanBeResolved = false
isCanBeConsumed = false
isVisible = false
}
compileClasspath { extendsFrom(localImplementation.get()) }
runtimeClasspath { extendsFrom(localImplementation.get()) }
}
dependencies {
@ -148,9 +158,9 @@ dependencies {
modCompileOnly(variantOf(libs.create.forge) { classifier("slim") })
// Depend on our other projects.
api(commonClasses(project(":forge-api"))) { cct.exclude(this) }
clientApi(clientClasses(project(":forge-api"))) { cct.exclude(this) }
implementation(project(":core")) { cct.exclude(this) }
"localImplementation"(project(":core"))
"localImplementation"(commonClasses(project(":forge-api")))
clientImplementation(clientClasses(project(":forge-api")))
jarJar(libs.cobalt)
jarJar(libs.jzlib)
@ -180,12 +190,12 @@ dependencies {
// Compile tasks
tasks.processResources {
inputs.property("modVersion", modVersion)
inputs.property("forgeVersion", libs.versions.forge.get())
var props = mapOf(
"forgeVersion" to libs.versions.forge.get(),
"file" to mapOf("jarVersion" to modVersion),
)
filesMatching("META-INF/mods.toml") {
expand(mapOf("forgeVersion" to libs.versions.forge.get(), "file" to mapOf("jarVersion" to modVersion)))
}
filesMatching("META-INF/mods.toml") { expand(props) }
}
tasks.jar {

View File

@ -95,14 +95,14 @@ val illuaminateDocs by tasks.registering(cc.tweaked.gradle.IlluaminateExecToDir:
// Sources
inputs.files(rootProject.fileTree("doc")).withPropertyName("docs")
inputs.files(project(":core").fileTree("src/main/resources/data/computercraft/lua")).withPropertyName("lua rom")
inputs.files(project(":common").tasks.named("luaJavadoc"))
inputs.dir(project(":common").tasks.named<Javadoc>("luaJavadoc").map { it.destinationDir!! }).withPropertyName("luaJavadoc")
// Assets
inputs.files(rollup)
// Output directory. Also defined in illuaminate.sexp.
output = layout.buildDirectory.dir("illuaminate")
args = listOf("doc-gen")
args("doc-gen")
workingDir = rootProject.projectDir
}