From d3b21dbcb93b8723eafb1daa041d0be0988da7ef Mon Sep 17 00:00:00 2001 From: Gabor Garancsi Date: Wed, 3 Feb 2021 06:52:55 +0100 Subject: [PATCH] Allow loading of Spotbugs properties from external file Some detector can be configured with these properties, also debugging can be turned on if needed. The option name is the same as the one that is used in Spotbugs itself ('findbugs.loadPropertiesFrom') --- .../sputnik/configuration/GeneralOption.java | 2 ++ .../processor/spotbugs/SpotBugsProcessor.java | 28 +++++++++++++++++-- .../spotbugs/SpotBugsProcessorTest.java | 13 ++++++++- .../spotbugs/spotbugs-config.properties | 2 ++ 4 files changed, 42 insertions(+), 3 deletions(-) create mode 100644 src/test/resources/spotbugs/spotbugs-config.properties diff --git a/src/main/java/pl/touk/sputnik/configuration/GeneralOption.java b/src/main/java/pl/touk/sputnik/configuration/GeneralOption.java index ec93c80c..3f3fc779 100644 --- a/src/main/java/pl/touk/sputnik/configuration/GeneralOption.java +++ b/src/main/java/pl/touk/sputnik/configuration/GeneralOption.java @@ -45,10 +45,12 @@ public enum GeneralOption implements ConfigurationOption { PMD_SHOW_VIOLATION_DETAILS("pmd.showViolationDetails", "Show violation details and URL", "false"), FINDBUGS_ENABLED("findbugs.enabled", "FindBugs enabled", "false"), + FINDBUGS_LOAD_PROPERTIES_FROM("findbugs.loadPropertiesFrom", "FindBugs properties file", ""), FINDBUGS_INCLUDE_FILTER("findbugs.includeFilter", "FindBugs include filter file", ""), FINDBUGS_EXCLUDE_FILTER("findbugs.excludeFilter", "FindBugs exclude filter file", ""), SPOTBUGS_ENABLED("spotbugs.enabled", "SpotBugs enabled", "false"), + SPOTBUGS_LOAD_PROPERTIES_FROM("spotbugs.loadPropertiesFrom", "SpotBugs properties file", ""), SPOTBUGS_INCLUDE_FILTER("spotbugs.includeFilter", "SpotBugs include filter file", ""), SPOTBUGS_EXCLUDE_FILTER("spotbugs.excludeFilter", "SpotBugs exclude filter file", ""), diff --git a/src/main/java/pl/touk/sputnik/processor/spotbugs/SpotBugsProcessor.java b/src/main/java/pl/touk/sputnik/processor/spotbugs/SpotBugsProcessor.java index 050b71ad..8366dc65 100644 --- a/src/main/java/pl/touk/sputnik/processor/spotbugs/SpotBugsProcessor.java +++ b/src/main/java/pl/touk/sputnik/processor/spotbugs/SpotBugsProcessor.java @@ -1,11 +1,17 @@ package pl.touk.sputnik.processor.spotbugs; +import java.net.MalformedURLException; +import java.nio.file.Paths; +import java.util.Optional; +import java.util.stream.Stream; + import edu.umd.cs.findbugs.ClassScreener; import edu.umd.cs.findbugs.DetectorFactoryCollection; import edu.umd.cs.findbugs.FindBugs2; import edu.umd.cs.findbugs.IClassScreener; import edu.umd.cs.findbugs.Priorities; import edu.umd.cs.findbugs.Project; +import edu.umd.cs.findbugs.SystemProperties; import edu.umd.cs.findbugs.config.UserPreferences; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -36,8 +42,8 @@ public SpotBugsProcessor(@NotNull Configuration configuration) { @Nullable @Override public ReviewResult process(@NotNull Review review) { - FindBugs2 spotBugs = createFindBugs2(review); - try { + loadSystemProperties(); + try (FindBugs2 spotBugs = createFindBugs2(review)) { spotBugs.execute(); } catch (Exception e) { log.error("SpotBugs processing error", e); @@ -46,6 +52,17 @@ public ReviewResult process(@NotNull Review review) { return collectorBugReporter.getReviewResult(); } + private void loadSystemProperties() { + getPropertiesFileLocation().ifPresent(propertiesFileLocation -> { + try { + SystemProperties.loadPropertiesFromURL(Paths.get(propertiesFileLocation).toUri().toURL()); + log.info("Using SpotBugs properties file {}", propertiesFileLocation); + } catch (MalformedURLException e) { + log.error("Invalid location for properties file: {}", propertiesFileLocation); + } + }); + } + @NotNull @Override public String getName() { @@ -102,6 +119,13 @@ private IClassScreener createClassScreener(@NotNull Review review) { return classScreener; } + private Optional getPropertiesFileLocation() { + return Stream.of(GeneralOption.SPOTBUGS_LOAD_PROPERTIES_FROM, GeneralOption.FINDBUGS_LOAD_PROPERTIES_FROM) + .map(config::getProperty) + .filter(StringUtils::isNotBlank) + .findFirst(); + } + @Nullable private String getIncludeFilterFilename() { String includeFilterFilename = config.getProperty(GeneralOption.SPOTBUGS_INCLUDE_FILTER); diff --git a/src/test/java/pl/touk/sputnik/processor/spotbugs/SpotBugsProcessorTest.java b/src/test/java/pl/touk/sputnik/processor/spotbugs/SpotBugsProcessorTest.java index 1b50d222..15b4fdc9 100644 --- a/src/test/java/pl/touk/sputnik/processor/spotbugs/SpotBugsProcessorTest.java +++ b/src/test/java/pl/touk/sputnik/processor/spotbugs/SpotBugsProcessorTest.java @@ -4,6 +4,8 @@ import com.google.common.collect.ImmutableMap; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; + +import edu.umd.cs.findbugs.SystemProperties; import pl.touk.sputnik.TestEnvironment; import pl.touk.sputnik.configuration.ConfigurationSetup; import pl.touk.sputnik.configuration.GeneralOption; @@ -24,7 +26,10 @@ class SpotBugsProcessorTest extends TestEnvironment { @BeforeEach void setUp() { - config = new ConfigurationSetup().setUp(ImmutableMap.of(GeneralOption.BUILD_TOOL.getKey(), GRADLE)); + config = new ConfigurationSetup().setUp(ImmutableMap.of( + GeneralOption.BUILD_TOOL.getKey(), GRADLE, + GeneralOption.SPOTBUGS_LOAD_PROPERTIES_FROM.getKey(), "src/test/resources/spotbugs/spotbugs-config.properties" + )); spotBugsProcessor = new SpotBugsProcessor(config); } @@ -54,4 +59,10 @@ void shouldReturnEmptyWhenNoFilesToReview() { assertThat(reviewResult.getViolations()).isEmpty(); } + @Test + void shouldLoadPropertiesFromExternalLocation() { + ReviewResult reviewResult = spotBugsProcessor.process(nonExistentReview()); + + assertThat(SystemProperties.getBoolean("findbugs.de.comment")).isTrue(); + } } diff --git a/src/test/resources/spotbugs/spotbugs-config.properties b/src/test/resources/spotbugs/spotbugs-config.properties new file mode 100644 index 00000000..66649009 --- /dev/null +++ b/src/test/resources/spotbugs/spotbugs-config.properties @@ -0,0 +1,2 @@ +# Don't report empty catch blocks if a source comment is found in the block. +findbugs.de.comment = true