Skip to content

Backported changes from the CC: Tweaked Gametest framework present in 1.20.x #622

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import cc.tweaked.gradle.ClientJavaExec
import net.darkhax.curseforgegradle.TaskPublishCurseForge

import java.text.SimpleDateFormat
Expand All @@ -8,7 +9,7 @@ plugins {
id 'org.jetbrains.changelog' version '1.2.1'
id "com.modrinth.minotaur" version "2.+"
id "org.jetbrains.kotlin.jvm" version "${kotlin_version}"
id 'net.minecraftforge.gradle' version '[6.0.18,6.2)'
id 'net.minecraftforge.gradle'
id 'org.parchmentmc.librarian.forgegradle' version '1.+'
id 'org.spongepowered.mixin' version '0.7.+'
id "com.github.breadmoirai.github-release" version "2.5.2"
Expand Down Expand Up @@ -148,7 +149,7 @@ minecraft {
}
}

gameTestClient {
testClient {
workingDirectory project.file('test-files/client')
parent runs.client

Expand Down Expand Up @@ -664,3 +665,9 @@ publishing {
}
}
}

tasks.register('runGameTestClient', ClientJavaExec, { task ->
description "Runs client-side gametests with no mods"
setRunConfig(minecraft.runs["testClient"])
tags("client")
})
21 changes: 21 additions & 0 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
plugins {
`java-gradle-plugin`
`kotlin-dsl`
kotlin("jvm") version "1.9.23"
}

repositories {
mavenCentral()

maven("https://maven.minecraftforge.net") {
name = "Forge"
content {
includeGroup("net.minecraftforge")
includeGroup("net.minecraftforge.gradle")
}
}
}

dependencies {
implementation("net.minecraftforge.gradle:ForgeGradle:[6.0.18,6.2)")
}
157 changes: 157 additions & 0 deletions buildSrc/src/main/kotlin/cc/tweaked/gradle/Extensions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0

package cc.tweaked.gradle

import org.gradle.api.artifacts.dsl.DependencyHandler
import org.gradle.api.file.FileSystemLocation
import org.gradle.api.provider.Property
import org.gradle.api.provider.Provider
import org.gradle.api.tasks.JavaExec
import org.gradle.process.BaseExecSpec
import org.gradle.process.JavaExecSpec
import org.gradle.process.ProcessForkOptions

/**
* Add an annotation processor to all source sets.
*/
fun DependencyHandler.annotationProcessorEverywhere(dep: Any) {
add("compileOnly", dep)
add("annotationProcessor", dep)

add("clientCompileOnly", dep)
add("clientAnnotationProcessor", dep)

add("testCompileOnly", dep)
add("testAnnotationProcessor", dep)
}

/**
* A version of [JavaExecSpec.copyTo] which copies *all* properties.
*/
fun JavaExec.copyToFull(spec: JavaExec) {
copyTo(spec)

// Additional Java options
spec.jvmArgs = jvmArgs // Fabric overrides getJvmArgs so copyTo doesn't do the right thing.
spec.args = args
spec.argumentProviders.addAll(argumentProviders)
spec.mainClass.set(mainClass)
spec.classpath = classpath
spec.javaLauncher.set(javaLauncher)
if (executable != null) spec.setExecutable(executable!!)

// Additional ExecSpec options
copyToExec(spec)
}

/**
* Copy additional [BaseExecSpec] options which aren't handled by [ProcessForkOptions.copyTo].
*/
fun BaseExecSpec.copyToExec(spec: BaseExecSpec) {
spec.isIgnoreExitValue = isIgnoreExitValue
if (standardInput != null) spec.standardInput = standardInput
if (standardOutput != null) spec.standardOutput = standardOutput
if (errorOutput != null) spec.errorOutput = errorOutput
}

/**
* An alternative to [Nothing] with a more descriptive name. Use to enforce calling a function with named arguments:
*
* ```kotlin
* fun f(vararg unused: UseNamedArgs, arg1: Int, arg2: Int) {
* // ...
* }
* ```
*/
class UseNamedArgs private constructor()

/**
* An [AutoCloseable] implementation which can be used to combine other [AutoCloseable] instances.
*
* Values which implement [AutoCloseable] can be dynamically registered with [CloseScope.add]. When the scope is closed,
* each value is closed in the opposite order.
*
* This is largely intended for cases where it's not appropriate to nest [AutoCloseable.use], for instance when nested
* would be too deep.
*/
class CloseScope : AutoCloseable {
private val toClose = ArrayDeque<AutoCloseable>()

/**
* Add a value to be closed when this scope is closed.
*/
public fun add(value: AutoCloseable) {
toClose.addLast(value)
}

override fun close() {
close(null)
}

@PublishedApi
internal fun close(baseException: Throwable?) {
var exception = baseException

while (true) {
var toClose = toClose.removeLastOrNull() ?: break
try {
toClose.close()
} catch (e: Throwable) {
if (exception == null) {
exception = e
} else {
exception.addSuppressed(e)
}
}
}

if (exception != null) throw exception
}

inline fun <R> use(block: (CloseScope) -> R): R {
var exception: Throwable? = null
try {
return block(this)
} catch (e: Throwable) {
exception = e
throw e
} finally {
close(exception)
}
}
}

/** Proxy method to avoid overload ambiguity. */
fun <T> Property<T>.setProvider(provider: Provider<out T>) = set(provider)

/** Short-cut method to get the absolute path of a [FileSystemLocation] provider. */
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()
}
26 changes: 26 additions & 0 deletions buildSrc/src/main/kotlin/cc/tweaked/gradle/ForgeExtensions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// SPDX-FileCopyrightText: 2023 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0

package cc.tweaked.gradle

import net.minecraftforge.gradle.common.util.RunConfig
import net.minecraftforge.gradle.common.util.runs.setRunConfigInternal
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.api.tasks.JavaExec
import org.gradle.jvm.toolchain.JavaToolchainService
import java.nio.file.Files

/**
* Set [JavaExec] task to run a given [RunConfig].
*/
fun JavaExec.setRunConfig(config: RunConfig) {
dependsOn("prepareRuns")
setRunConfigInternal(project, this, config)
doFirst("Create working directory") { Files.createDirectories(workingDir.toPath()) }

javaLauncher.set(
project.extensions.getByType(JavaToolchainService::class.java)
.launcherFor(project.extensions.getByType(JavaPluginExtension::class.java).toolchain),
)
}
Loading