diff --git a/src/main/java/pl/touk/sputnik/configuration/GeneralOption.java b/src/main/java/pl/touk/sputnik/configuration/GeneralOption.java index 75286f55..4b8c26ee 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