Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/qa/fluent-logger' into qa/fluent…
Browse files Browse the repository at this point in the history
…-logger
  • Loading branch information
jdrueckert committed May 17, 2024
2 parents 4ad29ed + eb7ed68 commit f4b34ff
Show file tree
Hide file tree
Showing 31 changed files with 111 additions and 163 deletions.
203 changes: 96 additions & 107 deletions engine/build.gradle → engine/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// SPDX-License-Identifier: Apache-2.0

// The engine build is the primary Java project and has the primary list of dependencies

import groovy.json.JsonSlurper
import java.time.OffsetDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
Expand All @@ -16,45 +14,35 @@ plugins {
}

// Grab all the common stuff like plugins to use, artifact repositories, code analysis config, etc
apply from: "$rootDir/config/gradle/publish.gradle"

// Declare "extra properties" (variables) for the project - a Gradle thing that makes them special.
ext {
// Read environment variables, including variables passed by jenkins continuous integration server
env = System.getenv()
apply(from = "$rootDir/config/gradle/publish.gradle")

templatesDir = new File(rootDir, "templates")
// Read environment variables, including variables passed by jenkins continuous integration server
val env = System.getenv()

// Stuff for our automatic version file setup
startDateTimeString = OffsetDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX"))
versionBase = new File(templatesDir, "version.txt").text.trim()
displayVersion = versionBase
}
// Stuff for our automatic version file setup
val startDateTimeString = OffsetDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX"))
val displayVersion by lazy { File("$rootDir/templates/version.txt").readText().trim() }

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Java Section //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

