diff --git a/doc/Continuous-Integration.md b/doc/Continuous-Integration.md index 13b617c7..8fdaaa01 100644 --- a/doc/Continuous-Integration.md +++ b/doc/Continuous-Integration.md @@ -1,6 +1,6 @@ # Continuous Integration des Coding Style -Gemäß des Grundsatzes **eat your own dogfood** ist dieser Coding Style bereits für die Continuous Integration +Gemäß dem Grundsatz **eat your own dogfood** ist dieser Coding Style bereits für die Continuous Integration in [GitHub Actions](https://github.com/features/actions) und [Jenkins](https://jenkins.io) vorbereitet. ## Maven Konfiguration @@ -15,7 +15,7 @@ U.a. sind die folgenden Plugins vorkonfiguriert: - maven-javadoc-plugin: aktiviert die strikte Prüfung von JavaDoc Kommentaren - maven-jar-plugin: legt einen Modulnamen fest, falls das Projekt in Java 9 oder höher verwendet wird. Außerdem wird ein test-jar konfiguriert, sodass alle Tests (und abstrakte Testklassen) auch als Dependencies genutzt werden können. -- maven-pmd-plugin: prüft das Projekt mit PMD, die Regeln liegen in der Datei [pmd-configuration.xml](../etc/pmd-configuration.xml). +- maven-pmd-plugin: prüft das Projekt mit PMD, die Regeln liegen in den Dateien [pmd-java-configuration.xml](../etc/pmd-java-configuration.xml), [pmd-tests-configuration.xml](../etc/pmd-tests-configuration.xml) und [pmd-javascript-configuration.xml](../etc/pmd-javascript-configuration.xml). - maven-checkstyle-plugin: prüft das Projekt mit CheckStyle, die Regeln liegen in den Dateien [checkstyle-java-configuration.xml](../etc/checkstyle-java-configuration.xml) und [checkstyle-tests-configuration.xml](../etc/checkstyle-tests-configuration.xml). - spotbugs-maven-plugin: prüft das Projekt mit SpotBugs, alle Regeln werden verwendet mit den Ausnahmen definiert in der Datei [spotbugs-exclusion-filter.xml](../etc/spotbugs-exclusion-filter.xml). - org.revapi: prüft, ob die aktuelle Versionsnummer die [semantische Versionierung](https://semver.org) berücksichtigt (source and binary). D.h. es gilt: diff --git a/etc/pmd-configuration.xml b/etc/pmd-java-configuration.xml similarity index 91% rename from etc/pmd-configuration.xml rename to etc/pmd-java-configuration.xml index e7b178ee..dfffd564 100644 --- a/etc/pmd-configuration.xml +++ b/etc/pmd-java-configuration.xml @@ -3,7 +3,7 @@ + xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd"> Ullrich Hafner's PMD rules @@ -11,7 +11,6 @@ - @@ -25,7 +24,6 @@ - @@ -69,16 +67,14 @@ - + - + - + - - diff --git a/etc/pmd-javascript-configuration.xml b/etc/pmd-javascript-configuration.xml new file mode 100644 index 00000000..092b7334 --- /dev/null +++ b/etc/pmd-javascript-configuration.xml @@ -0,0 +1,12 @@ + + + + Ullrich Hafner's PMD rules + + + + + diff --git a/etc/pmd-tests-configuration.xml b/etc/pmd-tests-configuration.xml new file mode 100644 index 00000000..ca49ed31 --- /dev/null +++ b/etc/pmd-tests-configuration.xml @@ -0,0 +1,109 @@ + + + + Ullrich Hafner's PMD rules + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pom.xml b/pom.xml index d7a0e3af..5de3e347 100644 --- a/pom.xml +++ b/pom.xml @@ -86,7 +86,7 @@ 3.2.5 3.3.0 3.21.2 - 6.55.0 + 7.0.0-rc4 3.3.1 10.14.1 4.8.3.1 @@ -490,7 +490,7 @@ config **/checkstyle-configuration.xml - **/pmd-configuration.xml + **/pmd-*-configuration.xml **/spotbugs-exclusion-filter.xml @@ -547,18 +547,14 @@ false false - - etc/pmd-configuration.xml - ${java.version} - true - 50 - - target/generated-test-sources/test-annotations - target/generated-test-sources/assertj-assertions - + + net.sourceforge.pmd + pmd-compat6 + ${pmd.version} + net.sourceforge.pmd pmd-core @@ -569,15 +565,54 @@ pmd-java ${pmd.version} + + net.sourceforge.pmd + pmd-javascript + ${pmd.version} + + + net.sourceforge.pmd + pmd-jsp + ${pmd.version} + - run-pmd + run-pmd-java + + pmd + cpd + + verify + + ${project.build.directory}/pmd-java + + etc/pmd-java-configuration.xml + + false + 50 + + + + run-pmd-tests pmd cpd verify + + ${project.build.directory}/pmd-tests + + etc/pmd-tests-configuration.xml + + true + 100 + + src/main/java + ${project.build.directory}/generated-test-sources/test-annotations + ${project.build.directory}/generated-test-sources/assertj-assertions + + diff --git a/src/main/java/edu/hm/hafner/util/Ensure.java b/src/main/java/edu/hm/hafner/util/Ensure.java index ae0bb43b..92e13308 100644 --- a/src/main/java/edu/hm/hafner/util/Ensure.java +++ b/src/main/java/edu/hm/hafner/util/Ensure.java @@ -13,7 +13,7 @@ import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; /** - * Provides several helper methods to validate method arguments and class invariants thus supporting the design by + * Provides several helper methods to validate method arguments and class invariants, thus supporting the design by * contract concept (DBC). * *

