From 84c5887f8867712f6c7cd4353e48a05e0cca98f8 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 19 Jul 2022 20:40:39 +0200 Subject: [PATCH 1/6] [doc] Fix missing additional rulesets Fixes #4051 --- docs/pages/release_notes.md | 1 + .../net/sourceforge/pmd/docs/GenerateRuleDocsCmd.java | 9 +++++---- .../net/sourceforge/pmd/docs/RuleSetResolverTest.java | 9 +++++++++ 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 56690a23a0..2084697dbf 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -43,6 +43,7 @@ Being based on a proper Antlr grammar, CPD can: ### Fixed Issues * core * [#4031](https://github.com/pmd/pmd/issues/4031): \[core] If report is written to stdout, stdout should not be closed + * [#4051](https://github.com/pmd/pmd/issues/4051): \[doc] Additional rulesets are not listed in documentation * java * [#4015](https://github.com/pmd/pmd/issues/4015): \[java] Support JDK 19 * java-bestpractices diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/GenerateRuleDocsCmd.java b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/GenerateRuleDocsCmd.java index d5b3002a6b..b434d4e8f5 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/GenerateRuleDocsCmd.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/GenerateRuleDocsCmd.java @@ -47,16 +47,17 @@ public final class GenerateRuleDocsCmd { System.out.println("Generated docs in " + (System.currentTimeMillis() - start) + " ms"); } + static final Pattern ADDITIONAL_RULESET_PATTERN = Pattern.compile("^.+" + Pattern.quote(File.separator) + "pmd-\\w+" + + Pattern.quote(IOUtil.normalizePath(File.separator + Paths.get("src", "main", "resources", "rulesets").toString()) + File.separator) + + "\\w+" + Pattern.quote(File.separator) + "\\w+.xml$"); + public static List findAdditionalRulesets(Path basePath) { try { List additionalRulesets = new ArrayList<>(); - Pattern rulesetPattern = Pattern.compile("^.+" + Pattern.quote(File.separator) + "pmd-\\w+" - + Pattern.quote(IOUtil.normalizePath(File.separator + Paths.get("src", "main", "resources", "rulesets").toString() + File.separator)) - + "\\w+" + Pattern.quote(File.separator) + "\\w+.xml$"); Files.walkFileTree(basePath, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { - if (rulesetPattern.matcher(file.toString()).matches()) { + if (ADDITIONAL_RULESET_PATTERN.matcher(file.toString()).matches()) { additionalRulesets.add(file.toString()); } diff --git a/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleSetResolverTest.java b/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleSetResolverTest.java index 3d85da8daa..7894f8c97f 100644 --- a/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleSetResolverTest.java +++ b/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleSetResolverTest.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd.docs; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.nio.file.FileSystems; @@ -34,6 +36,8 @@ public class RuleSetResolverTest { filterRuleSets(additionalRulesets); + assertFalse(additionalRulesets.isEmpty()); + RuleSetFactory ruleSetFactory = RulesetsFactoryUtils.defaultFactory(); for (String filename : additionalRulesets) { try { @@ -44,6 +48,11 @@ public class RuleSetResolverTest { } } + @Test + public void testAdditionalRulesetPattern() { + assertTrue(GenerateRuleDocsCmd.ADDITIONAL_RULESET_PATTERN.matcher("/home/foo/pmd/pmd-java/src/main/resources/rulesets/java/quickstart.xml").matches()); + } + private void filterRuleSets(List additionalRulesets) { Iterator it = additionalRulesets.iterator(); while (it.hasNext()) { From c31278504c1daad06af61daa62fc0b33652ba7a7 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 21 Jul 2022 10:53:50 +0200 Subject: [PATCH 2/6] Fix test under Windows --- .../java/net/sourceforge/pmd/docs/RuleSetResolverTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleSetResolverTest.java b/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleSetResolverTest.java index 7894f8c97f..bafaed3623 100644 --- a/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleSetResolverTest.java +++ b/pmd-doc/src/test/java/net/sourceforge/pmd/docs/RuleSetResolverTest.java @@ -50,7 +50,8 @@ public class RuleSetResolverTest { @Test public void testAdditionalRulesetPattern() { - assertTrue(GenerateRuleDocsCmd.ADDITIONAL_RULESET_PATTERN.matcher("/home/foo/pmd/pmd-java/src/main/resources/rulesets/java/quickstart.xml").matches()); + String filePath = IOUtil.normalizePath("/home/foo/pmd/pmd-java/src/main/resources/rulesets/java/quickstart.xml"); + assertTrue(GenerateRuleDocsCmd.ADDITIONAL_RULESET_PATTERN.matcher(filePath).matches()); } private void filterRuleSets(List additionalRulesets) { From bf5828d7d176d493d165589e497c350257efd748 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 28 Jul 2022 14:59:08 +0200 Subject: [PATCH 3/6] [doc] Fix jdoc link in release notes --- docs/pages/release_notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index b45e8879f0..a41cae583f 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -88,7 +88,7 @@ Being based on a proper Antlr grammar, CPD can: but it is no longer supported with Java 19 Preview. * The interface {% jdoc core::cpd.renderer.CPDRenderer %} is deprecated. For custom CPD renderers the new interface {% jdoc core::cpd.renderer.CPDReportRenderer %} should be used. -* The class {% jdoc test::testframework.TestDescriptor %} is deprecated, replaced with {% jdoc test-schema::testframework.RuleTestDescriptor %}. +* The class {% jdoc test::testframework.TestDescriptor %} is deprecated, replaced with {% jdoc test-schema::test.schema.RuleTestDescriptor %}. * Many methods of {% jdoc test::testframework.RuleTst %} have been deprecated as internal API. #### Experimental APIs From ee38e7d81a0733b18da23a61c9558d90016b602b Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 29 Jul 2022 10:11:35 +0200 Subject: [PATCH 4/6] [core] Add "--debug" flag for CPD Fixes #3796 --- docs/pages/pmd/userdocs/cpd/cpd.md | 3 ++ docs/pages/release_notes.md | 6 ++++ .../java/net/sourceforge/pmd/cpd/CPD.java | 16 ++++++++++ .../sourceforge/pmd/cpd/CPDConfiguration.java | 13 ++++++++ .../pmd/cpd/CPDCommandLineInterfaceTest.java | 32 ++++++++++++++++--- 5 files changed, 65 insertions(+), 5 deletions(-) diff --git a/docs/pages/pmd/userdocs/cpd/cpd.md b/docs/pages/pmd/userdocs/cpd/cpd.md index d909eb4f2f..67b81492be 100644 --- a/docs/pages/pmd/userdocs/cpd/cpd.md +++ b/docs/pages/pmd/userdocs/cpd/cpd.md @@ -73,6 +73,9 @@ Novice as much as advanced readers may want to [read on on Refactoring Guru](htt description="Sources code language." default="java" %} + {% include custom/cli_option_row.html options="--debug,--verbose" + description="Debug mode. Prints more log output." + %} {% include custom/cli_option_row.html options="--encoding" description="Character encoding to use when processing files. If not specified, CPD uses the system default encoding." %} diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a41cae583f..dc7f15c512 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -44,6 +44,7 @@ Being based on a proper Antlr grammar, CPD can: * apex * [#4056](https://github.com/pmd/pmd/pull/4056): \[apex] ApexSOQLInjection: Add support count query * core + * [#3796](https://github.com/pmd/pmd/issues/3796): \[core] CPD should also provide a `--debug` flag * [#4021](https://github.com/pmd/pmd/pull/4021): \[core] CPD: Add total number of tokens to XML reports * [#4031](https://github.com/pmd/pmd/issues/4031): \[core] If report is written to stdout, stdout should not be closed * [#4051](https://github.com/pmd/pmd/issues/4051): \[doc] Additional rulesets are not listed in documentation @@ -66,6 +67,11 @@ Being based on a proper Antlr grammar, CPD can: ### API Changes +#### CPD CLI + +* CPD has a new CLI option `--debug`. This option has the same behavior as in PMD. It enables more verbose + logging output. + #### Rule Test Framework * The module "pmd-test", which contains support classes to write rule tests, now **requires Java 8**. If you depend on diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPD.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPD.java index 0ffc7b397d..b7a39e7112 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPD.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPD.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; +import java.util.logging.ConsoleHandler; import java.util.logging.Level; import java.util.logging.Logger; @@ -28,6 +29,7 @@ import net.sourceforge.pmd.util.IOUtil; import net.sourceforge.pmd.util.database.DBMSMetadata; import net.sourceforge.pmd.util.database.DBURI; import net.sourceforge.pmd.util.database.SourceObject; +import net.sourceforge.pmd.util.log.ScopedLogHandlersManager; public class CPD { private static final Logger LOGGER = Logger.getLogger(CPD.class.getName()); @@ -54,8 +56,10 @@ public class CPD { } public void go() { + LOGGER.fine("Running match algorithm on " + source.size() + " files..."); matchAlgorithm = new MatchAlgorithm(source, tokens, configuration.getMinimumTileSize(), listener); matchAlgorithm.findMatches(); + LOGGER.fine("Finished: " + matchAlgorithm.getMatches().size() + " duplicates found"); } public Iterator getMatches() { @@ -80,6 +84,7 @@ public class CPD { if (!dir.exists()) { throw new FileNotFoundException("Couldn't find directory " + dir); } + LOGGER.fine("Searching directory " + dir + " for files"); FileFinder finder = new FileFinder(); // TODO - could use SourceFileSelector here add(finder.findFilesFrom(dir, configuration.filenameFilter(), recurse)); @@ -145,6 +150,7 @@ public class CPD { } private void addAndThrowLexicalError(SourceCode sourceCode) throws IOException { + LOGGER.fine("Tokenizing " + sourceCode.getFileName()); configuration.tokenizer().tokenize(sourceCode, tokens); listener.addedFile(1, new File(sourceCode.getFileName())); source.put(sourceCode.getFileName(), sourceCode); @@ -206,6 +212,13 @@ public class CPD { return statusCode; } + final Level logLevel = arguments.isDebug() ? Level.FINER : Level.INFO; + final ScopedLogHandlersManager logHandlerManager = new ScopedLogHandlersManager(logLevel, new ConsoleHandler()); + final Level oldLogLevel = LOGGER.getLevel(); + // Need to do this, since the static logger has already been initialized + // at this point + LOGGER.setLevel(logLevel); + CPD cpd = new CPD(arguments); try { @@ -233,6 +246,9 @@ public class CPD { e.printStackTrace(); LOGGER.severe(CliMessages.errorDetectedMessage(1, CPDCommandLineInterface.PROGRAM_NAME)); statusCode = StatusCode.ERROR; + } finally { + logHandlerManager.close(); + LOGGER.setLevel(oldLogLevel); } return statusCode; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java index abda86e5e0..82906e807b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java @@ -141,6 +141,9 @@ public class CPDConfiguration extends AbstractConfiguration { description = "By default CPD exits with status 4 if code duplications are found. Disable this option with '-failOnViolation false' to exit with 0 instead and just write the report.") private boolean failOnViolation = true; + @Parameter(names = { "--debug", "--verbose" }, description = "Debug mode.") + private boolean debug = false; + // this has to be a public static class, so that JCommander can use it! public static class LanguageConverter implements IStringConverter { @@ -540,4 +543,14 @@ public class CPDConfiguration extends AbstractConfiguration { public void setFailOnViolation(boolean failOnViolation) { this.failOnViolation = failOnViolation; } + + @Override + public boolean isDebug() { + return debug; + } + + @Override + public void setDebug(boolean debug) { + this.debug = debug; + } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDCommandLineInterfaceTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDCommandLineInterfaceTest.java index ce680e4c5b..9dcabdc35a 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDCommandLineInterfaceTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDCommandLineInterfaceTest.java @@ -4,6 +4,7 @@ package net.sourceforge.pmd.cpd; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -17,9 +18,9 @@ import java.util.Collection; import java.util.List; import java.util.Map; -import org.junit.Assert; import org.junit.Rule; import org.junit.Test; +import org.junit.contrib.java.lang.system.SystemErrRule; import org.junit.contrib.java.lang.system.SystemOutRule; import org.junit.rules.TemporaryFolder; @@ -39,6 +40,10 @@ public class CPDCommandLineInterfaceTest { @Rule public final SystemOutRule log = new SystemOutRule().enableLog().muteForSuccessfulTests(); + + @Rule + public final SystemErrRule errLog = new SystemErrRule().enableLog().muteForSuccessfulTests(); + @Rule public final JavaUtilLoggingRule loggingRule = new JavaUtilLoggingRule(PMD.class.getPackage().getName()).mute(); @Rule @@ -65,8 +70,8 @@ public class CPDCommandLineInterfaceTest { CPD.StatusCode statusCode = CPD.runCpd("--minimum-tokens", "340", "--language", "java", "--files", SRC_DIR, "--format", "xml"); final String expectedFilesXml = getExpectedFileEntriesXml(NUMBER_OF_TOKENS.keySet()); - Assert.assertEquals(CPD.StatusCode.OK, statusCode); - Assert.assertEquals("" + "\n" + "" + "\n" + expectedFilesXml + "", log.getLog()); + assertEquals(CPD.StatusCode.OK, statusCode); + assertEquals("" + "\n" + "" + "\n" + expectedFilesXml + "", log.getLog()); } @Test @@ -80,12 +85,29 @@ public class CPDCommandLineInterfaceTest { CPD.StatusCode statusCode = CPD.runCpd("--minimum-tokens", "340", "--language", "java", "--filelist", filelist.toAbsolutePath().toString(), "--format", "xml", "-failOnViolation", "true"); - Assert.assertEquals(CPD.StatusCode.OK, statusCode); - Assert.assertEquals("" + "\n" + "" + "\n" + expectedFilesXml + "", log.getLog()); + assertEquals(CPD.StatusCode.OK, statusCode); + assertEquals("" + "\n" + "" + "\n" + expectedFilesXml + "", log.getLog()); assertTrue(loggingRule.getLog().contains("Some deprecated options were used on the command-line, including -failOnViolation")); assertTrue(loggingRule.getLog().contains("Consider replacing it with --fail-on-violation")); // only one parameter is logged assertFalse(loggingRule.getLog().contains("Some deprecated options were used on the command-line, including --filelist")); assertFalse(loggingRule.getLog().contains("Consider replacing it with --file-list")); } + + @Test + public void testDebugLogging() { + CPD.StatusCode statusCode = CPD.runCpd("--minimum-tokens", "340", "--language", "java", "--files", + SRC_DIR, "--debug"); + assertEquals(CPD.StatusCode.OK, statusCode); + assertTrue(errLog.getLog().contains("Tokenizing ")); // this is a debug logging + } + + @Test + public void testNormalLogging() { + loggingRule.clear(); + CPD.StatusCode statusCode = CPD.runCpd("--minimum-tokens", "340", "--language", "java", "--files", + SRC_DIR); + assertEquals(CPD.StatusCode.OK, statusCode); + assertFalse(errLog.getLog().contains("Tokenizing ")); // this is a debug logging + } } From a36032b2bfab942ba8949808de217aa29950baca Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Fri, 29 Jul 2022 12:33:43 +0200 Subject: [PATCH 5/6] Fixups from review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Clément Fournier --- .../sourceforge/pmd/cpd/CPDCommandLineInterfaceTest.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDCommandLineInterfaceTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDCommandLineInterfaceTest.java index 9dcabdc35a..a01b355b7d 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDCommandLineInterfaceTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cpd/CPDCommandLineInterfaceTest.java @@ -4,6 +4,9 @@ package net.sourceforge.pmd.cpd; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -99,7 +102,7 @@ public class CPDCommandLineInterfaceTest { CPD.StatusCode statusCode = CPD.runCpd("--minimum-tokens", "340", "--language", "java", "--files", SRC_DIR, "--debug"); assertEquals(CPD.StatusCode.OK, statusCode); - assertTrue(errLog.getLog().contains("Tokenizing ")); // this is a debug logging + assertThat(errLog.getLog(), containsString("Tokenizing ")); // this is a debug logging } @Test @@ -108,6 +111,6 @@ public class CPDCommandLineInterfaceTest { CPD.StatusCode statusCode = CPD.runCpd("--minimum-tokens", "340", "--language", "java", "--files", SRC_DIR); assertEquals(CPD.StatusCode.OK, statusCode); - assertFalse(errLog.getLog().contains("Tokenizing ")); // this is a debug logging + assertThat(errLog.getLog(), not(containsString("Tokenizing "))); // this is a debug logging } } From 6128631acb420119b65126273db3a5013ff09729 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 30 Jul 2022 09:59:57 +0200 Subject: [PATCH 6/6] [doc] Add SPONSORS.md --- SPONSORS.md | 10 ++++++++++ docs/pages/release_notes.md | 6 ++++++ 2 files changed, 16 insertions(+) create mode 100644 SPONSORS.md diff --git a/SPONSORS.md b/SPONSORS.md new file mode 100644 index 0000000000..4bbe1c7b55 --- /dev/null +++ b/SPONSORS.md @@ -0,0 +1,10 @@ +# PMD's sponsors + +Many thanks to all our sponsors: + +* [Matt Hargett](https://github.com/matthargett) (@matthargett) + +If you also want to sponsor PMD, you have two options: + +* [Sponsor @pmd on GitHub Sponsors](https://github.com/sponsors/pmd) +* [PMD - Open Collective](https://opencollective.com/pmd) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a41cae583f..7a305420e2 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -112,6 +112,12 @@ You can identify them with the `@InternalApi` annotation. You'll also get a depr * {%jdoc !!core::cpd.CPDConfiguration#getCPDRendererFromString(java.lang.String,java.lang.String) %} * {%jdoc core::cpd.renderer.CPDRendererAdapter %} +### Financial Contributions + +Many thanks to our sponsors: + +* [Matt Hargett](https://github.com/matthargett) (@matthargett) + ### External Contributions * [#3984](https://github.com/pmd/pmd/pull/3984): \[java] Fix AddEmptyString false-negative issue - [@LiGaOg](https://github.com/LiGaOg) * [#3988](https://github.com/pmd/pmd/pull/3988): \[java] Modify WhileLoopWithLiteralBoolean to meet the missing case #3455 - [@VoidxHoshi](https://github.com/VoidxHoshi)