sourceSets {
configure<SourceSetContainer> {
// Adjust output path (changed with the Gradle 6 upgrade, this puts it back)
main {
proto {
srcDir "src/main/protobuf"
}
java {
// Adjust output path (changed with the Gradle 6 upgrade, this puts it back)
destinationDirectory = new File("$buildDir/classes")
}
test.java.destinationDirectory = new File("$buildDir/testClasses")
java.destinationDirectory.set(layout.buildDirectory.dir("classes"))
proto.srcDir("src/main/protobuf")
}
test { java.destinationDirectory.set(layout.buildDirectory.dir("testClasses")) }
}

// Customizations for the main compilation configuration
configurations {

// Exclude a couple JWJGL modules that aren't needed during compilation (OS specific stuff in these two perhaps)
implementation {
exclude module: "lwjgl-platform"
exclude module: "jinput-platform"
exclude(module = "lwjgl-platform")
exclude(module = "jinput-platform")
}
}

Expand Down Expand Up @@ -90,7 +78,7 @@ dependencies {
implementation("com.esotericsoftware:reflectasm:1.11.9")

// Graphics, 3D, UI, etc
api(platform("org.lwjgl:lwjgl-bom:$LwjglVersion"))
api(platform("org.lwjgl:lwjgl-bom:${rootProject.extra["LwjglVersion"]}"))
api("org.lwjgl:lwjgl")
implementation("org.lwjgl:lwjgl-assimp")
api("org.lwjgl:lwjgl-glfw")
Expand Down Expand Up @@ -128,7 +116,7 @@ dependencies {

// telemetry
implementation("com.snowplowanalytics:snowplow-java-tracker:0.12.1") {
exclude group: "org.slf4j", module: "slf4j-simple"
exclude(group = "org.slf4j", module = "slf4j-simple")
}
implementation("net.logstash.logback:logstash-logback-encoder:7.4")

Expand All @@ -148,7 +136,7 @@ dependencies {


// Wildcard dependency to catch any libs provided with the project (remote repo preferred instead)
api fileTree(dir: "libs", include: "*.jar")
api(fileTree("libs") { include("*.jar") })

// TODO: Consider moving this back to the PC Facade instead of having the engine rely on it?
implementation("org.terasology.crashreporter:cr-terasology:5.0.0")
Expand All @@ -164,95 +152,50 @@ protobuf {
}
}

// Instructions for packaging a jar file for the engine
jar {
// Unlike the content modules Gradle grabs the assets as they're in a resources directory. Need to avoid dupes tho
duplicatesStrategy = "EXCLUDE"

doFirst {
manifest {
def manifestClasspath = "$subDirLibs/" + configurations."${sourceSets.main.runtimeClasspathConfigurationName}".collect {
it.getName()
}.join(" $subDirLibs/")
attributes("Class-Path": manifestClasspath, "Implementation-Title": "Terasology", "Implementation-Version": displayVersion + ", engine v" + project.version + " , build number " + env.BUILD_NUMBER)
}
}
}

// JMH related tasks

sourceSets {
jmh {
java.srcDirs = ["src/jmh/java"]
resources.srcDirs = ["src/jmh/resources"]
compileClasspath += sourceSets.main.runtimeClasspath
java.destinationDirectory = new File("$buildDir/jmhClasses")
}
}

tasks.register("jmh", JavaExec) {
dependsOn jmhClasses
mainClass = "org.openjdk.jmh.Main"
classpath = sourceSets.jmh.compileClasspath + sourceSets.jmh.runtimeClasspath
}

dependencies {
jmhAnnotationProcessor("org.openjdk.jmh:jmh-generator-annprocess:1.27")
jmhImplementation("org.openjdk.jmh:jmh-core:1.27")
jmhImplementation("org.openjdk.jmh:jmh-generator-annprocess:1.27")
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Version file stuff //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// First read the internal version out of the engine"s module.txt
def moduleFile = file("src/main/resources/org/terasology/engine/module.txt")

if (!moduleFile.exists()) {
println "Failed to find module.txt for engine"
throw new GradleException("Failed to find module.txt for engine")
}
val moduleFile = layout.projectDirectory.file("src/main/resources/org/terasology/engine/module.txt").asFile

println "Scanning for version in module.txt for engine"
def slurper = new JsonSlurper()
def moduleConfig = slurper.parseText(moduleFile.text)
println("Scanning for version in module.txt for engine")
val moduleConfig = groovy.json.JsonSlurper().parseText(moduleFile.readText()) as Map<String, String>

// Gradle uses the magic version variable when creating the jar name (unless explicitly set differently)
version = moduleConfig.version
version = moduleConfig["version"]!!

// Jenkins-Artifactory integration catches on to this as part of the Maven-type descriptor
group = "org.terasology.engine"

println "Version for $project.name loaded as $version for group $group"

// This version info file actually goes inside the built jar and can be used at runtime
def createVersionInfoFile = tasks.register("createVersionInfoFile", WriteProperties) {
//noinspection GroovyAssignabilityCheck
properties([
buildNumber: env.BUILD_NUMBER,
buildId: env.BUILD_ID,
buildTag: env.BUILD_TAG,
buildUrl: env.BUILD_URL,
jobName: env.JOB_NAME,
gitCommit: env.GIT_COMMIT,
displayVersion: displayVersion,
engineVersion: version
].findAll { it.value != null })
if (env.JOB_NAME != null) {
// Only set the dateTime property when there is a Jenkins JOB_NAME.
// It is a value we can always get (on Jenkins or otherwise) but we don't want local builds
// to invalidate their cache whenever the time changes.
// TODO: after upgrading to Gradle 6.8, see if we can have it ignore this property specifically:
// https://docs.gradle.org/current/userguide/incremental_build.html#sec:property_file_normalization
println("Version for $project.name loaded as $version for group $group")

// This version info file actually goes inside the built jar and can be used at runtime, contents:
// displayVersion=alpha-20
// engineVersion=5.4.0-SNAPSHOT
tasks.register<WriteProperties>("createVersionInfoFile") {
mapOf(
"buildNumber" to env["BUILD_NUMBER"],
"buildId" to env["BUILD_ID"],
"buildTag" to env["BUILD_TAG"],
"buildUrl" to env["BUILD_URL"],
"jobName" to env["JOB_NAME"],
"gitCommit" to env["GIT_COMMIT"],
"displayVersion" to displayVersion,
"engineVersion" to version
).filterValues { it != null }.forEach { (key, value) ->
property(key, value!!)
inputs.property(key, value)
}
if (env["JOB_NAME"] != null) {
property("dateTime", startDateTimeString)
}

destinationFile = layout.buildDirectory.dir("createrVersionInfoFile").get().file("versionInfo.properties")
}

tasks.named("processResources", Copy) {
from(createVersionInfoFile) {
tasks.named<Copy>("processResources") {
from("createVersionInfoFile") {
into("org/terasology/engine/version/")
}
from("$rootDir/docs") {
Expand All @@ -261,16 +204,62 @@ tasks.named("processResources", Copy) {
}

//TODO: Remove this when gestalt can handle ProtectionDomain without classes (Resources)
tasks.register("copyResourcesToClasses", Copy) {
from processResources
into sourceSets.main.output.classesDirs.first()

tasks.register<Copy>("copyResourcesToClasses") {
from("processResources")
into(sourceSets["main"].output.classesDirs.first())
}

tasks.named("compileJava") {
dependsOn(tasks.named("copyResourcesToClasses"))
}

// Instructions for packaging a jar file for the engine
tasks.withType<Jar> {
// Unlike the content modules Gradle grabs the assets as they're in a resources directory. Need to avoid dupes tho
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
manifest {
attributes["Class-Path"] = "libs/" + configurations.runtimeClasspath.get().joinToString(" libs/") { it.name }
attributes["Implementation-Title"] = "Terasology"
attributes["Implementation-Version"] =
"$displayVersion, engine v${project.version}, build number ${env["BUILD_NUMBER"]}"
}
}

// JMH related tasks

sourceSets {
create("jmh") {
java.srcDir("src/jmh/java")
resources.srcDir("src/jmh/resources")
compileClasspath += sourceSets["main"].runtimeClasspath
java.destinationDirectory.set(layout.buildDirectory.dir("jmhClasses"))
}
}

tasks.register<JavaExec>("jmh") {
dependsOn("jmhClasses")
mainClass.set("org.openjdk.jmh.Main")
classpath = sourceSets.named("jmh").get().compileClasspath + sourceSets.named("jmh").get().runtimeClasspath
}

dependencies {
"jmhAnnotationProcessor"("org.openjdk.jmh:jmh-generator-annprocess:1.27")
"jmhImplementation"("org.openjdk.jmh:jmh-core:1.27")
"jmhImplementation"("org.openjdk.jmh:jmh-generator-annprocess:1.27")
}

// following tasks use the output of jmh, so declare explicit dependency
listOf(
Checkstyle::class,
Pmd::class,
Javadoc::class,
com.github.spotbugs.snom.SpotBugsTask::class
).forEach { taskClass ->
tasks.withType(taskClass.java).configureEach {
dependsOn(":engine:compileJmhJava")
}
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// General IDE customization //
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -281,11 +270,11 @@ idea {
inheritOutputDirs = false
outputDir = file("build/classes")
testOutputDir = file("build/testClasses")
downloadSources = true
isDownloadSources = true
}
}

// Make sure our config file for code analytics get extracted (vulnerability: non-IDE execution of single analytic)
ideaModule.dependsOn rootProject.extractConfig
tasks.eclipse.dependsOn rootProject.extractConfig
check.dependsOn rootProject.extractConfig
tasks.named("ideaModule") { dependsOn(tasks.getByPath(":extractConfig")) }
tasks.named("eclipse") { dependsOn(tasks.getByPath(":extractConfig")) }
tasks.named("check") { dependsOn(tasks.getByPath(":extractConfig")) }
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
import org.terasology.engine.world.sun.CelestialSystem;
import org.terasology.engine.world.sun.DefaultCelestialSystem;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.gestalt.module.exceptions.UnresolvedDependencyException;

import java.io.IOException;
import java.nio.file.Path;
Expand Down Expand Up @@ -104,7 +105,7 @@ public boolean step() {
// setting the world seed will create the world builder
worldGenerator.setWorldSeed(worldInfo.getSeed());
context.put(WorldGenerator.class, worldGenerator);
} catch (UnresolvedWorldGeneratorException e) {
} catch (UnresolvedWorldGeneratorException | UnresolvedDependencyException e) {
logger.atError().log("Unable to load world generator {}. Available world generators: {}",
worldInfo.getWorldGenerator(), worldGeneratorManager.getWorldGenerators());
context.get(GameEngine.class).changeState(new StateMainMenu("Failed to resolve world generator."));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import org.terasology.gestalt.entitysystem.component.Component;
import org.terasology.gestalt.module.Module;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.gestalt.module.exceptions.UnresolvedDependencyException;
import org.terasology.gestalt.module.dependencyresolution.DependencyInfo;
import org.terasology.gestalt.module.dependencyresolution.DependencyResolver;
import org.terasology.gestalt.module.dependencyresolution.ResolutionResult;
Expand Down Expand Up @@ -194,6 +195,8 @@ public WorldGeneratorInfo get() {

getManager().pushScreen(MessagePopup.ASSET_URI, MessagePopup.class).setMessage("No selectable world generators!",
"Please select at least one module that supports a registered world generator!");
CoreRegistry.put(UniverseWrapper.class, context.get(UniverseWrapper.class));
triggerBackAnimation();

return null;
}
Expand Down Expand Up @@ -351,6 +354,10 @@ private void addNewWorld(WorldGeneratorInfo worldGeneratorInfo) {
universeWrapper.setWorldGenerator(worldGenerator);
context.put(UniverseWrapper.class, universeWrapper);
} catch (UnresolvedWorldGeneratorException e) {
getManager().pushScreen(MessagePopup.ASSET_URI, MessagePopup.class).setMessage("Selected world generator cannot be resolved!",
"Please report this issue on Discord/GitHub and select a different world generator!");
e.printStackTrace();
} catch (UnresolvedDependencyException e) {
//TODO: this will likely fail at game creation time later-on due to lack of world generator - don't just ignore this

Check warning on line 361 in engine/src/main/java/org/terasology/engine/rendering/nui/layers/mainMenu/UniverseSetupScreen.java

View check run for this annotation

Terasology Jenkins.io / Open Tasks Scanner

TODO

NORMAL: this will likely fail at game creation time later-on due to lack of world generator - don't just ignore this
e.printStackTrace();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.terasology.engine.world.generator.WorldGenerator;
import org.terasology.gestalt.module.Module;
import org.terasology.gestalt.module.ModuleEnvironment;
import org.terasology.gestalt.module.exceptions.UnresolvedDependencyException;
import org.terasology.gestalt.module.dependencyresolution.DependencyResolver;
import org.terasology.gestalt.module.dependencyresolution.ResolutionResult;
import org.terasology.gestalt.naming.Name;
Expand Down Expand Up @@ -98,7 +99,8 @@ public WorldGeneratorInfo getWorldGeneratorInfo(SimpleUri uri) {
* @param context objects from this context will be injected into the
* @return The instantiated world generator.
*/
public static WorldGenerator createGenerator(SimpleUri uri, Context context) throws UnresolvedWorldGeneratorException {
public static WorldGenerator createGenerator(SimpleUri uri, Context context)
throws UnresolvedWorldGeneratorException, UnresolvedDependencyException {
ModuleManager moduleManager = context.get(ModuleManager.class);
Module module = moduleManager.getEnvironment().get(uri.getModuleName());
if (module == null) {
Expand Down Expand Up @@ -128,12 +130,12 @@ public static WorldGenerator createGenerator(SimpleUri uri, Context context) thr
* @return a new world generator with the specified uri.
*/
public static WorldGenerator createWorldGenerator(SimpleUri uri, Context context, ModuleEnvironment environment)
throws UnresolvedWorldGeneratorException {
throws UnresolvedWorldGeneratorException, UnresolvedDependencyException {
for (Class<?> generatorClass : environment.getTypesAnnotatedWith(RegisterWorldGenerator.class)) {
RegisterWorldGenerator annotation = generatorClass.getAnnotation(RegisterWorldGenerator.class);
Name moduleName = environment.getModuleProviding(generatorClass);
if (moduleName == null) {
throw new UnresolvedWorldGeneratorException("Cannot find module for world generator " + generatorClass);
throw new UnresolvedDependencyException("Cannot find module for world generator " + generatorClass);
}
SimpleUri generatorUri = new SimpleUri(moduleName, annotation.id());
if (generatorUri.equals(uri)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,13 +437,9 @@
"water-reflections-ssr": "water-reflections-ssr",
"widget-selection-prompt": "widget-selection-prompt",
"widget-selection-title": "widget-selection-title",
"world-config-preview": "world-config-preview",
"world-configuration": "world-configuration",
"world-generator": "world-generator",
"world-name": "world-name",
"world-pre-generation": "world-pre-generation",
"world-seed": "world-seed",
"world-setup": "world-setup",
"catching-world": "catching-world",
"awaiting-character-spawn": "awaiting-character-spawn",
"ensuring-save-game-consistency": "ensuring-save-game-consistency",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,5 @@
"water-reflections-ssr": "SSR (تجريبي)",
"widget-selection-prompt": "Select the type of the widget:",
"widget-selection-title": "Widget Selection",
"world-config-preview": "التفاصيل...",
"world-seed": "بذرة"
}
Loading

0 comments on commit f4b34ff

Please sign in to comment.