@@ -34,7 +34,6 @@ * @author Ullrich Hafner * @see Design by Contract (Meyer, Bertrand) */ -@SuppressWarnings({"NonBooleanMethodNameMayNotStartWithQuestion", "CyclicClassDependency", "NullAway"}) public final class Ensure { /** * Returns a boolean condition. @@ -44,7 +43,6 @@ public final class Ensure { * * @return a boolean condition */ - @SuppressWarnings("BooleanParameter") @CheckReturnValue public static BooleanCondition that(final boolean value) { return new BooleanCondition(value); @@ -169,7 +167,7 @@ public static void thatStatementIsNeverReached(final String explanation, final O * always thrown */ @FormatMethod - private static void throwException(final String message, final Object... args) { + private static void throwException(final String message, @CheckForNull final Object... args) { throw new AssertionError(String.format(message, args)); } @@ -260,7 +258,6 @@ public static class CollectionCondition extends IterableCondition { * @param value * value of the condition */ - @SuppressWarnings("AssignmentToCollectionOrArrayFieldFromParameter") public CollectionCondition(@CheckForNull final Collection value) { super(value); } @@ -503,6 +500,7 @@ private boolean isBlank() { public static class ObjectCondition { @CheckForNull private final T value; + @CheckForNull private final Object[] additionalValues; /** @@ -524,8 +522,8 @@ public ObjectCondition(@CheckForNull final T value) { * additional values of the condition */ @SuppressFBWarnings("EI2") - @SuppressWarnings({"AssignmentToCollectionOrArrayFieldFromParameter", "PMD.ArrayIsStoredDirectly"}) - public ObjectCondition(@CheckForNull final T value, final Object... additionalValues) { + @SuppressWarnings("PMD.ArrayIsStoredDirectly") + public ObjectCondition(@CheckForNull final T value, @CheckForNull final Object... additionalValues) { this.value = value; this.additionalValues = additionalValues; } @@ -555,12 +553,14 @@ public void isNotNull() { */ @FormatMethod public void isNotNull(final String explanation, final Object... args) { - if (value == null) { + if (value == null || additionalValues == null) { throwNullPointerException(explanation, args); } - for (Object additionalValue : additionalValues) { - if (additionalValue == null) { - throwNullPointerException(explanation, args); + else { + for (Object additionalValue : additionalValues) { + if (additionalValue == null) { + throwNullPointerException(explanation, args); + } } } } @@ -597,7 +597,6 @@ public void isNull() { * @throws AssertionError * if the object is not {@code null} */ - @SuppressWarnings("VariableNotUsedInsideIf") @FormatMethod public void isNull(final String explanation, final Object... args) { if (value != null) { @@ -669,7 +668,6 @@ public static class BooleanCondition { * @param value * value of the condition */ - @SuppressWarnings("BooleanParameter") public BooleanCondition(final boolean value) { this.value = value; } diff --git a/src/main/java/edu/hm/hafner/util/TreeString.java b/src/main/java/edu/hm/hafner/util/TreeString.java index 775cd88e..6593c3ac 100644 --- a/src/main/java/edu/hm/hafner/util/TreeString.java +++ b/src/main/java/edu/hm/hafner/util/TreeString.java @@ -52,7 +52,7 @@ public final class TreeString implements Serializable { } String getLabel() { - return new String(label); + return String.valueOf(label); } /** diff --git a/src/main/java/edu/hm/hafner/util/TreeStringBuilder.java b/src/main/java/edu/hm/hafner/util/TreeStringBuilder.java index 7573e585..8f399c7f 100644 --- a/src/main/java/edu/hm/hafner/util/TreeStringBuilder.java +++ b/src/main/java/edu/hm/hafner/util/TreeStringBuilder.java @@ -118,7 +118,6 @@ public Child intern(final String string) { /** * Makes sure {@link #children} is writable. */ - @SuppressWarnings("PMD.CompareObjectsWithEquals") private void makeWritable() { if (children == NO_CHILDREN) { children = new HashMap<>(); diff --git a/src/test/java/edu/hm/hafner/util/ArchitectureTest.java b/src/test/java/edu/hm/hafner/util/ArchitectureTest.java index 8d550ec4..c8e84e08 100644 --- a/src/test/java/edu/hm/hafner/util/ArchitectureTest.java +++ b/src/test/java/edu/hm/hafner/util/ArchitectureTest.java @@ -13,7 +13,6 @@ * * @author Ullrich Hafner */ -@SuppressWarnings("hideutilityclassconstructor") @AnalyzeClasses(packages = "edu.hm.hafner", importOptions = DoNotIncludeRulesUnderTest.class) class ArchitectureTest { @ArchTest diff --git a/src/test/java/edu/hm/hafner/util/LineRangeListTest.java b/src/test/java/edu/hm/hafner/util/LineRangeListTest.java index 3f1d0e97..318efe8d 100644 --- a/src/test/java/edu/hm/hafner/util/LineRangeListTest.java +++ b/src/test/java/edu/hm/hafner/util/LineRangeListTest.java @@ -1,5 +1,7 @@ package edu.hm.hafner.util; +import java.util.List; + import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.*; @@ -75,15 +77,15 @@ void shouldResizeCorrectly() { @Test void shouldProvideContains() { - LineRangeList last = createThreeElements(); + var last = createThreeElements(); last.remove(new LineRange(4, 5)); assertThat(last).containsExactly(new LineRange(0, 1), new LineRange(2, 3)); - LineRangeList middle = createThreeElements(); + var middle = createThreeElements(); middle.remove(new LineRange(2, 3)); assertThat(middle).containsExactly(new LineRange(0, 1), new LineRange(4, 5)); - LineRangeList first = createThreeElements(); + var first = createThreeElements(); assertThat(first.contains(new LineRange(0, 1))).isTrue(); assertThat(first.contains(new LineRange(2, 3))).isTrue(); assertThat(first.contains(new LineRange(4, 5))).isTrue(); @@ -95,7 +97,7 @@ void shouldProvideContains() { assertThat(first.contains(new LineRange(0, 1))).isFalse(); } - private LineRangeList createThreeElements() { + private List createThreeElements() { var range = new LineRangeList(); range.add(new LineRange(0, 1)); range.add(new LineRange(2, 3)); diff --git a/src/test/java/edu/hm/hafner/util/PackageArchitectureTest.java b/src/test/java/edu/hm/hafner/util/PackageArchitectureTest.java index 7eefe998..3d48bd6a 100644 --- a/src/test/java/edu/hm/hafner/util/PackageArchitectureTest.java +++ b/src/test/java/edu/hm/hafner/util/PackageArchitectureTest.java @@ -17,7 +17,6 @@ * * @author Ullrich Hafner */ -@SuppressWarnings("hideutilityclassconstructor") @AnalyzeClasses(packages = "edu.hm.hafner..", importOptions = DoNotIncludeTests.class) class PackageArchitectureTest { private static final URL PACKAGE_DESIGN = PackageArchitectureTest.class.getResource("/design.puml"); diff --git a/src/test/java/edu/hm/hafner/util/PathUtilTest.java b/src/test/java/edu/hm/hafner/util/PathUtilTest.java index 0c594479..116ca12f 100644 --- a/src/test/java/edu/hm/hafner/util/PathUtilTest.java +++ b/src/test/java/edu/hm/hafner/util/PathUtilTest.java @@ -21,7 +21,7 @@ * @author Ullrich Hafner */ @SuppressFBWarnings("DMI") -@SuppressWarnings("NullAway") +@SuppressWarnings("NullAway") // in tests, we do not care about null values when the path does not exist class PathUtilTest extends ResourceTest { private static final String NOT_EXISTING = "/should/not/exist"; private static final String ILLEGAL = "\0 Null-Byte"; diff --git a/src/test/java/edu/hm/hafner/util/ResourceTest.java b/src/test/java/edu/hm/hafner/util/ResourceTest.java index 3293902b..b669326e 100644 --- a/src/test/java/edu/hm/hafner/util/ResourceTest.java +++ b/src/test/java/edu/hm/hafner/util/ResourceTest.java @@ -30,8 +30,7 @@ * * @author Ullrich Hafner */ -@SuppressWarnings("PMD.AbstractClassWithoutAbstractMethod") -public abstract class ResourceTest { +public class ResourceTest { /** * Returns whether the OS under test is Windows or Unix. * @@ -223,7 +222,7 @@ private String createString(final byte[] bytes) { * * @return the content represented by a byte array */ - @SuppressWarnings({"resource", "IOResourceOpenedButNotSafelyClosed"}) + @SuppressWarnings("IOResourceOpenedButNotSafelyClosed") protected Stream getTextLinesAsStream(final String text) { return new BufferedReader(new StringReader(text)).lines(); } diff --git a/src/test/resources/archunit_ignore_patterns.txt b/src/test/resources/archunit_ignore_patterns.txt index 6cc05935..948a5b7d 100644 --- a/src/test/resources/archunit_ignore_patterns.txt +++ b/src/test/resources/archunit_ignore_patterns.txt @@ -1 +1,5 @@ -// empty up to now, see https://www.archunit.org/userguide/html/000_Index.html#_ignoring_violations \ No newline at end of file +# see https://www.archunit.org/userguide/html/000_Index.html#_ignoring_violations + +# ParserConfiguration.doCheckConsoleLogScanningPermitted does not require @POST or a permission check. +# As-implemented, it does not leak data, even if called illegally. +.*edu.hm.hafner.util.ResourceTest.*