diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index da292837ad0..7a4a01ffb0a 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -4,7 +4,8 @@ If you would like to contribute code, documentation, or other assets you can do *When submitting code, please make every effort to follow existing conventions and style in order to keep the code as readable as possible.* -Read on for an overview and [check the wiki for more details](https://github.com/MovingBlocks/Terasology/wiki). For questions please join us in our [forum](http://forum.terasology.org/forum/) or on `#terasology` (irc.freenode.net). +Read on for an overview and [check the wiki for more details](https://github.com/MovingBlocks/Terasology/wiki). +For questions please join us in our [forum] or [Discord]. ## File an Issue @@ -12,10 +13,13 @@ You can report bugs and feature requests to [GitHub Issues](https://github.com/M For finding easy to do issues to start with look at the [Good First Issue](https://github.com/MovingBlocks/Terasology/labels/Good%20First%20Issue) issues. -We prefer questions and support requests be posted in the [forum](http://forum.terasology.org/forum). +We prefer questions and support requests be posted in the [forum] or [Discord]. __Please provide as much information as possible to help us solve problems and answer questions better!__ +[forum]: https://forum.terasology.org/forum/ +[Discord]: https://discord.gg/Terasology + ## PR Title / Commit Message Guidelines We try to follow the [conventional commits](https://www.conventionalcommits.org/en/v1.0.0-beta.2/) style for commit messages and pull request titles. diff --git a/Jenkinsfile b/Jenkinsfile index eed491396e4..b465aab7155 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -134,7 +134,7 @@ pipeline { recordIssues(skipBlames: true, enabledForFailure: true, tools: [ - spotBugs(pattern: '**/build/reports/spotbugs/main/*.xml', useRankAsPriority: true), + spotBugs(pattern: '**/build/reports/spotbugs/*.xml', useRankAsPriority: true), pmdParser(pattern: '**/build/reports/pmd/*.xml') ]) diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index 55509f1f4e1..26a260ad7a7 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -1,4 +1,4 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 import java.net.URI @@ -10,6 +10,7 @@ plugins { repositories { mavenCentral() google() // gestalt uses an annotation package by Google + gradlePluginPortal() maven { name = "Terasology Artifactory" @@ -40,6 +41,10 @@ dependencies { // for inspecting modules implementation("org.terasology.gestalt:gestalt-module:7.1.0") + // plugins we configure + implementation("com.github.spotbugs.snom:spotbugs-gradle-plugin:4.8.0") // TODO: upgrade with gradle 7.x + implementation("org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.3") + api(kotlin("test")) } diff --git a/build-logic/src/main/kotlin/facade.gradle.kts b/build-logic/src/main/kotlin/facade.gradle.kts index 906f29e200d..3a7e5d17b45 100644 --- a/build-logic/src/main/kotlin/facade.gradle.kts +++ b/build-logic/src/main/kotlin/facade.gradle.kts @@ -1,4 +1,4 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 import org.terasology.gradology.JAR_COLLECTION @@ -6,6 +6,7 @@ import org.terasology.gradology.namedAttribute plugins { application + id("terasology-common") } val dirNatives: String by rootProject.extra diff --git a/build-logic/src/main/kotlin/terasology-common.gradle.kts b/build-logic/src/main/kotlin/terasology-common.gradle.kts new file mode 100644 index 00000000000..295a77a9709 --- /dev/null +++ b/build-logic/src/main/kotlin/terasology-common.gradle.kts @@ -0,0 +1,7 @@ +// Copyright 2022 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 + +plugins { + id("terasology-repositories") + id("terasology-metrics") +} diff --git a/build-logic/src/main/kotlin/terasology-metrics.gradle.kts b/build-logic/src/main/kotlin/terasology-metrics.gradle.kts new file mode 100644 index 00000000000..efdd3da3237 --- /dev/null +++ b/build-logic/src/main/kotlin/terasology-metrics.gradle.kts @@ -0,0 +1,69 @@ +// Copyright 2022 The Terasology Foundation +// SPDX-License-Identifier: Apache-2.0 + +import com.github.spotbugs.snom.SpotBugsExtension +import com.github.spotbugs.snom.SpotBugsTask + +plugins { + java + checkstyle + pmd + `project-report` + id("com.github.spotbugs") + id("org.sonarqube") +} + +dependencies { + "pmd"("net.sourceforge.pmd:pmd-core:6.15.0") + "pmd"("net.sourceforge.pmd:pmd-java:6.15.0") +} + +tasks.withType { + useJUnitPlatform() + + // ignoreFailures: Specifies whether the build should break when the verifications performed by this task fail. + ignoreFailures = true + // showStandardStreams: makes the standard streams (err and out) visible at console when running tests + testLogging.showStandardStreams = true + reports { + junitXml.isEnabled = true + } + jvmArgs("-Xms512m", "-Xmx1024m") + + // Make sure the natives have been extracted, but only for multi-workspace setups (not for solo module builds) + if (project.name != project(":").name) { + dependsOn(tasks.getByPath(":extractNatives")) + } +} + +// The config files here work in both a multi-project workspace (IDEs, running from source) and for solo module builds +// Solo module builds in Jenkins get a copy of the config dir from the engine harness so it still lives at root/config +// TODO: Maybe update other projects like modules to pull the zipped dependency so fewer quirks are needed in Jenkins +configure { + isIgnoreFailures = false + + val checkstyleDir = rootDir.resolve("config/metrics/checkstyle") + configDirectory.set(checkstyleDir) + setConfigProperties("samedir" to checkstyleDir) +} + +configure { + isIgnoreFailures = true + ruleSetFiles = files(rootDir.resolve("config/metrics/pmd/pmd.xml")) + // By default, gradle uses both ruleset file AND the rulesets. Override the ruleSets to use only those from the file + ruleSets = listOf() +} + +configure { + // The version of the spotbugs tool https://github.com/spotbugs/spotbugs + // not necessarily the same as the version of spotbugs-gradle-plugin + toolVersion.set("4.7.0") + ignoreFailures.set(true) + excludeFilter.set(file(rootDir.resolve("config/metrics/findbugs/findbugs-exclude.xml"))) +} + +tasks.named("spotbugsMain") { + reports.register("xml") { + enabled = true + } +} diff --git a/build-logic/src/main/kotlin/terasology-module.gradle.kts b/build-logic/src/main/kotlin/terasology-module.gradle.kts index 9ba7a4823e9..584f55664e9 100644 --- a/build-logic/src/main/kotlin/terasology-module.gradle.kts +++ b/build-logic/src/main/kotlin/terasology-module.gradle.kts @@ -1,4 +1,4 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 // Simple build file for modules - the one under the Core module is the template, will be copied as needed to modules @@ -11,6 +11,7 @@ plugins { `java-library` idea eclipse + id("terasology-common") } val moduleMetadata = ModuleMetadataForGradle.forProject(project) diff --git a/build.gradle b/build.gradle index c1e5ed907ed..6c4da8f63fc 100644 --- a/build.gradle +++ b/build.gradle @@ -25,15 +25,6 @@ buildscript { } dependencies { - //Spotbugs - classpath "gradle.plugin.com.github.spotbugs.snom:spotbugs-gradle-plugin:4.0.0" - - // SonarQube / Cloud scanning - classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.8" - - // Protobuf plugin - classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.16' - // Our locally included /build-logic classpath("org.terasology.gradology:build-logic") } @@ -52,6 +43,7 @@ plugins { // For the "Build and run using: Intellij IDEA | Gradle" switch id "org.jetbrains.gradle.plugin.idea-ext" version "1.0" + id("com.google.protobuf") version "0.8.16" apply false id("terasology-repositories") } diff --git a/config/gradle/common.gradle b/config/gradle/common.gradle index 873ae8ba70b..0bb76c48bbf 100644 --- a/config/gradle/common.gradle +++ b/config/gradle/common.gradle @@ -8,14 +8,6 @@ apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'idea' -// Analytics -apply plugin: 'project-report' -apply plugin: 'checkstyle' -apply plugin: 'pmd' -apply plugin: 'com.github.spotbugs' -apply plugin: 'jacoco' -apply plugin: 'org.sonarqube' - apply plugin: 'terasology-repositories' java { @@ -28,12 +20,6 @@ tasks.withType(JavaCompile) { options.encoding = 'UTF-8' } -dependencies { - pmd('net.sourceforge.pmd:pmd-core:6.15.0') - pmd('net.sourceforge.pmd:pmd-java:6.15.0') - // the FindBugs version is set in the configuration -} - task sourceJar(type: Jar) { description = "Create a JAR with all sources" from sourceSets.main.allSource @@ -47,76 +33,6 @@ task javadocJar(type: Jar, dependsOn: javadoc) { archiveClassifier = 'javadoc' } -// Extra details provided for unit tests -test { - useJUnitPlatform() - - // ignoreFailures: Specifies whether the build should break when the verifications performed by this task fail. - ignoreFailures = true - // showStandardStreams: makes the standard streams (err and out) visible at console when running tests - testLogging.showStandardStreams = true - reports { - junitXml.enabled = true - } - // Arguments to include while running tests - jvmArgs '-Xms512m', '-Xmx1024m' - - // Make sure the natives have been extracted, but only for multi-workspace setups (not for solo module builds) - if (project.name != project(':').name) { - dependsOn rootProject.extractNatives - } - - // Keep in sync with other exclude-lists for Jacoco, e.g., in 'engine-tests/build.gradle' - jacoco.excludes = ["org.terasology.protobuf.*", "*MethodAccess", "*FieldAccess"] -} - -jacoco { - toolVersion = "0.8.8" -} - -jacocoTestReport { - dependsOn test // Despite doc saying this should be automatic we need to explicitly add it anyway :-( - reports { - // Used to be exec, but that had a binary incompatibility between JaCoCo 0.7.4 and 0.7.5 and issues with some plugins - xml.enabled true - csv.enabled false - html.enabled true - } -} - -// The config files here work in both a multi-project workspace (IDEs, running from source) and for solo module builds -// Solo module builds in Jenkins get a copy of the config dir from the engine harness so it still lives at root/config -// TODO: Maybe update other projects like modules to pull the zipped dependency so fewer quirks are needed in Jenkins -checkstyle { - ignoreFailures = false - - def checkstyleDir = rootProject.file('config/metrics/checkstyle') - configDirectory = checkstyleDir - configProperties.samedir = checkstyleDir -} - -pmd { - ignoreFailures = true - ruleSetFiles = files("$rootDir/config/metrics/pmd/pmd.xml") - // By default, gradle uses both ruleset file AND the rulesets. Override the ruleSets to use only those from the file - ruleSets = [] -} - -spotbugs { - toolVersion = '4.0.0' - ignoreFailures = true - excludeFilter = new File(rootDir, "config/metrics/findbugs/findbugs-exclude.xml") -} - -spotbugsMain { - reports { - xml { - enabled = true - destination = file("$buildDir/reports/spotbugs/main/spotbugs.xml") - } - } -} - tasks.javadoc { // Disable doclint messages about missing "@param" or "@return" tags. options.addBooleanOption("Xdoclint:all,-missing", true) diff --git a/engine-tests/build.gradle b/engine-tests/build.gradle index 323360d1aa3..24e30634001 100644 --- a/engine-tests/build.gradle +++ b/engine-tests/build.gradle @@ -6,6 +6,7 @@ plugins { id "java-library" id "org.jetbrains.gradle.plugin.idea-ext" + id "terasology-common" } // Grab all the common stuff like plugins to use, artifact repositories, code analysis config @@ -110,9 +111,6 @@ task unitTest(type: Test) { excludeTags "MteTest", "TteTest" } systemProperty("junit.jupiter.execution.timeout.default", "1m") - - // Keep in sync with other exclude-lists for Jacoco, e.g., in 'common.gradle' - jacoco.excludes = ["org.terasology.protobuf.*", "*MethodAccess", "*FieldAccess"] } task integrationTest(type: Test) { @@ -127,8 +125,6 @@ task integrationTest(type: Test) { includeTags "MteTest", "TteTest" } systemProperty("junit.jupiter.execution.timeout.default", "5m") - - jacoco.excludes = ["org.terasology.protobuf.*", "*MethodAccess", "*FieldAccess"] } idea { diff --git a/engine-tests/src/test/java/org/terasology/engine/registry/CoreRegistryTest.java b/engine-tests/src/test/java/org/terasology/engine/registry/CoreRegistryTest.java index dad43023317..39f85c11bbe 100644 --- a/engine-tests/src/test/java/org/terasology/engine/registry/CoreRegistryTest.java +++ b/engine-tests/src/test/java/org/terasology/engine/registry/CoreRegistryTest.java @@ -1,4 +1,4 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.engine.registry; @@ -82,7 +82,7 @@ private static class ContextImplementation implements Context { private final Map, Object> map = Maps.newConcurrentMap(); @Override - public T get(Class type) { + public T get(Class type) { T result = type.cast(map.get(type)); if (result != null) { return result; diff --git a/engine/build.gradle b/engine/build.gradle index dffa7e31211..d7aaa07acc1 100644 --- a/engine/build.gradle +++ b/engine/build.gradle @@ -6,9 +6,10 @@ plugins { id "java-library" id "org.jetbrains.gradle.plugin.idea-ext" + id "com.google.protobuf" + id "terasology-common" } -apply plugin: 'com.google.protobuf' // Grab all the common stuff like plugins to use, artifact repositories, code analysis config, etc apply from: "$rootDir/config/gradle/publish.gradle" diff --git a/engine/src/main/java/org/terasology/engine/context/Context.java b/engine/src/main/java/org/terasology/engine/context/Context.java index 2384ebd6c9c..74eed81db2d 100644 --- a/engine/src/main/java/org/terasology/engine/context/Context.java +++ b/engine/src/main/java/org/terasology/engine/context/Context.java @@ -1,9 +1,12 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.engine.context; import org.terasology.gestalt.module.sandbox.API; +import java.util.NoSuchElementException; +import java.util.Optional; + /** * Provides classes with the utility objects that belong to the context they are running in. * @@ -21,9 +24,31 @@ public interface Context { /** - * @return the object that is known in this context for this type. + * Get the object that is known in this context for this type. + */ + T get(Class type); + + /** + * Get the object that is known in this context for this type. Never null. + * + * @throws NoSuchElementException No instance was registered with that type. + */ + @SuppressWarnings("unused") + default T getValue(Class type) { + T value = get(type); + if (value == null) { + throw new NoSuchElementException(type.toString()); + } + return value; + } + + /** + * Get the object that is known in this context for this type. */ - T get(Class type); + @SuppressWarnings("unused") + default Optional getMaybe(Class type) { + return Optional.ofNullable(get(type)); + } /** * Makes the object known in this context to be the object to work with for the given type. diff --git a/engine/src/main/java/org/terasology/engine/context/internal/ContextImpl.java b/engine/src/main/java/org/terasology/engine/context/internal/ContextImpl.java index 28e94772338..33c13c977d7 100644 --- a/engine/src/main/java/org/terasology/engine/context/internal/ContextImpl.java +++ b/engine/src/main/java/org/terasology/engine/context/internal/ContextImpl.java @@ -1,4 +1,4 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.engine.context.internal; @@ -13,7 +13,7 @@ public class ContextImpl implements Context { private final Context parent; - private final Map, Object> map = Maps.newConcurrentMap(); + private final Map, Object> map = Maps.newConcurrentMap(); /** @@ -30,7 +30,7 @@ public ContextImpl() { } @Override - public T get(Class type) { + public T get(Class type) { if (type == Context.class) { return type.cast(this); } @@ -41,7 +41,7 @@ public T get(Class type) { if (parent != null) { return parent.get(type); } - return result; + return null; } @Override diff --git a/engine/src/main/java/org/terasology/engine/context/internal/MockContext.java b/engine/src/main/java/org/terasology/engine/context/internal/MockContext.java index f5b5c7ed614..90e77ab705f 100644 --- a/engine/src/main/java/org/terasology/engine/context/internal/MockContext.java +++ b/engine/src/main/java/org/terasology/engine/context/internal/MockContext.java @@ -1,4 +1,4 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 package org.terasology.engine.context.internal; @@ -6,7 +6,7 @@ public class MockContext implements Context { @Override - public T get(Class type) { + public T get(Class type) { return null; } diff --git a/facades/PC/build.gradle.kts b/facades/PC/build.gradle.kts index 7f86a010240..741fed95abd 100644 --- a/facades/PC/build.gradle.kts +++ b/facades/PC/build.gradle.kts @@ -1,4 +1,4 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 // The PC facade is responsible for the primary distribution - a plain Java application runnable on PCs diff --git a/subsystems/DiscordRPC/build.gradle.kts b/subsystems/DiscordRPC/build.gradle.kts index df6cd5c98cc..d309e0170bf 100644 --- a/subsystems/DiscordRPC/build.gradle.kts +++ b/subsystems/DiscordRPC/build.gradle.kts @@ -1,9 +1,10 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 plugins { java `java-library` + id("terasology-common") } apply(from = "$rootDir/config/gradle/common.gradle") @@ -12,4 +13,4 @@ dependencies { implementation(project(":engine")) api("com.jagrosh:DiscordIPC:0.4") implementation("ch.qos.logback:logback-classic:1.2.3") -} \ No newline at end of file +} diff --git a/subsystems/TypeHandlerLibrary/build.gradle.kts b/subsystems/TypeHandlerLibrary/build.gradle.kts index 4fc9250f370..04d08725f1d 100644 --- a/subsystems/TypeHandlerLibrary/build.gradle.kts +++ b/subsystems/TypeHandlerLibrary/build.gradle.kts @@ -1,9 +1,10 @@ -// Copyright 2021 The Terasology Foundation +// Copyright 2022 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 plugins { java `java-library` + id("terasology-common") } apply(from = "$rootDir/config/gradle/publish.gradle") diff --git a/templates/build.gradle b/templates/build.gradle index 3c124902cfb..b05d96aa3fe 100644 --- a/templates/build.gradle +++ b/templates/build.gradle @@ -1,14 +1,9 @@ // Copyright 2020 The Terasology Foundation // SPDX-License-Identifier: Apache-2.0 -// Since SpotBugs and SonarQube in the legacy style have external dependencies we have to have this block here. -// Alternatively we untangle and update the common.gradle / Kotlin Gradle plugin stuff or just remove these two buildscript { repositories { mavenCentral() google() - maven { - url = uri("https://plugins.gradle.org/m2/") - } maven { // required to provide runtime dependencies to build-logic. name = "Terasology Artifactory" @@ -24,14 +19,6 @@ buildscript { allowInsecureProtocol = true // 😱 } } - - dependencies { - //Spotbugs - classpath("gradle.plugin.com.github.spotbugs.snom:spotbugs-gradle-plugin:4.0.0") - - // SonarQube / Cloud scanning - classpath("org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.8") - } } plugins {