From d3e68d795b07d0cbc94e38ac85e708f7d5fef107 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sat, 12 Nov 2022 20:39:12 +0100 Subject: [PATCH 01/22] Add --relativize-paths-with --- .../net/sourceforge/pmd/PMDConfiguration.java | 42 +++++++++++- .../java/net/sourceforge/pmd/PmdAnalysis.java | 5 ++ .../java/net/sourceforge/pmd/ant/PMDTask.java | 18 ++++++ .../pmd/ant/internal/PMDTaskImpl.java | 12 ++-- .../sourceforge/pmd/cli/PMDParameters.java | 12 ++++ .../pmd/cli/PmdParametersParseResult.java | 4 +- .../pmd/internal/util/FileCollectionUtil.java | 34 +++++++--- .../pmd/lang/document/FileCollector.java | 64 +++++++++++++++++-- .../pmd/lang/document/NioTextFile.java | 3 +- .../pmd/util/datasource/FileDataSource.java | 16 ++++- .../net/sourceforge/pmd/ant/PMDTaskTest.java | 18 +++++- .../pmd/lang/document/FileCollectorTest.java | 2 +- .../sourceforge/pmd/ant/xml/pmdtasktest.xml | 12 +++- 13 files changed, 211 insertions(+), 31 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java index 023c017912..770c238639 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java @@ -7,6 +7,7 @@ package net.sourceforge.pmd; import java.io.File; import java.io.IOException; import java.net.URI; +import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; @@ -126,6 +127,7 @@ public class PMDConfiguration extends AbstractConfiguration { private boolean benchmark; private AnalysisCache analysisCache = new NoopAnalysisCache(); private boolean ignoreIncrementalAnalysis; + private final List relativizeRoots = new ArrayList<>(); /** * Get the suppress marker. This is the source level marker used to indicate @@ -913,8 +915,8 @@ public class PMDConfiguration extends AbstractConfiguration { */ public void setAnalysisCacheLocation(final String cacheLocation) { setAnalysisCache(cacheLocation == null - ? new NoopAnalysisCache() - : new FileAnalysisCache(new File(cacheLocation))); + ? new NoopAnalysisCache() + : new FileAnalysisCache(new File(cacheLocation))); } @@ -940,4 +942,40 @@ public class PMDConfiguration extends AbstractConfiguration { public boolean isIgnoreIncrementalAnalysis() { return ignoreIncrementalAnalysis; } + + /** + * Set the path used to shorten paths output in the report. + * The path does not need to exist. If it exists, it must point + * to a directory and not a file. See {@link #getRelativizeRoots()} + * for the interpretation. + * + *

Setting to null is not recommended as it is only used for + * compatibility with the older {@link #isReportShortNames()} functionality. + * It will possibly be disallowed with PMD 7. The default value is + * null. + * + * @param path A path + * + * @throws IllegalArgumentException If the path points to a file + */ + public void addRelativizeRoot(Path path) { + // TODO symlinks? + this.relativizeRoots.add(Objects.requireNonNull(path)); + + if (Files.isRegularFile(path)) { + throw new IllegalArgumentException("Relativize root should be a directory: " + path); + } + } + + /** + * Returns the path used to shorten paths output in the report. + *

+ */ + public List getRelativizeRoots() { + return Collections.unmodifiableList(relativizeRoots); + } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java b/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java index abec9ff1b9..94fbb890eb 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PmdAnalysis.java @@ -5,6 +5,7 @@ package net.sourceforge.pmd; import java.io.IOException; +import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -86,8 +87,12 @@ public final class PmdAnalysis implements AutoCloseable { config.getLanguageVersionDiscoverer(), reporter ); + for (Path path : config.getRelativizeRoots()) { + this.collector.relativizeWith(path); + } final Level logLevel = configuration.isDebug() ? Level.TRACE : Level.INFO; this.reporter.setLevel(logLevel); + } /** diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/ant/PMDTask.java b/pmd-core/src/main/java/net/sourceforge/pmd/ant/PMDTask.java index ba9367ad15..d77d42f45e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/ant/PMDTask.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/ant/PMDTask.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd.ant; +import java.io.File; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; @@ -25,7 +27,9 @@ public class PMDTask extends Task { private final List filesets = new ArrayList<>(); private boolean failOnError; private boolean failOnRuleViolation; + @Deprecated private boolean shortFilenames; + private String relativizePathsWith; private String suppressMarker; private String rulesetFiles; private boolean noRuleSetCompatibility; @@ -264,4 +268,18 @@ public class PMDTask extends Task { public void setNoCache(boolean noCache) { this.noCache = noCache; } + + public void setRelativizePathsWith(String relativizePathsWith) { + this.relativizePathsWith = relativizePathsWith; + } + + public List getRelativizeRoots() { + List paths = new ArrayList<>(); + if (relativizePathsWith != null) { + for (String file : relativizePathsWith.split(File.pathSeparator)) { + paths.add(Paths.get(file)); + } + } + return paths; + } } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java b/pmd-core/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java index 6d649cc643..68dde8b8b1 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java @@ -8,7 +8,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; -import org.apache.commons.lang3.StringUtils; import org.apache.tools.ant.AntClassLoader; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.DirectoryScanner; @@ -48,6 +47,9 @@ public class PMDTaskImpl { public PMDTaskImpl(PMDTask task) { configuration.setReportShortNames(task.isShortFilenames()); + for (java.nio.file.Path path : task.getRelativizeRoots()) { + configuration.addRelativizeRoot(path); + } configuration.setSuppressMarker(task.getSuppressMarker()); this.failOnError = task.isFailOnError(); this.failOnRuleViolation = task.isFailOnRuleViolation(); @@ -94,7 +96,6 @@ public class PMDTaskImpl { @SuppressWarnings("PMD.CloseResource") final List reportShortNamesPaths = new ArrayList<>(); - List fullInputPath = new ArrayList<>(); List ruleSetPaths = expandRuleSetPaths(); // don't let PmdAnalysis.create create rulesets itself. @@ -113,7 +114,6 @@ public class PMDTaskImpl { } final String commonInputPath = ds.getBasedir().getPath(); - fullInputPath.add(commonInputPath); if (configuration.isReportShortNames()) { reportShortNamesPaths.add(commonInputPath); } @@ -124,7 +124,7 @@ public class PMDTaskImpl { pmd.addRenderer(formatter.toRenderer(project, reportShortNamesPaths)); } - pmd.addRenderer(getLogRenderer(StringUtils.join(fullInputPath, ","))); + pmd.addRenderer(getLogRenderer()); report = pmd.performAnalysisAndCollectReport(); if (failOnError && pmd.getReporter().numErrors() > 0) { @@ -154,7 +154,7 @@ public class PMDTaskImpl { return paths; } - private AbstractRenderer getLogRenderer(final String commonInputPath) { + private AbstractRenderer getLogRenderer() { return new AbstractRenderer("log", "Logging renderer") { @Override public void start() { @@ -163,7 +163,7 @@ public class PMDTaskImpl { @Override public void startFileAnalysis(DataSource dataSource) { - project.log("Processing file " + dataSource.getNiceFileName(false, commonInputPath), + project.log("Processing file " + dataSource.getNiceFileName(false, null), Project.MSG_VERBOSE); } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java index b2a39a2a65..15a5db1962 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java @@ -4,6 +4,7 @@ package net.sourceforge.pmd.cli; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.Properties; @@ -31,6 +32,7 @@ import com.beust.jcommander.validators.PositiveInteger; @InternalApi public class PMDParameters { + static final String RELATIVIZE_PATHS_WITH = "--relativize-paths-with"; @Parameter(names = { "--rulesets", "-rulesets", "-R" }, description = "Path to a ruleset xml file. " + "The path may reference a resource on the classpath of the application, be a local file system path, or a URL. " @@ -121,6 +123,13 @@ public class PMDParameters { + "If this option is not specified, the report is rendered to standard output.") private String reportfile = null; + @Parameter(names = { RELATIVIZE_PATHS_WITH }, + arity = 1, + description = "Path relative to which directories are rendered in the report." + + "This option can be used to render shorter paths. " + + "This option replaces --short-names since PMD 6.52.0.") + private String relativizePathRoot = null; + @Parameter(names = { "-version", "-v" }, description = "Specify version of a language PMD should use.") private String version = null; @@ -235,6 +244,9 @@ public class PMDParameters { configuration.setReportFormat(this.getFormat()); configuration.setBenchmark(this.isBenchmark()); configuration.setDebug(this.isDebug()); + if (relativizePathRoot != null) { + configuration.addRelativizeRoot(Paths.get(this.relativizePathRoot)); + } configuration.setMinimumPriority(this.getMinimumPriority()); configuration.setReportFile(this.getReportfile()); configuration.setReportProperties(this.getProperties()); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PmdParametersParseResult.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PmdParametersParseResult.java index f38d691939..acff763ca0 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PmdParametersParseResult.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PmdParametersParseResult.java @@ -137,6 +137,7 @@ public final class PmdParametersParseResult { /** Map of deprecated option to suggested replacement. */ private static final Map SUGGESTED_REPLACEMENT; + static { Map m = new LinkedHashMap<>(); @@ -153,7 +154,8 @@ public final class PmdParametersParseResult { m.put("-threads", "--threads"); m.put("-benchmark", "--benchmark"); m.put("-stress", "--stress"); - m.put("-shortnames", "--short-names"); + m.put("-shortnames", PMDParameters.RELATIVIZE_PATHS_WITH); + m.put("--short-names", PMDParameters.RELATIVIZE_PATHS_WITH); m.put("-showsuppressed", "--show-suppressed"); m.put("-suppressmarker", "--suppress-marker"); m.put("-minimumpriority", "--minimum-priority"); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java index e8041d3430..58ce54151c 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java @@ -12,6 +12,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.sql.SQLException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Set; @@ -46,12 +47,14 @@ public final class FileCollectionUtil { return result; } + @Deprecated public static FileCollector collectFiles(PMDConfiguration configuration, Set languages, MessageReporter reporter) { FileCollector collector = collectFiles(configuration, reporter); collector.filterLanguages(languages); return collector; } + @Deprecated private static FileCollector collectFiles(PMDConfiguration configuration, MessageReporter reporter) { FileCollector collector = FileCollector.newCollector( configuration.getLanguageVersionDiscoverer(), @@ -66,8 +69,22 @@ public final class FileCollectionUtil { collector.setCharset(configuration.getSourceEncoding()); } + // This is to be removed when --short-names is removed. + // If the new --relativize-paths-with option is specified (!= null), it takes precedence. + boolean legacyShortNamesBehavior = + configuration.getRelativizeRoots().isEmpty() && configuration.isReportShortNames(); + if (configuration.getInputPaths() != null) { - collectFiles(collector, configuration.getInputPaths()); + for (Path path : configuration.getInputPathList()) { + try { + if (legacyShortNamesBehavior) { + collector.relativizeWith(path.toString()); + } + addRoot(collector, path); + } catch (IOException e) { + collector.getReporter().errorEx("Error collecting " + path, e); + } + } } if (configuration.getInputUri() != null) { @@ -90,11 +107,11 @@ public final class FileCollectionUtil { } - public static void collectFiles(FileCollector collector, String fileLocations) { - for (String rootLocation : fileLocations.split(",")) { + public static void collectFiles(FileCollector collector, List fileLocations) { + for (String rootLocation : fileLocations) { try { - collector.relativizeWith(rootLocation); - addRoot(collector, rootLocation); + // no relativizeWith call + addRoot(collector, Paths.get(rootLocation)); } catch (IOException e) { collector.getReporter().errorEx("Error collecting " + rootLocation, e); } @@ -115,11 +132,10 @@ public final class FileCollectionUtil { collector.getReporter().errorEx("Error reading {0}", new Object[] { fileListLocation }, e); return; } - collectFiles(collector, filePaths); + collectFiles(collector, Arrays.asList(filePaths.split(","))); } - private static void addRoot(FileCollector collector, String rootLocation) throws IOException { - Path path = Paths.get(rootLocation); + private static void addRoot(FileCollector collector, Path path) throws IOException { if (!Files.exists(path)) { collector.getReporter().error("No such file {0}", path); return; @@ -127,7 +143,7 @@ public final class FileCollectionUtil { if (Files.isDirectory(path)) { collector.addDirectory(path); - } else if (rootLocation.endsWith(".zip") || rootLocation.endsWith(".jar")) { + } else if (path.toString().endsWith(".zip") || path.toString().endsWith(".jar")) { @SuppressWarnings("PMD.CloseResource") FileSystem fs = collector.addZipFile(path); if (fs == null) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java index 8db97175c3..398510bf70 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java @@ -51,7 +51,9 @@ public final class FileCollector implements AutoCloseable { private Charset charset = StandardCharsets.UTF_8; private final LanguageVersionDiscoverer discoverer; private final MessageReporter reporter; - private final List relativizeRoots = new ArrayList<>(); + @Deprecated + private final List legacyRelativizeRoots = new ArrayList<>(); + private final List relativizeRootPaths = new ArrayList<>(); private boolean closed; // construction @@ -239,14 +241,18 @@ public final class FileCollector implements AutoCloseable { } private String getDisplayName(Path file) { - return getDisplayName(file, relativizeRoots); + if (!relativizeRootPaths.isEmpty()) { + // takes precedence over legacy behavior + return getDisplayName(file, relativizeRootPaths); + } + return getDisplayNameLegacy(file, legacyRelativizeRoots); } /** * Return the textfile's display name. * test only */ - static String getDisplayName(Path file, List relativizeRoots) { + static String getDisplayNameLegacy(Path file, List relativizeRoots) { String fileName = file.toString(); for (String root : relativizeRoots) { if (file.startsWith(root)) { @@ -260,6 +266,34 @@ public final class FileCollector implements AutoCloseable { return fileName; } + /** + * Return the textfile's display name. Takes the shortest path we + * can construct from the relativize roots. + * test only + */ + static String getDisplayName(Path file, List relativizeRoots) { + Path best = file; + for (Path root : relativizeRoots) { + Path candidate; + if (isFileSystemRoot(root)) { + // Absolutize the path. + candidate = file.toAbsolutePath(); + } else { + candidate = root.relativize(file); + } + // take the shortest path. + if (candidate.getNameCount() < best.getNameCount()) { + best = candidate; + } + } + return best.toString(); + } + + /** Return whether the path is the root path (/). */ + private static boolean isFileSystemRoot(Path root) { + return root.isAbsolute() && root.getNameCount() == 0; + } + /** * Add a directory recursively using {@link #addFile(Path)} on @@ -344,12 +378,30 @@ public final class FileCollector implements AutoCloseable { * will have a path id of {@code /tmp/src/main/java/org/foo.java}, and a * display name of {@code main/java/org/foo.java}. * - * This only matters for files added from a {@link Path} object. + *

This only matters for files added from a {@link Path} object. * * @param prefix Prefix to relativize (if a directory, include a trailing slash) + * + * @deprecated Use {@link #relativizeWith(Path)} */ + @Deprecated public void relativizeWith(String prefix) { - this.relativizeRoots.add(Objects.requireNonNull(prefix)); + this.legacyRelativizeRoots.add(Objects.requireNonNull(prefix)); + } + + /** + * Add a prefix that is used to relativize file paths as their display name. + * For instance, when adding a file {@code /tmp/src/main/java/org/foo.java}, + * and relativizing with {@code /tmp/src/}, the registered {@link TextFile} + * will have a path id of {@code /tmp/src/main/java/org/foo.java}, and a + * display name of {@code main/java/org/foo.java}. + * + *

This only matters for files added from a {@link Path} object. + * + * @param path Path with which to relativize + */ + public void relativizeWith(Path path) { + this.relativizeRootPaths.add(Objects.requireNonNull(path)); } // filtering @@ -359,7 +411,7 @@ public final class FileCollector implements AutoCloseable { */ public void exclude(FileCollector excludeCollector) { HashSet toExclude = new HashSet<>(excludeCollector.allFilesToProcess); - for (Iterator iterator = allFilesToProcess.iterator(); iterator.hasNext();) { + for (Iterator iterator = allFilesToProcess.iterator(); iterator.hasNext(); ) { TextFile file = iterator.next(); if (toExclude.contains(file)) { reporter.trace("Excluding file {0}", file.getPathId()); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NioTextFile.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NioTextFile.java index 16ab46f93f..4f15a84cdd 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NioTextFile.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NioTextFile.java @@ -36,6 +36,7 @@ class NioTextFile implements TextFile { AssertionUtil.requireParamNotNull("path", path); AssertionUtil.requireParamNotNull("charset", charset); AssertionUtil.requireParamNotNull("language version", languageVersion); + AssertionUtil.requireParamNotNull("display name", displayName); this.displayName = displayName; this.path = path; @@ -74,7 +75,7 @@ class NioTextFile implements TextFile { @Override public DataSource toDataSourceCompat() { - return new LanguageAwareDataSource(new FileDataSource(path.toFile()), languageVersion); + return new LanguageAwareDataSource(new FileDataSource(path.toFile(), displayName), languageVersion); } @Override diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/datasource/FileDataSource.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/datasource/FileDataSource.java index b0624e75b7..49155e74b1 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/datasource/FileDataSource.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/datasource/FileDataSource.java @@ -19,13 +19,22 @@ import net.sourceforge.pmd.util.datasource.internal.AbstractDataSource; */ public class FileDataSource extends AbstractDataSource { private final File file; + private final String displayName; /** - * @param file - * the file to read + * @param file the file to read */ public FileDataSource(File file) { this.file = file; + this.displayName = null; + } + + /** + * @param file the file to read + */ + public FileDataSource(File file, String displayName) { + this.file = file; + this.displayName = displayName; } @Override @@ -39,6 +48,9 @@ public class FileDataSource extends AbstractDataSource { } private String glomName(boolean shortNames, String inputPaths, File file) { + if (displayName != null) { + return displayName; + } if (shortNames) { if (inputPaths != null) { List inputPathPrefixes = Arrays.asList(inputPaths.split(",")); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java index fba597a5f1..c30a8c5ce8 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java @@ -10,6 +10,8 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.BuildFileRule; @@ -74,11 +76,23 @@ public class PMDTaskTest { public void testWithShortFilenames() throws IOException { buildRule.executeTarget("testWithShortFilenames"); - try (InputStream in = new FileInputStream("target/pmd-ant-test.txt")) { + try (InputStream in = Files.newInputStream(Paths.get("target/pmd-ant-test.txt"))) { String actual = IOUtil.readToString(in, StandardCharsets.UTF_8); // remove any trailing newline actual = actual.replaceAll("\n|\r", ""); - Assert.assertEquals("sample.dummy:0:\tSampleXPathRule:\tTest Rule 2", actual); + Assert.assertEquals("src/sample.dummy:0:\tSampleXPathRule:\tTest Rule 2", actual); + } + } + + @Test + public void testRelativizeWith() throws IOException { + buildRule.executeTarget("testRelativizeWith"); + + try (InputStream in = Files.newInputStream(Paths.get("target/pmd-ant-test.txt"))) { + String actual = IOUtil.readToString(in, StandardCharsets.UTF_8); + // remove any trailing newline + actual = actual.replaceAll("\n|\r", ""); + Assert.assertEquals("src/sample.dummy:0:\tSampleXPathRule:\tTest Rule 2", actual); } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/FileCollectorTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/FileCollectorTest.java index e74f3dbce4..fb5bd97c0c 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/FileCollectorTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/FileCollectorTest.java @@ -101,7 +101,7 @@ public class FileCollectorTest { @Test public void testRelativize() throws IOException { - String displayName = FileCollector.getDisplayName(Paths.get("a", "b", "c"), listOf(Paths.get("a").toString())); + String displayName = FileCollector.getDisplayNameLegacy(Paths.get("a", "b", "c"), listOf(Paths.get("a").toString())); assertEquals(displayName, Paths.get("b", "c").toString()); } diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml b/pmd-core/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml index 71c482915a..7f75a16143 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml @@ -29,7 +29,17 @@ ${pmd.home}/src/test/resources/rulesets/dummy/basic.xml - + + + + + + + + + ${pmd.home}/src/test/resources/rulesets/dummy/basic.xml + + From 99b24b702ff3cad00d6cc0217d8ced0944c5c08f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 13 Nov 2022 13:57:14 +0100 Subject: [PATCH 02/22] Add tests, dedup collected files --- .../main/java/net/sourceforge/pmd/PMD.java | 13 +++- .../net/sourceforge/pmd/PMDConfiguration.java | 33 +++++++--- .../pmd/ant/internal/PMDTaskImpl.java | 4 +- .../sourceforge/pmd/cli/PMDParameters.java | 42 ++++++++++-- .../pmd/internal/util/FileCollectionUtil.java | 1 - .../pmd/lang/document/FileCollector.java | 26 ++++---- .../net/sourceforge/pmd/cli/CoreCliTest.java | 51 ++++++++++++++ .../sourceforge/pmd/cli/PMDFilelistTest.java | 66 +++++++++++++++---- .../net/sourceforge/pmd/cli/FakeRuleset2.xml | 21 ++++++ .../net/sourceforge/pmd/cli/filelist4.txt | 4 ++ .../pmd/cli/otherSrc/somefile.dummy | 0 11 files changed, 214 insertions(+), 47 deletions(-) create mode 100644 pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml create mode 100644 pmd-core/src/test/resources/net/sourceforge/pmd/cli/filelist4.txt create mode 100644 pmd-core/src/test/resources/net/sourceforge/pmd/cli/otherSrc/somefile.dummy diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java index 632761e002..618b4fe18a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java @@ -22,6 +22,8 @@ import java.util.logging.ConsoleHandler; import java.util.logging.Level; import java.util.logging.Logger; +import org.apache.commons.lang3.exception.ExceptionUtils; + import net.sourceforge.pmd.annotation.InternalApi; import net.sourceforge.pmd.benchmark.TextTimingReportRenderer; import net.sourceforge.pmd.benchmark.TimeTracker; @@ -472,7 +474,16 @@ public class PMD { System.err.println(CliMessages.runWithHelpFlagMessage()); return StatusCode.ERROR; } - return runPmd(parseResult.toConfiguration()); + + PMDConfiguration conf; + try { + conf = parseResult.toConfiguration(); + return runPmd(conf); + } catch (IllegalArgumentException e) { + System.err.println("Cannot start analysis: " + e); + LOG.fine(ExceptionUtils.getStackTrace(e)); + return StatusCode.ERROR; + } } private static void printErrorDetected(int errors) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java index 770c238639..8aad402651 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java @@ -949,14 +949,13 @@ public class PMDConfiguration extends AbstractConfiguration { * to a directory and not a file. See {@link #getRelativizeRoots()} * for the interpretation. * - *

Setting to null is not recommended as it is only used for - * compatibility with the older {@link #isReportShortNames()} functionality. - * It will possibly be disallowed with PMD 7. The default value is - * null. + *

If several paths are added, the shortest paths possible are + * built. * * @param path A path * - * @throws IllegalArgumentException If the path points to a file + * @throws IllegalArgumentException If the path points to a file, and not a directory + * @throws NullPointerException If the path is null */ public void addRelativizeRoot(Path path) { // TODO symlinks? @@ -967,12 +966,28 @@ public class PMDConfiguration extends AbstractConfiguration { } } + /** - * Returns the path used to shorten paths output in the report. + * Add several paths to shorten paths that are output in the report. + * See {@link #addRelativizeRoot(Path)}. + * + * @param paths A list of non-null paths + * + * @throws IllegalArgumentException If any path points to a file, and not a directory + * @throws NullPointerException If the list, or any path in the list is null + */ + public void addRelativizeRoots(List paths) { + for (Path path : paths) { + addRelativizeRoot(path); + } + } + + /** + * Returns the paths used to shorten paths output in the report. *

    - *
  • If the path is {@code /} (root), then paths are rendered as absolute. - *
  • If the path is null, then paths are not touched (unless {@link #isReportShortNames()} is true) - *
  • Otherwise, the path is a directory. + *
  • If the list is empty, then paths are not touched (unless {@link #isReportShortNames()} is true) + *
  • If the list is non-empty, then source file paths are relativized with all the items in the list. + * The shortest of these relative paths is taken as the display name of the file. *
*/ public List getRelativizeRoots() { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java b/pmd-core/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java index 68dde8b8b1..e21d474c04 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java @@ -47,9 +47,7 @@ public class PMDTaskImpl { public PMDTaskImpl(PMDTask task) { configuration.setReportShortNames(task.isShortFilenames()); - for (java.nio.file.Path path : task.getRelativizeRoots()) { - configuration.addRelativizeRoot(path); - } + configuration.addRelativizeRoots(task.getRelativizeRoots()); configuration.setSuppressMarker(task.getSuppressMarker()); this.failOnError = task.isFailOnError(); this.failOnRuleViolation = task.isFailOnRuleViolation(); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java index 15a5db1962..61cfe94b88 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd.cli; +import java.nio.file.Files; +import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; @@ -123,12 +125,17 @@ public class PMDParameters { + "If this option is not specified, the report is rendered to standard output.") private String reportfile = null; - @Parameter(names = { RELATIVIZE_PATHS_WITH }, - arity = 1, + @Parameter(names = { RELATIVIZE_PATHS_WITH, "-z" }, + variableArity = true, description = "Path relative to which directories are rendered in the report." - + "This option can be used to render shorter paths. " - + "This option replaces --short-names since PMD 6.52.0.") - private String relativizePathRoot = null; + + "This option allows shortening directories in the report; " + + "without it, paths are rendered as absolute paths. " + + "The option can be repeated, in which case the shortest relative path." + + "If / is mentioned (root path), then the paths will be rendered as absolute." + + "This option replaces --short-names since PMD 6.52.0.", + validateValueWith = PathToRelativizeRootValidator.class, + converter = StringToPathConverter.class) + private List relativizePathRoot = new ArrayList<>(); @Parameter(names = { "-version", "-v" }, description = "Specify version of a language PMD should use.") private String version = null; @@ -227,6 +234,27 @@ public class PMDParameters { } } + public static class PathToRelativizeRootValidator implements IValueValidator> { + + @Override + public void validate(String name, List value) throws ParameterException { + for (Path p : value) { + if (Files.isRegularFile(p)) { + throw new ParameterException("Expected a directory path for option " + name + ", found a file: " + p); + } + } + } + } + + + public static class StringToPathConverter implements IStringConverter { + + @Override + public Path convert(String value) { + return Paths.get(value); + } + } + /** * Converts these parameters into a configuration. @@ -244,8 +272,8 @@ public class PMDParameters { configuration.setReportFormat(this.getFormat()); configuration.setBenchmark(this.isBenchmark()); configuration.setDebug(this.isDebug()); - if (relativizePathRoot != null) { - configuration.addRelativizeRoot(Paths.get(this.relativizePathRoot)); + for (Path path: relativizePathRoot) { + configuration.addRelativizeRoot(path); } configuration.setMinimumPriority(this.getMinimumPriority()); configuration.setReportFile(this.getReportfile()); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java index 58ce54151c..3fd8529b0e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java @@ -110,7 +110,6 @@ public final class FileCollectionUtil { public static void collectFiles(FileCollector collector, List fileLocations) { for (String rootLocation : fileLocations) { try { - // no relativizeWith call addRoot(collector, Paths.get(rootLocation)); } catch (IOException e) { collector.getReporter().errorEx("Error collecting " + rootLocation, e); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java index 398510bf70..099a9f5b63 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java @@ -24,6 +24,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.Iterator; +import java.util.LinkedHashSet; import java.util.List; import java.util.Objects; import java.util.Set; @@ -46,7 +47,7 @@ import net.sourceforge.pmd.util.log.MessageReporter; @SuppressWarnings("PMD.CloseResource") public final class FileCollector implements AutoCloseable { - private final List allFilesToProcess = new ArrayList<>(); + private final Set allFilesToProcess = new LinkedHashSet<>(); private final List resourcesToClose = new ArrayList<>(); private Charset charset = StandardCharsets.UTF_8; private final LanguageVersionDiscoverer discoverer; @@ -84,6 +85,7 @@ public final class FileCollector implements AutoCloseable { if (closed) { throw new IllegalStateException("Collector was closed!"); } + List allFilesToProcess = new ArrayList<>(this.allFilesToProcess); Collections.sort(allFilesToProcess, new Comparator() { @Override public int compare(TextFile o1, TextFile o2) { @@ -135,8 +137,7 @@ public final class FileCollector implements AutoCloseable { } LanguageVersion languageVersion = discoverLanguage(file.toString()); if (languageVersion != null) { - addFileImpl(new NioTextFile(file, charset, languageVersion, getDisplayName(file))); - return true; + return addFileImpl(new NioTextFile(file, charset, languageVersion, getDisplayName(file))); } return false; } @@ -158,8 +159,7 @@ public final class FileCollector implements AutoCloseable { return false; } NioTextFile nioTextFile = new NioTextFile(file, charset, discoverer.getDefaultLanguageVersion(language), getDisplayName(file)); - addFileImpl(nioTextFile); - return true; + return addFileImpl(nioTextFile); } /** @@ -172,8 +172,7 @@ public final class FileCollector implements AutoCloseable { public boolean addFile(TextFile textFile) { AssertionUtil.requireParamNotNull("textFile", textFile); if (checkContextualVersion(textFile)) { - addFileImpl(textFile); - return true; + return addFileImpl(textFile); } return false; } @@ -190,16 +189,19 @@ public final class FileCollector implements AutoCloseable { LanguageVersion version = discoverLanguage(pathId); if (version != null) { - addFileImpl(new StringTextFile(sourceContents, pathId, pathId, version)); - return true; + return addFileImpl(new StringTextFile(sourceContents, pathId, pathId, version)); } return false; } - private void addFileImpl(TextFile textFile) { + private boolean addFileImpl(TextFile textFile) { reporter.trace("Adding file {0} (lang: {1}) ", textFile.getPathId(), textFile.getLanguageVersion().getTerseName()); - allFilesToProcess.add(textFile); + if (allFilesToProcess.add(textFile)) { + return true; + } + reporter.trace("File was already collected, skipping"); + return false; } private LanguageVersion discoverLanguage(String file) { @@ -411,7 +413,7 @@ public final class FileCollector implements AutoCloseable { */ public void exclude(FileCollector excludeCollector) { HashSet toExclude = new HashSet<>(excludeCollector.allFilesToProcess); - for (Iterator iterator = allFilesToProcess.iterator(); iterator.hasNext(); ) { + for (Iterator iterator = allFilesToProcess.iterator(); iterator.hasNext();) { TextFile file = iterator.next(); if (toExclude.contains(file)) { reporter.trace("Excluding file {0}", file.getPathId()); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java index 0c5f6a62e3..ef90c37187 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java @@ -22,6 +22,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; +import java.util.List; import java.util.logging.Logger; import org.hamcrest.Matcher; @@ -36,7 +37,10 @@ import org.junit.rules.TemporaryFolder; import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.PMD.StatusCode; +import net.sourceforge.pmd.RuleContext; import net.sourceforge.pmd.junit.JavaUtilLoggingRule; +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.rule.MockRule; import net.sourceforge.pmd.util.IOUtil; /** @@ -45,6 +49,7 @@ import net.sourceforge.pmd.util.IOUtil; public class CoreCliTest { private static final String DUMMY_RULESET = "net/sourceforge/pmd/cli/FakeRuleset.xml"; + private static final String DUMMY_RULESET_WITH_VIOLATIONS = "net/sourceforge/pmd/cli/FakeRuleset2.xml"; private static final String STRING_TO_REPLACE = "__should_be_replaced__"; @Rule @@ -127,6 +132,42 @@ public class CoreCliTest { assertTrue("Report file should have been created", Files.exists(reportFile)); } + @Test + public void testNoRelativizeWith() { + startCapturingErrAndOut(); + runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS); + + assertThat(outStreamCaptor.getLog(), containsString(srcDir.resolve("someSource.dummy").toString())); + } + + @Test + public void testRelativizeWith() { + startCapturingErrAndOut(); + runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.getParent()); + + assertThat(outStreamCaptor.getLog(), not(containsString(srcDir.resolve("someSource.dummy").toString()))); + assertThat(outStreamCaptor.getLog(), containsString("src/someSource.dummy")); + } + + @Test + public void testRelativizeWithMultiple() { + startCapturingErrAndOut(); + runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.getParent(), srcDir); + + assertThat(outStreamCaptor.getLog(), not(containsString(srcDir.resolve("someSource.dummy").toString()))); + assertThat(outStreamCaptor.getLog(), containsString("someSource.dummy")); + } + + @Test + public void testRelativizeWithFileIsError() { + startCapturingErrAndOut(); + runPmd(StatusCode.ERROR, "--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.resolve("someSource.dummy")); + + assertThat(errStreamCaptor.getLog(), containsString( + "Expected a directory path for option --relativize-paths-with, found a file: " + + srcDir.resolve("someSource.dummy"))); + } + @Test public void testFileCollectionWithUnknownFiles() throws IOException { Path reportFile = tempRoot().resolve("out/reportFile.txt"); @@ -283,5 +324,15 @@ public class CoreCliTest { assertEquals("Exit code", expectedExitCode, actualExitCode); } + public static class FooRule extends MockRule { + + @Override + public void apply(List nodes, RuleContext ctx) { + for (Node node : nodes) { + ctx.addViolation(node); + } + } + } + } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java index fe83f0d256..5de23080bb 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java @@ -6,7 +6,11 @@ package net.sourceforge.pmd.cli; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.endsWith; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; +import java.nio.file.Paths; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; @@ -18,16 +22,18 @@ import org.junit.Test; import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.PMDConfiguration; +import net.sourceforge.pmd.PmdAnalysis; import net.sourceforge.pmd.lang.DummyLanguageModule; import net.sourceforge.pmd.lang.Language; +import net.sourceforge.pmd.lang.document.TextFile; import net.sourceforge.pmd.util.datasource.DataSource; public class PMDFilelistTest { + + private final Set languages = new HashSet(Arrays.asList(new DummyLanguageModule())); + @Test public void testGetApplicableFiles() { - Set languages = new HashSet<>(); - languages.add(new DummyLanguageModule()); - PMDConfiguration configuration = new PMDConfiguration(); configuration.setInputFilePath("src/test/resources/net/sourceforge/pmd/cli/filelist.txt"); @@ -39,24 +45,59 @@ public class PMDFilelistTest { @Test public void testGetApplicableFilesMultipleLines() { - Set languages = new HashSet<>(); - languages.add(new DummyLanguageModule()); - PMDConfiguration configuration = new PMDConfiguration(); configuration.setInputFilePath("src/test/resources/net/sourceforge/pmd/cli/filelist2.txt"); List applicableFiles = PMD.getApplicableFiles(configuration, languages); - Assert.assertEquals(3, applicableFiles.size()); + Assert.assertEquals(2, applicableFiles.size()); assertThat(applicableFiles.get(0).getNiceFileName(false, ""), endsWith("anotherfile.dummy")); assertThat(applicableFiles.get(1).getNiceFileName(false, ""), endsWith("somefile.dummy")); - assertThat(applicableFiles.get(2).getNiceFileName(false, ""), endsWith("somefile.dummy")); + } + + @Test + public void testRelativizeWith() { + PMDConfiguration conf = new PMDConfiguration(); + conf.setInputFilePath(Paths.get("src/test/resources/net/sourceforge/pmd/cli/filelist2.txt")); + conf.addRelativizeRoot(Paths.get("src/test/resources")); + try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { + List files = pmd.files().getCollectedFiles(); + assertThat(files, hasSize(2)); + assertThat(files.get(0).getDisplayName(), equalTo("net/sourceforge/pmd/cli/src/anotherfile.dummy")); + assertThat(files.get(1).getDisplayName(), equalTo("net/sourceforge/pmd/cli/src/somefile.dummy")); + } + } + + @Test + public void testRelativizeWithOtherDir() { + PMDConfiguration conf = new PMDConfiguration(); + conf.setInputFilePath(Paths.get("src/test/resources/net/sourceforge/pmd/cli/filelist4.txt")); + conf.addRelativizeRoot(Paths.get("src/test/resources/net/sourceforge/pmd/cli/src")); + try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { + List files = pmd.files().getCollectedFiles(); + assertThat(files, hasSize(3)); + assertThat(files.get(0).getDisplayName(), equalTo("../otherSrc/somefile.dummy")); + assertThat(files.get(1).getDisplayName(), equalTo("anotherfile.dummy")); + assertThat(files.get(2).getDisplayName(), equalTo("somefile.dummy")); + } + } + + @Test + public void testRelativizeWithSeveralDirs() { + PMDConfiguration conf = new PMDConfiguration(); + conf.setInputFilePath(Paths.get("src/test/resources/net/sourceforge/pmd/cli/filelist4.txt")); + conf.addRelativizeRoot(Paths.get("src/test/resources/net/sourceforge/pmd/cli/src")); + conf.addRelativizeRoot(Paths.get("src/test/resources/net/sourceforge/pmd/cli/otherSrc")); + try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { + List files = pmd.files().getCollectedFiles(); + assertThat(files, hasSize(3)); + assertThat(files.get(0).getDisplayName(), equalTo("somefile.dummy")); + assertThat(files.get(1).getDisplayName(), equalTo("anotherfile.dummy")); + assertThat(files.get(2).getDisplayName(), equalTo("somefile.dummy")); + } } @Test public void testGetApplicatbleFilesWithIgnores() { - Set languages = new HashSet<>(); - languages.add(new DummyLanguageModule()); - PMDConfiguration configuration = new PMDConfiguration(); configuration.setInputFilePath("src/test/resources/net/sourceforge/pmd/cli/filelist3.txt"); configuration.setIgnoreFilePath("src/test/resources/net/sourceforge/pmd/cli/ignorelist.txt"); @@ -69,9 +110,6 @@ public class PMDFilelistTest { @Test public void testGetApplicatbleFilesWithDirAndIgnores() { - Set languages = new HashSet<>(); - languages.add(new DummyLanguageModule()); - PMDConfiguration configuration = new PMDConfiguration(); configuration.setInputPaths("src/test/resources/net/sourceforge/pmd/cli/src"); configuration.setIgnoreFilePath("src/test/resources/net/sourceforge/pmd/cli/ignorelist.txt"); diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml b/pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml new file mode 100644 index 0000000000..33a996d1ba --- /dev/null +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml @@ -0,0 +1,21 @@ + + + + + Ruleset used by test RuleSetFactoryTest + + + + +Just for test + + 3 + + + + + + diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/cli/filelist4.txt b/pmd-core/src/test/resources/net/sourceforge/pmd/cli/filelist4.txt new file mode 100644 index 0000000000..9f7ddef003 --- /dev/null +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/cli/filelist4.txt @@ -0,0 +1,4 @@ +src/test/resources/net/sourceforge/pmd/cli/src/somefile.dummy, +src/test/resources/net/sourceforge/pmd/cli/otherSrc/somefile.dummy, +src/test/resources/net/sourceforge/pmd/cli/src/anotherfile.dummy +src/test/resources/net/sourceforge/pmd/cli/src/somefile.dummy diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/cli/otherSrc/somefile.dummy b/pmd-core/src/test/resources/net/sourceforge/pmd/cli/otherSrc/somefile.dummy new file mode 100644 index 0000000000..e69de29bb2 From e0c0bd924126df5d4387651877a0bc87fbeedef6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 13 Nov 2022 15:20:31 +0100 Subject: [PATCH 03/22] Test -z / --- .../pmd/lang/document/FileCollector.java | 14 ++++++- .../sourceforge/pmd/cli/PMDFilelistTest.java | 39 +++++++++++++------ 2 files changed, 39 insertions(+), 14 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java index 099a9f5b63..fdc003fd78 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java @@ -278,8 +278,11 @@ public final class FileCollector implements AutoCloseable { for (Path root : relativizeRoots) { Path candidate; if (isFileSystemRoot(root)) { - // Absolutize the path. - candidate = file.toAbsolutePath(); + // Absolutize the path. Since the relativize roots are + // sorted by ascending length, this should be the first in the list + // (so another root can override it). + best = file.toAbsolutePath(); + continue; } else { candidate = root.relativize(file); } @@ -404,6 +407,13 @@ public final class FileCollector implements AutoCloseable { */ public void relativizeWith(Path path) { this.relativizeRootPaths.add(Objects.requireNonNull(path)); + Collections.sort(relativizeRootPaths, new Comparator() { + @Override + public int compare(Path o1, Path o2) { + int lengthCmp = Integer.compare(o1.getNameCount(), o2.getNameCount()); + return lengthCmp == 0 ? o1.compareTo(o2) : lengthCmp; + } + }); } // filtering diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java index 5de23080bb..0dc033d95c 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java @@ -30,12 +30,13 @@ import net.sourceforge.pmd.util.datasource.DataSource; public class PMDFilelistTest { + private static final String RESOURCE_PREFIX = "src/test/resources/net/sourceforge/pmd/cli/"; private final Set languages = new HashSet(Arrays.asList(new DummyLanguageModule())); @Test public void testGetApplicableFiles() { PMDConfiguration configuration = new PMDConfiguration(); - configuration.setInputFilePath("src/test/resources/net/sourceforge/pmd/cli/filelist.txt"); + configuration.setInputFilePath(RESOURCE_PREFIX + "filelist.txt"); List applicableFiles = PMD.getApplicableFiles(configuration, languages); Assert.assertEquals(2, applicableFiles.size()); @@ -46,7 +47,7 @@ public class PMDFilelistTest { @Test public void testGetApplicableFilesMultipleLines() { PMDConfiguration configuration = new PMDConfiguration(); - configuration.setInputFilePath("src/test/resources/net/sourceforge/pmd/cli/filelist2.txt"); + configuration.setInputFilePath(RESOURCE_PREFIX + "filelist2.txt"); List applicableFiles = PMD.getApplicableFiles(configuration, languages); Assert.assertEquals(2, applicableFiles.size()); @@ -57,7 +58,7 @@ public class PMDFilelistTest { @Test public void testRelativizeWith() { PMDConfiguration conf = new PMDConfiguration(); - conf.setInputFilePath(Paths.get("src/test/resources/net/sourceforge/pmd/cli/filelist2.txt")); + conf.setInputFilePath(Paths.get(RESOURCE_PREFIX + "filelist2.txt")); conf.addRelativizeRoot(Paths.get("src/test/resources")); try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { List files = pmd.files().getCollectedFiles(); @@ -70,8 +71,8 @@ public class PMDFilelistTest { @Test public void testRelativizeWithOtherDir() { PMDConfiguration conf = new PMDConfiguration(); - conf.setInputFilePath(Paths.get("src/test/resources/net/sourceforge/pmd/cli/filelist4.txt")); - conf.addRelativizeRoot(Paths.get("src/test/resources/net/sourceforge/pmd/cli/src")); + conf.setInputFilePath(Paths.get(RESOURCE_PREFIX + "filelist4.txt")); + conf.addRelativizeRoot(Paths.get(RESOURCE_PREFIX + "src")); try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { List files = pmd.files().getCollectedFiles(); assertThat(files, hasSize(3)); @@ -84,9 +85,9 @@ public class PMDFilelistTest { @Test public void testRelativizeWithSeveralDirs() { PMDConfiguration conf = new PMDConfiguration(); - conf.setInputFilePath(Paths.get("src/test/resources/net/sourceforge/pmd/cli/filelist4.txt")); - conf.addRelativizeRoot(Paths.get("src/test/resources/net/sourceforge/pmd/cli/src")); - conf.addRelativizeRoot(Paths.get("src/test/resources/net/sourceforge/pmd/cli/otherSrc")); + conf.setInputFilePath(Paths.get(RESOURCE_PREFIX + "filelist4.txt")); + conf.addRelativizeRoot(Paths.get(RESOURCE_PREFIX + "src")); + conf.addRelativizeRoot(Paths.get(RESOURCE_PREFIX + "otherSrc")); try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { List files = pmd.files().getCollectedFiles(); assertThat(files, hasSize(3)); @@ -96,11 +97,25 @@ public class PMDFilelistTest { } } + @Test + public void testUseAbsolutePaths() { + PMDConfiguration conf = new PMDConfiguration(); + conf.setInputFilePath(Paths.get(RESOURCE_PREFIX + "filelist4.txt")); + conf.addRelativizeRoot(Paths.get("/")); + try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { + List files = pmd.files().getCollectedFiles(); + assertThat(files, hasSize(3)); + assertThat(files.get(0).getDisplayName(), equalTo(Paths.get(RESOURCE_PREFIX, "otherSrc", "somefile.dummy").toAbsolutePath().toString())); + assertThat(files.get(1).getDisplayName(), equalTo(Paths.get(RESOURCE_PREFIX, "src", "anotherfile.dummy").toAbsolutePath().toString())); + assertThat(files.get(2).getDisplayName(), equalTo(Paths.get(RESOURCE_PREFIX, "src", "somefile.dummy").toAbsolutePath().toString())); + } + } + @Test public void testGetApplicatbleFilesWithIgnores() { PMDConfiguration configuration = new PMDConfiguration(); - configuration.setInputFilePath("src/test/resources/net/sourceforge/pmd/cli/filelist3.txt"); - configuration.setIgnoreFilePath("src/test/resources/net/sourceforge/pmd/cli/ignorelist.txt"); + configuration.setInputFilePath(RESOURCE_PREFIX + "filelist3.txt"); + configuration.setIgnoreFilePath(RESOURCE_PREFIX + "ignorelist.txt"); List applicableFiles = PMD.getApplicableFiles(configuration, languages); Assert.assertEquals(2, applicableFiles.size()); @@ -111,8 +126,8 @@ public class PMDFilelistTest { @Test public void testGetApplicatbleFilesWithDirAndIgnores() { PMDConfiguration configuration = new PMDConfiguration(); - configuration.setInputPaths("src/test/resources/net/sourceforge/pmd/cli/src"); - configuration.setIgnoreFilePath("src/test/resources/net/sourceforge/pmd/cli/ignorelist.txt"); + configuration.setInputPaths(RESOURCE_PREFIX + "src"); + configuration.setIgnoreFilePath(RESOURCE_PREFIX + "ignorelist.txt"); List applicableFiles = PMD.getApplicableFiles(configuration, languages); Assert.assertEquals(4, applicableFiles.size()); From b45ab080210678b0352d8402abe8e699f58573e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Fournier?= Date: Sun, 13 Nov 2022 16:19:29 +0100 Subject: [PATCH 04/22] Add tests for zip file paths --- .../pmd/internal/util/FileCollectionUtil.java | 10 +-- .../pmd/lang/document/FileCollector.java | 80 +++++++++++++++--- .../net/sourceforge/pmd/cli/ZipFileTest.java | 67 +++++++++++++++ .../sourceforge/pmd/cli/zipWithSources.zip | Bin 0 -> 1108 bytes 4 files changed, 138 insertions(+), 19 deletions(-) create mode 100644 pmd-core/src/test/java/net/sourceforge/pmd/cli/ZipFileTest.java create mode 100644 pmd-core/src/test/resources/net/sourceforge/pmd/cli/zipWithSources.zip diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java index 3fd8529b0e..357d7f847e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java @@ -6,7 +6,6 @@ package net.sourceforge.pmd.internal.util; import java.io.IOException; import java.io.Reader; -import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; @@ -143,14 +142,7 @@ public final class FileCollectionUtil { if (Files.isDirectory(path)) { collector.addDirectory(path); } else if (path.toString().endsWith(".zip") || path.toString().endsWith(".jar")) { - @SuppressWarnings("PMD.CloseResource") - FileSystem fs = collector.addZipFile(path); - if (fs == null) { - return; - } - for (Path zipRoot : fs.getRootDirectories()) { - collector.addFileOrDirectory(zipRoot); - } + collector.addZipFile(path); } else if (Files.isRegularFile(path)) { collector.addFile(path); } else { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java index fdc003fd78..484e215c81 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java @@ -30,6 +30,7 @@ import java.util.Objects; import java.util.Set; import net.sourceforge.pmd.PmdAnalysis; +import net.sourceforge.pmd.annotation.Experimental; import net.sourceforge.pmd.annotation.InternalApi; import net.sourceforge.pmd.internal.util.AssertionUtil; import net.sourceforge.pmd.lang.Language; @@ -52,6 +53,7 @@ public final class FileCollector implements AutoCloseable { private Charset charset = StandardCharsets.UTF_8; private final LanguageVersionDiscoverer discoverer; private final MessageReporter reporter; + private final String outerFsDisplayName; @Deprecated private final List legacyRelativizeRoots = new ArrayList<>(); private final List relativizeRootPaths = new ArrayList<>(); @@ -59,9 +61,10 @@ public final class FileCollector implements AutoCloseable { // construction - private FileCollector(LanguageVersionDiscoverer discoverer, MessageReporter reporter) { + private FileCollector(LanguageVersionDiscoverer discoverer, MessageReporter reporter, String outerFsDisplayName) { this.discoverer = discoverer; this.reporter = reporter; + this.outerFsDisplayName = outerFsDisplayName; } /** @@ -70,7 +73,7 @@ public final class FileCollector implements AutoCloseable { */ @InternalApi public static FileCollector newCollector(LanguageVersionDiscoverer discoverer, MessageReporter reporter) { - return new FileCollector(discoverer, reporter); + return new FileCollector(discoverer, reporter, null); } // public behaviour @@ -243,6 +246,14 @@ public final class FileCollector implements AutoCloseable { } private String getDisplayName(Path file) { + String localDisplayName = getLocalDisplayName(file); + if (outerFsDisplayName != null) { + return outerFsDisplayName + "!" + localDisplayName; + } + return localDisplayName; + } + + private String getLocalDisplayName(Path file) { if (!relativizeRootPaths.isEmpty()) { // takes precedence over legacy behavior return getDisplayName(file, relativizeRootPaths); @@ -284,6 +295,14 @@ public final class FileCollector implements AutoCloseable { best = file.toAbsolutePath(); continue; } else { + if (!root.getFileSystem().equals(file.getFileSystem())) { + // maybe the file is in a zip + root = file.getFileSystem().getPath(root.toString()); // SUPPRESS CHECKSTYLE ModifiedControlVariable + } + if (root.isAbsolute() != file.isAbsolute()) { // this causes IllegalArgumentException + root = root.toAbsolutePath(); // SUPPRESS CHECKSTYLE ModifiedControlVariable + file = file.toAbsolutePath(); + } candidate = root.relativize(file); } // take the shortest path. @@ -349,19 +368,48 @@ public final class FileCollector implements AutoCloseable { * {@link #addFile(Path)} and such. The zip file is registered as * a resource to close at the end of analysis. */ - public FileSystem addZipFile(Path zipFile) { + @Experimental + public void addZipFile(Path zipFile) throws IOException { if (!Files.isRegularFile(zipFile)) { throw new IllegalArgumentException("Not a regular file: " + zipFile); } - URI zipUri = URI.create("zip:" + zipFile.toUri()); + URI zipUri = URI.create("jar:" + zipFile.toUri()); + FileSystem fs; + boolean isNewFileSystem = false; try { - FileSystem fs = FileSystems.getFileSystem(zipUri); - resourcesToClose.add(fs); - return fs; - } catch (FileSystemNotFoundException | ProviderNotFoundException e) { - reporter.errorEx("Cannot open zip file " + zipFile, e); - return null; + // find an existing file system, may fail + fs = FileSystems.getFileSystem(zipUri); + } catch (FileSystemNotFoundException ignored) { + // if it fails, try to create it. + try { + fs = FileSystems.newFileSystem(zipUri, Collections.emptyMap()); + isNewFileSystem = true; + } catch (ProviderNotFoundException | IOException e) { + reporter.errorEx("Cannot open zip file " + zipFile, e); + return; + } } + try (FileCollector zipCollector = newZipCollector(zipFile)) { + for (Path zipRoot : fs.getRootDirectories()) { + zipCollector.addFileOrDirectory(zipRoot); + } + this.absorb(zipCollector); + if (isNewFileSystem) { + resourcesToClose.add(fs); + } + + } catch (IOException ioe) { + reporter.errorEx("Error reading zip file " + zipFile + ", will be skipped", ioe); + fs.close(); + } + } + + + /** A collector that prefixes the display name of the files it will contain with the path of the zip. */ + @Experimental + private FileCollector newZipCollector(Path zipFilePath) { + String zipDisplayName = getDisplayName(zipFilePath); + return new FileCollector(discoverer, reporter, zipDisplayName); } // configuration @@ -432,6 +480,17 @@ public final class FileCollector implements AutoCloseable { } } + /** + * Add all files collected in the other collector into this one. + * Transfers resources to close as well. The parameter is left empty. + */ + public void absorb(FileCollector otherCollector) { + this.allFilesToProcess.addAll(otherCollector.allFilesToProcess); + this.resourcesToClose.addAll(otherCollector.resourcesToClose); + otherCollector.allFilesToProcess.clear(); + otherCollector.resourcesToClose.clear(); + } + /** * Exclude all collected files whose language is not part of the given * collection. @@ -447,6 +506,7 @@ public final class FileCollector implements AutoCloseable { } } + @Override public String toString() { return "FileCollector{filesToProcess=" + allFilesToProcess + '}'; diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/ZipFileTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/ZipFileTest.java new file mode 100644 index 0000000000..a79ff07f3a --- /dev/null +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/ZipFileTest.java @@ -0,0 +1,67 @@ +/** + * BSD-style license; for more info see http://pmd.sourceforge.net/license.html + */ + +package net.sourceforge.pmd.cli; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasSize; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; + +import org.junit.Test; + +import net.sourceforge.pmd.PMDConfiguration; +import net.sourceforge.pmd.PmdAnalysis; +import net.sourceforge.pmd.lang.document.TextFile; + +public class ZipFileTest { + + private static final String ZIP_PATH = "src/test/resources/net/sourceforge/pmd/cli/zipWithSources.zip"; + private final Path zipPath = Paths.get(ZIP_PATH); + + @Test + public void testZipFile() { + PMDConfiguration conf = new PMDConfiguration(); + conf.addInputPath(zipPath); + try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { + List files = pmd.files().getCollectedFiles(); + assertThat(files, hasSize(3)); + assertThat(files.get(0).getDisplayName(), equalTo(ZIP_PATH + "!/otherSrc/somefile.dummy")); + assertThat(files.get(1).getDisplayName(), equalTo(ZIP_PATH + "!/src/somefile.dummy")); + assertThat(files.get(2).getDisplayName(), equalTo(ZIP_PATH + "!/src/somefile1.dummy")); + } + } + + @Test + public void testZipFileRelativizeWith() { + PMDConfiguration conf = new PMDConfiguration(); + conf.addInputPath(zipPath); + conf.addRelativizeRoot(Paths.get("src/test/resources")); + try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { + List files = pmd.files().getCollectedFiles(); + assertThat(files, hasSize(3)); + assertThat(files.get(0).getDisplayName(), equalTo("net/sourceforge/pmd/cli/zipWithSources.zip!/otherSrc/somefile.dummy")); + assertThat(files.get(1).getDisplayName(), equalTo("net/sourceforge/pmd/cli/zipWithSources.zip!/src/somefile.dummy")); + assertThat(files.get(2).getDisplayName(), equalTo("net/sourceforge/pmd/cli/zipWithSources.zip!/src/somefile1.dummy")); + } + } + + @Test + public void testZipFileRelativizeWithRoot() { + PMDConfiguration conf = new PMDConfiguration(); + conf.addInputPath(zipPath); + conf.addRelativizeRoot(Paths.get("/")); + try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { + List files = pmd.files().getCollectedFiles(); + assertThat(files, hasSize(3)); + assertThat(files.get(0).getDisplayName(), equalTo(zipPath.toAbsolutePath() + "!/otherSrc/somefile.dummy")); + assertThat(files.get(1).getDisplayName(), equalTo(zipPath.toAbsolutePath() + "!/src/somefile.dummy")); + assertThat(files.get(2).getDisplayName(), equalTo(zipPath.toAbsolutePath() + "!/src/somefile1.dummy")); + } + } + +} diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/cli/zipWithSources.zip b/pmd-core/src/test/resources/net/sourceforge/pmd/cli/zipWithSources.zip new file mode 100644 index 0000000000000000000000000000000000000000..877cbdbe2cf92756b4eb8cc407dfcf1087678d0b GIT binary patch literal 1108 zcmWIWW@Zs#0D)5_xuIYNl;C7gV8}1YNG%F3O4bhz;bma={ala?!=)A642&!C$r zL;%zn4!AK)P-DcAjVaF0O-;+pN!3d!&CRWZ8~X4U#9%Z-nHgZlGBBLpY#D;=Iu@X@ z#W07x%l?q4ax*`u3V}skE+hBd>I3GC#EgJXto$4d7Uh4xWJ(R3Jzq?h%v~3gCj4$BoQ38;84y= zEK3Xx;bdTj*@PB2!NBNH0I5_+%P&$WNi8nP%uDAA@MdHZVaA;(VA1f`5yT=PiNK7- zo=9NEZfSH!HWo|tfYKn2B!ldBY)J-Y$zR8LKqhes2;pq>PzNO;7}(PI0LTQHh{eUQ z@W+}!ahnfHJTS1O(Tx$+d?J$)C`ja(aU~lGu=zlf8MZX8g<60u5wSuN5n2KY@MdKL P8NddF+Q1wy49@ic19B3& literal 0 HcmV?d00001 From 81bfed2ef7579c3d92e6cb9271178eca915a76ed Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 24 Jan 2023 10:55:11 +0100 Subject: [PATCH 05/22] Fix unit tests --- .../java/net/sourceforge/pmd/lang/document/FileCollector.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java index c06222d81e..27cf889627 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java @@ -263,13 +263,9 @@ public final class FileCollector implements AutoCloseable { /** * Return the textfile's display name. - * test only */ static String getDisplayNameLegacy(Path file, List relativizeRoots) { String fileName = file.toString(); - if ("jar".equals(file.toUri().getScheme())) { - fileName = URI.create(file.toUri().getSchemeSpecificPart()).getPath(); - } for (String root : relativizeRoots) { if (file.startsWith(root)) { if (fileName.startsWith(File.separator, root.length())) { From e9baa5b931ab73d6499da97d863f2fcf2e3df874 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 24 Jan 2023 11:35:55 +0100 Subject: [PATCH 06/22] [doc] Update CLI reference for new --relativize-paths-with --- docs/pages/pmd/userdocs/cli_reference.md | 16 +++++++++++++--- docs/pages/release_notes.md | 9 +++++++++ .../net/sourceforge/pmd/cli/PMDParameters.java | 5 ++--- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/docs/pages/pmd/userdocs/cli_reference.md b/docs/pages/pmd/userdocs/cli_reference.md index 5f4500b6e7..154eebe2b2 100644 --- a/docs/pages/pmd/userdocs/cli_reference.md +++ b/docs/pages/pmd/userdocs/cli_reference.md @@ -114,7 +114,8 @@ The tool comes with a rather extensive help text, simply running with `--help`! %} {% include custom/cli_option_row.html options="-language,-l" option_arg="lang" - description="Specify the language PMD should use. Used together with `-version`. See also [Supported Languages](#supported-languages)." + description="Specify the language PMD should use. Used together with `-version`. See also [Supported Languages](#supported-languages). +

Deprecated since PMD 6.52.0. Use `--use-version` instead.

" %} {% include custom/cli_option_row.html options="--minimum-priority,-min" option_arg="num" @@ -133,12 +134,20 @@ The tool comes with a rather extensive help text, simply running with `--help`! description="Specifies a property for the report renderer. The option can be specified several times." default="[]" %} + {% include custom/cli_option_row.html options="--relativize-paths-with,-z" + option_arg="path" + description="Path relative to which directories are rendered in the report. This option allows + shortening directories in the report; without it, paths are rendered as absolute paths. + The option can be repeated, in which case the shortest relative path will be used. + This option replaces `--short-names` since PMD 6.54.0." + %} {% include custom/cli_option_row.html options="--report-file,-r" option_arg="path" description="Path to a file to which report output is written. The file is created if it does not exist. If this option is not specified, the report is rendered to standard output." %} {% include custom/cli_option_row.html options="--short-names" - description="Prints shortened filenames in the report." + description="Prints shortened filenames in the report. +

Deprecated since PMD 6.54.0. Use `--relativize-paths-with` instead.

" %} {% include custom/cli_option_row.html options="--show-suppressed" description="Causes the suppressed rule violations to be added to the report." @@ -167,7 +176,8 @@ The tool comes with a rather extensive help text, simply running with `--help`! %} {% include custom/cli_option_row.html options="-version,-v" option_arg="version" - description="Specify the version of a language PMD should use. Used together with `-language`. See also [Supported Languages](#supported-languages)." + description="Specify the version of a language PMD should use. Used together with `-language`. See also [Supported Languages](#supported-languages). +

Deprecated since PMD 6.52.0. Use `--use-version` instead.

" %} diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 69320f5778..64d8575931 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -15,9 +15,18 @@ This is a {{ site.pmd.release_type }} release. ### New and noteworthy ### Fixed Issues +* core + * [#4026](https://github.com/pmd/pmd/issues/4026): \[cli] Filenames printed as absolute paths in the report despite parameter `--short-names` ### API Changes +#### PMD CLI + +* PMD now supports a new `--relativize-paths-with` flag (or short `-z`), which replaces `--short-names`. + It serves the same purpose: Shortening the pathnames in the reports. However, with the new flag it's possible + to explicitly define one or more pathnames that should be used as the base when creating relative paths. + The old flag `--short-names` is deprecated. + #### Deprecated APIs ##### For removal diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java index 61cfe94b88..505c475475 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java @@ -130,9 +130,8 @@ public class PMDParameters { description = "Path relative to which directories are rendered in the report." + "This option allows shortening directories in the report; " + "without it, paths are rendered as absolute paths. " - + "The option can be repeated, in which case the shortest relative path." - + "If / is mentioned (root path), then the paths will be rendered as absolute." - + "This option replaces --short-names since PMD 6.52.0.", + + "The option can be repeated, in which case the shortest relative path will be used." + + "This option replaces --short-names since PMD 6.54.0.", validateValueWith = PathToRelativizeRootValidator.class, converter = StringToPathConverter.class) private List relativizePathRoot = new ArrayList<>(); From fed44709c75f19481bab2744192613467698a066 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 24 Jan 2023 11:41:51 +0100 Subject: [PATCH 07/22] Test deprecation warning for --short-names --- .../test/java/net/sourceforge/pmd/cli/CoreCliTest.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java index e0e12f752e..edfbd83c76 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java @@ -171,6 +171,14 @@ public class CoreCliTest { + srcDir.resolve("someSource.dummy"))); } + @Test + public void testDeprecationWarningForShortNames() { + runPmdSuccessfully("--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET, "--short-names"); + + assertThat(loggingRule.getLog(), containsString("Some deprecated options were used on the command-line, including --short-names")); + assertThat(loggingRule.getLog(), containsString("Consider replacing it with --relativize-paths-with")); + } + @Test public void testFileCollectionWithUnknownFiles() throws IOException { Path reportFile = tempRoot().resolve("out/reportFile.txt"); From 74e6f85a50c5bc1e8795a6693234af343da02a94 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 24 Jan 2023 12:05:21 +0100 Subject: [PATCH 08/22] Fix tests under Windows --- .../net/sourceforge/pmd/ant/PMDTaskTest.java | 4 ++-- .../net/sourceforge/pmd/cli/CoreCliTest.java | 2 +- .../net/sourceforge/pmd/cli/PMDFilelistTest.java | 9 +++++---- .../net/sourceforge/pmd/cli/ZipFileTest.java | 16 +++++++++------- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java index c30a8c5ce8..edc09cb669 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java @@ -80,7 +80,7 @@ public class PMDTaskTest { String actual = IOUtil.readToString(in, StandardCharsets.UTF_8); // remove any trailing newline actual = actual.replaceAll("\n|\r", ""); - Assert.assertEquals("src/sample.dummy:0:\tSampleXPathRule:\tTest Rule 2", actual); + Assert.assertEquals(IOUtil.normalizePath("src/sample.dummy") + ":0:\tSampleXPathRule:\tTest Rule 2", actual); } } @@ -92,7 +92,7 @@ public class PMDTaskTest { String actual = IOUtil.readToString(in, StandardCharsets.UTF_8); // remove any trailing newline actual = actual.replaceAll("\n|\r", ""); - Assert.assertEquals("src/sample.dummy:0:\tSampleXPathRule:\tTest Rule 2", actual); + Assert.assertEquals(IOUtil.normalizePath("src/sample.dummy") + ":0:\tSampleXPathRule:\tTest Rule 2", actual); } } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java index edfbd83c76..c65a8c2c31 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java @@ -149,7 +149,7 @@ public class CoreCliTest { runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.getParent()); assertThat(outStreamCaptor.getLog(), not(containsString(srcDir.resolve("someSource.dummy").toString()))); - assertThat(outStreamCaptor.getLog(), containsString("src/someSource.dummy")); + assertThat(outStreamCaptor.getLog(), containsString(IOUtil.normalizePath("src/someSource.dummy"))); } @Test diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java index 0dc033d95c..bd85a2d680 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java @@ -26,6 +26,7 @@ import net.sourceforge.pmd.PmdAnalysis; import net.sourceforge.pmd.lang.DummyLanguageModule; import net.sourceforge.pmd.lang.Language; import net.sourceforge.pmd.lang.document.TextFile; +import net.sourceforge.pmd.util.IOUtil; import net.sourceforge.pmd.util.datasource.DataSource; public class PMDFilelistTest { @@ -63,8 +64,8 @@ public class PMDFilelistTest { try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { List files = pmd.files().getCollectedFiles(); assertThat(files, hasSize(2)); - assertThat(files.get(0).getDisplayName(), equalTo("net/sourceforge/pmd/cli/src/anotherfile.dummy")); - assertThat(files.get(1).getDisplayName(), equalTo("net/sourceforge/pmd/cli/src/somefile.dummy")); + assertThat(files.get(0).getDisplayName(), equalTo(IOUtil.normalizePath("net/sourceforge/pmd/cli/src/anotherfile.dummy"))); + assertThat(files.get(1).getDisplayName(), equalTo(IOUtil.normalizePath("net/sourceforge/pmd/cli/src/somefile.dummy"))); } } @@ -76,7 +77,7 @@ public class PMDFilelistTest { try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { List files = pmd.files().getCollectedFiles(); assertThat(files, hasSize(3)); - assertThat(files.get(0).getDisplayName(), equalTo("../otherSrc/somefile.dummy")); + assertThat(files.get(0).getDisplayName(), equalTo(".." + IOUtil.normalizePath("/otherSrc/somefile.dummy"))); assertThat(files.get(1).getDisplayName(), equalTo("anotherfile.dummy")); assertThat(files.get(2).getDisplayName(), equalTo("somefile.dummy")); } @@ -101,7 +102,7 @@ public class PMDFilelistTest { public void testUseAbsolutePaths() { PMDConfiguration conf = new PMDConfiguration(); conf.setInputFilePath(Paths.get(RESOURCE_PREFIX + "filelist4.txt")); - conf.addRelativizeRoot(Paths.get("/")); + conf.addRelativizeRoot(Paths.get(RESOURCE_PREFIX).toAbsolutePath().getRoot()); try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { List files = pmd.files().getCollectedFiles(); assertThat(files, hasSize(3)); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/ZipFileTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/ZipFileTest.java index a79ff07f3a..af06203c45 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/ZipFileTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/ZipFileTest.java @@ -17,6 +17,7 @@ import org.junit.Test; import net.sourceforge.pmd.PMDConfiguration; import net.sourceforge.pmd.PmdAnalysis; import net.sourceforge.pmd.lang.document.TextFile; +import net.sourceforge.pmd.util.IOUtil; public class ZipFileTest { @@ -30,9 +31,9 @@ public class ZipFileTest { try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { List files = pmd.files().getCollectedFiles(); assertThat(files, hasSize(3)); - assertThat(files.get(0).getDisplayName(), equalTo(ZIP_PATH + "!/otherSrc/somefile.dummy")); - assertThat(files.get(1).getDisplayName(), equalTo(ZIP_PATH + "!/src/somefile.dummy")); - assertThat(files.get(2).getDisplayName(), equalTo(ZIP_PATH + "!/src/somefile1.dummy")); + assertThat(files.get(0).getDisplayName(), equalTo(IOUtil.normalizePath(ZIP_PATH) + "!/otherSrc/somefile.dummy")); + assertThat(files.get(1).getDisplayName(), equalTo(IOUtil.normalizePath(ZIP_PATH) + "!/src/somefile.dummy")); + assertThat(files.get(2).getDisplayName(), equalTo(IOUtil.normalizePath(ZIP_PATH) + "!/src/somefile1.dummy")); } } @@ -44,9 +45,10 @@ public class ZipFileTest { try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { List files = pmd.files().getCollectedFiles(); assertThat(files, hasSize(3)); - assertThat(files.get(0).getDisplayName(), equalTo("net/sourceforge/pmd/cli/zipWithSources.zip!/otherSrc/somefile.dummy")); - assertThat(files.get(1).getDisplayName(), equalTo("net/sourceforge/pmd/cli/zipWithSources.zip!/src/somefile.dummy")); - assertThat(files.get(2).getDisplayName(), equalTo("net/sourceforge/pmd/cli/zipWithSources.zip!/src/somefile1.dummy")); + String baseZipPath = IOUtil.normalizePath("net/sourceforge/pmd/cli/zipWithSources.zip"); + assertThat(files.get(0).getDisplayName(), equalTo(baseZipPath + "!/otherSrc/somefile.dummy")); + assertThat(files.get(1).getDisplayName(), equalTo(baseZipPath + "!/src/somefile.dummy")); + assertThat(files.get(2).getDisplayName(), equalTo(baseZipPath + "!/src/somefile1.dummy")); } } @@ -54,7 +56,7 @@ public class ZipFileTest { public void testZipFileRelativizeWithRoot() { PMDConfiguration conf = new PMDConfiguration(); conf.addInputPath(zipPath); - conf.addRelativizeRoot(Paths.get("/")); + conf.addRelativizeRoot(zipPath.toAbsolutePath().getRoot()); try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { List files = pmd.files().getCollectedFiles(); assertThat(files, hasSize(3)); From 0b4cc1e5bb34b8a7063a282b6b117200d5496858 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 24 Jan 2023 15:52:36 +0100 Subject: [PATCH 09/22] [ant] Make relativizePathsWith a path-like structure Update documentation --- docs/pages/pmd/userdocs/tools/ant.md | 19 ++++++++++-- .../java/net/sourceforge/pmd/ant/PMDTask.java | 30 ++++++++++++++----- .../net/sourceforge/pmd/ant/PMDTaskTest.java | 4 +++ .../sourceforge/pmd/ant/xml/pmdtasktest.xml | 5 +++- 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/docs/pages/pmd/userdocs/tools/ant.md b/docs/pages/pmd/userdocs/tools/ant.md index 9212ac552c..9cf33b6564 100644 --- a/docs/pages/pmd/userdocs/tools/ant.md +++ b/docs/pages/pmd/userdocs/tools/ant.md @@ -79,7 +79,11 @@ The examples below won't repeat this taskdef element, as this is always required shortFilenames - Places truncated filenames in the report. This can reduce your report file size by 15%-20%. + + Deprecated Use relativizePathsWith + as nested element instead. + Places truncated filenames in the report. This can reduce your report file size by 15%-20%. + No @@ -187,7 +191,7 @@ automatically and the latest language version is used. - + rulesets/java/quickstart.xml config/my-ruleset.xml @@ -199,6 +203,12 @@ automatically and the latest language version is used. `fileset` nested element - specify the actual java source files, that PMD should analyze. You can use multiple fileset elements. See [FileSet](https://ant.apache.org/manual/Types/fileset.html) for the syntax and usage. +`relativizePathsWith` nested element - configures the paths relative to which directories are rendered in the report. +This option allows shortening directories in the report; without it, paths are rendered as absolute paths. +The option can be repeated, in which case the shortest relative path will be used. +It is a [path-like structure](https://ant.apache.org/manual/using.html#path). +This option replaces `shortFilenames` since PMD 6.54.0. + ### Language version selection PMD selects the language automatically using the file extension. If multiple versions of a language are @@ -410,7 +420,7 @@ An HTML report with the "linkPrefix" and "linePrefix" properties: - + @@ -418,6 +428,9 @@ An HTML report with the "linkPrefix" and "linePrefix" properties: + + + diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/ant/PMDTask.java b/pmd-core/src/main/java/net/sourceforge/pmd/ant/PMDTask.java index d77d42f45e..b2404b1d4e 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/ant/PMDTask.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/ant/PMDTask.java @@ -4,7 +4,6 @@ package net.sourceforge.pmd.ant; -import java.io.File; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; @@ -12,11 +11,14 @@ import java.util.Iterator; import java.util.List; import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.Path; import org.apache.tools.ant.types.Reference; +import org.apache.tools.ant.types.Resource; +import net.sourceforge.pmd.annotation.InternalApi; import net.sourceforge.pmd.ant.internal.PMDTaskImpl; public class PMDTask extends Task { @@ -29,7 +31,7 @@ public class PMDTask extends Task { private boolean failOnRuleViolation; @Deprecated private boolean shortFilenames; - private String relativizePathsWith; + private final List relativizePathsWith = new ArrayList<>(); private String suppressMarker; private String rulesetFiles; private boolean noRuleSetCompatibility; @@ -77,6 +79,11 @@ public class PMDTask extends Task { } rulesetFiles = getNestedRuleSetFiles(); } + + if (shortFilenames) { + log("DEPRECATED - Use of shortFilenames is deprecated. Use a nested relativePathsWith element instead.", + Project.MSG_WARN); + } } private String getNestedRuleSetFiles() { @@ -91,6 +98,10 @@ public class PMDTask extends Task { return sb.toString(); } + /** + * @deprecated Use {@link #addRelativizePathsWith(Path)} + */ + @Deprecated public void setShortFilenames(boolean reportShortNames) { this.shortFilenames = reportShortNames; } @@ -269,15 +280,20 @@ public class PMDTask extends Task { this.noCache = noCache; } - public void setRelativizePathsWith(String relativizePathsWith) { - this.relativizePathsWith = relativizePathsWith; + public void addRelativizePathsWith(Path relativizePathsWith) { + this.relativizePathsWith.add(relativizePathsWith); } + public List getRelativizePathsWith() { + return relativizePathsWith; + } + + @InternalApi public List getRelativizeRoots() { List paths = new ArrayList<>(); - if (relativizePathsWith != null) { - for (String file : relativizePathsWith.split(File.pathSeparator)) { - paths.add(Paths.get(file)); + for (Path path : getRelativizePathsWith()) { + for (Resource resource : path) { + paths.add(Paths.get(resource.toString())); } } return paths; diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java index edc09cb669..3ca8fb9409 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java @@ -4,6 +4,8 @@ package net.sourceforge.pmd.ant; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.fail; import java.io.FileInputStream; @@ -82,6 +84,8 @@ public class PMDTaskTest { actual = actual.replaceAll("\n|\r", ""); Assert.assertEquals(IOUtil.normalizePath("src/sample.dummy") + ":0:\tSampleXPathRule:\tTest Rule 2", actual); } + + assertThat(buildRule.getLog(), containsString("DEPRECATED - Use of shortFilenames is deprecated. Use a nested relativePathsWith element instead.")); } @Test diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml b/pmd-core/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml index 7f75a16143..28b70e8e86 100644 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml +++ b/pmd-core/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml @@ -36,12 +36,15 @@ - + ${pmd.home}/src/test/resources/rulesets/dummy/basic.xml + + + From cf1dd6e902ad2d9b29f47d5c695c1f39db0e58b2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 24 Jan 2023 16:13:22 +0100 Subject: [PATCH 10/22] Small fixes in PMDParameters --- .../main/java/net/sourceforge/pmd/cli/PMDParameters.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java index 505c475475..7b53aa3988 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java @@ -130,8 +130,7 @@ public class PMDParameters { description = "Path relative to which directories are rendered in the report." + "This option allows shortening directories in the report; " + "without it, paths are rendered as absolute paths. " - + "The option can be repeated, in which case the shortest relative path will be used." - + "This option replaces --short-names since PMD 6.54.0.", + + "The option can be repeated, in which case the shortest relative path will be used.", validateValueWith = PathToRelativizeRootValidator.class, converter = StringToPathConverter.class) private List relativizePathRoot = new ArrayList<>(); @@ -271,9 +270,7 @@ public class PMDParameters { configuration.setReportFormat(this.getFormat()); configuration.setBenchmark(this.isBenchmark()); configuration.setDebug(this.isDebug()); - for (Path path: relativizePathRoot) { - configuration.addRelativizeRoot(path); - } + configuration.addRelativizeRoots(this.relativizePathRoot); configuration.setMinimumPriority(this.getMinimumPriority()); configuration.setReportFile(this.getReportfile()); configuration.setReportProperties(this.getProperties()); From e65fddff82fac723e14d307c8fddacf37e03127d Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Tue, 24 Jan 2023 16:37:06 +0100 Subject: [PATCH 11/22] [core] FileCollector - add back addZipFile() as deprecated method --- docs/pages/release_notes.md | 4 +++ .../pmd/internal/util/FileCollectionUtil.java | 2 +- .../pmd/lang/document/FileCollector.java | 33 +++++++++++++++++-- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 64d8575931..7723accb1b 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -36,6 +36,10 @@ This is a {{ site.pmd.release_type }} release. actually is used. Therefore, this method can't be used to determine the Apex version of the project that is being analyzed. +* {% jdoc !!core::lang.document.FileCollector#addZipFile(java.nio.file.Path) %} has been deprecated. It is replaced + by {% jdoc !!core::lang.document.FileCollector#addZipFileWithContent(java.nio.file.Path) %} which directly adds the + content of the zip file for analysis. + ##### Internal APIs * {% jdoc core::renderers.CSVWriter %} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java index 357d7f847e..bfc38e7918 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java @@ -142,7 +142,7 @@ public final class FileCollectionUtil { if (Files.isDirectory(path)) { collector.addDirectory(path); } else if (path.toString().endsWith(".zip") || path.toString().endsWith(".jar")) { - collector.addZipFile(path); + collector.addZipFileWithContent(path); } else if (Files.isRegularFile(path)) { collector.addFile(path); } else { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java index 27cf889627..26cac4d5e3 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java @@ -11,6 +11,7 @@ import java.net.URI; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.nio.file.FileSystem; +import java.nio.file.FileSystemAlreadyExistsException; import java.nio.file.FileSystemNotFoundException; import java.nio.file.FileSystems; import java.nio.file.FileVisitResult; @@ -366,9 +367,35 @@ public final class FileCollector implements AutoCloseable { * it can be explored with the {@link Path} API. You can then call * {@link #addFile(Path)} and such. The zip file is registered as * a resource to close at the end of analysis. + * + * @deprecated Use {@link #addZipFileWithContent(Path)} instead. + */ + @Deprecated + public FileSystem addZipFile(Path zipFile) { + if (!Files.isRegularFile(zipFile)) { + throw new IllegalArgumentException("Not a regular file: " + zipFile); + } + URI zipUri = URI.create("jar:" + zipFile.toUri()); + try { + FileSystem fs = FileSystems.newFileSystem(zipUri, Collections.emptyMap()); + resourcesToClose.add(fs); + return fs; + } catch (FileSystemAlreadyExistsException | ProviderNotFoundException | IOException e) { + reporter.errorEx("Cannot open zip file " + zipFile, e); + return null; + } + } + + /** + * Opens a zip file and adds all files of the zip file to the list + * of files to be processed. + * + *

The zip file is registered as a resource to close at the end of analysis.

+ * + * @return True if the zip file including its content has been added without errors */ @Experimental - public void addZipFile(Path zipFile) throws IOException { + public boolean addZipFileWithContent(Path zipFile) throws IOException { if (!Files.isRegularFile(zipFile)) { throw new IllegalArgumentException("Not a regular file: " + zipFile); } @@ -385,7 +412,7 @@ public final class FileCollector implements AutoCloseable { isNewFileSystem = true; } catch (ProviderNotFoundException | IOException e) { reporter.errorEx("Cannot open zip file " + zipFile, e); - return; + return false; } } try (FileCollector zipCollector = newZipCollector(zipFile)) { @@ -400,7 +427,9 @@ public final class FileCollector implements AutoCloseable { } catch (IOException ioe) { reporter.errorEx("Error reading zip file " + zipFile + ", will be skipped", ioe); fs.close(); + return false; } + return true; } From 8a85295e49b2e20b92a9e2a9c62909f524e34e73 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 25 Jan 2023 12:07:07 +0100 Subject: [PATCH 12/22] Verify behavior with no relativize paths and absolute/relative src dirs --- .../net/sourceforge/pmd/cli/CoreCliTest.java | 68 ++++++++++++++++--- .../net/sourceforge/pmd/cli/ZipFileTest.java | 16 +++-- 2 files changed, 70 insertions(+), 14 deletions(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java index c65a8c2c31..1d6e6fe5f4 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java @@ -7,13 +7,16 @@ package net.sourceforge.pmd.cli; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsStringIgnoringCase; +import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.not; +import static org.hamcrest.Matchers.startsWith; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.io.File; import java.io.FileOutputStream; import java.io.FilterOutputStream; import java.io.IOException; @@ -23,6 +26,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.List; import java.util.logging.Logger; import java.util.zip.ZipEntry; @@ -70,12 +74,8 @@ public class CoreCliTest { @Before public void setup() throws IOException { - // set current directory to wd - Path root = tempRoot(); - System.setProperty("user.dir", root.toString()); - // create a few files - srcDir = Files.createDirectories(root.resolve("src")); + srcDir = Files.createDirectories(tempRoot().resolve("src")); writeString(srcDir.resolve("someSource.dummy"), "dummy text"); // reset logger? Logger.getLogger("net.sourceforge.pmd"); @@ -136,20 +136,72 @@ public class CoreCliTest { } @Test - public void testNoRelativizeWith() { + public void testNoRelativizeWithAbsoluteSrcDir() { + assertTrue("srcDir should be absolute", srcDir.isAbsolute()); startCapturingErrAndOut(); runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS); assertThat(outStreamCaptor.getLog(), containsString(srcDir.resolve("someSource.dummy").toString())); } + @Test + public void testNoRelativizeWithRelativeSrcDir() throws IOException { + // Note, that we can't reliably change the current working directory for the current java process + // therefore we use the current directory and make sure, we are at the correct place - in pmd-core + Path cwd = Paths.get(".").toRealPath(); + assertThat(cwd.toString(), endsWith("pmd-core")); + String relativeSrcDir = "src/test/resources/net/sourceforge/pmd/cli/src"; + assertTrue(Files.isDirectory(cwd.resolve(relativeSrcDir))); + + startCapturingErrAndOut(); + runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", relativeSrcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS); + + assertThat(outStreamCaptor.getLog(), containsString("\n" + IOUtil.normalizePath(relativeSrcDir + "/somefile.dummy"))); + } + + @Test + public void testNoRelativizeWithRelativeSrcDirParent() throws IOException { + // Note, that we can't reliably change the current working directory for the current java process + // therefore we use the current directory and make sure, we are at the correct place - in pmd-core + Path cwd = Paths.get(".").toRealPath(); + assertThat(cwd.toString(), endsWith("pmd-core")); + String relativeSrcDir = IOUtil.normalizePath("src/test/resources/net/sourceforge/pmd/cli/src"); + assertTrue(Files.isDirectory(cwd.resolve(relativeSrcDir))); + + // use the parent directory + relativeSrcDir = relativeSrcDir + File.separator + ".."; + + startCapturingErrAndOut(); + runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", relativeSrcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS); + + assertThat(outStreamCaptor.getLog(), containsString("\n" + relativeSrcDir + IOUtil.normalizePath("/src/somefile.dummy"))); + } + + @Test + public void testRelativizeWithRootRelativeSrcDir() throws IOException { + // Note, that we can't reliably change the current working directory for the current java process + // therefore we use the current directory and make sure, we are at the correct place - in pmd-core + Path cwd = Paths.get(".").toRealPath(); + assertThat(cwd.toString(), endsWith("pmd-core")); + String relativeSrcDir = "src/test/resources/net/sourceforge/pmd/cli/src"; + assertTrue(Files.isDirectory(cwd.resolve(relativeSrcDir))); + + String root = cwd.getRoot().toString(); + + startCapturingErrAndOut(); + runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", relativeSrcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "--relativize-paths-with", root); + + String absoluteSrcPath = cwd.resolve(relativeSrcDir).resolve("somefile.dummy").toString(); + assertThat(outStreamCaptor.getLog(), containsString("\n" + absoluteSrcPath)); + } + @Test public void testRelativizeWith() { startCapturingErrAndOut(); runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.getParent()); assertThat(outStreamCaptor.getLog(), not(containsString(srcDir.resolve("someSource.dummy").toString()))); - assertThat(outStreamCaptor.getLog(), containsString(IOUtil.normalizePath("src/someSource.dummy"))); + assertThat(outStreamCaptor.getLog(), startsWith(IOUtil.normalizePath("src/someSource.dummy"))); } @Test @@ -158,7 +210,7 @@ public class CoreCliTest { runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.getParent(), srcDir); assertThat(outStreamCaptor.getLog(), not(containsString(srcDir.resolve("someSource.dummy").toString()))); - assertThat(outStreamCaptor.getLog(), containsString("someSource.dummy")); + assertThat(outStreamCaptor.getLog(), startsWith("someSource.dummy")); } @Test diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/ZipFileTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/ZipFileTest.java index af06203c45..e260f65f9d 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/ZipFileTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/ZipFileTest.java @@ -28,12 +28,14 @@ public class ZipFileTest { public void testZipFile() { PMDConfiguration conf = new PMDConfiguration(); conf.addInputPath(zipPath); + // no relativizeRoot paths configured -> we use the relative path + String reportPath = zipPath.toString(); try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { List files = pmd.files().getCollectedFiles(); assertThat(files, hasSize(3)); - assertThat(files.get(0).getDisplayName(), equalTo(IOUtil.normalizePath(ZIP_PATH) + "!/otherSrc/somefile.dummy")); - assertThat(files.get(1).getDisplayName(), equalTo(IOUtil.normalizePath(ZIP_PATH) + "!/src/somefile.dummy")); - assertThat(files.get(2).getDisplayName(), equalTo(IOUtil.normalizePath(ZIP_PATH) + "!/src/somefile1.dummy")); + assertThat(files.get(0).getDisplayName(), equalTo(reportPath + "!/otherSrc/somefile.dummy")); + assertThat(files.get(1).getDisplayName(), equalTo(reportPath + "!/src/somefile.dummy")); + assertThat(files.get(2).getDisplayName(), equalTo(reportPath + "!/src/somefile1.dummy")); } } @@ -56,13 +58,15 @@ public class ZipFileTest { public void testZipFileRelativizeWithRoot() { PMDConfiguration conf = new PMDConfiguration(); conf.addInputPath(zipPath); + // this configures "/" as the relativizeRoot -> result are absolute paths conf.addRelativizeRoot(zipPath.toAbsolutePath().getRoot()); + String reportPath = zipPath.toAbsolutePath().toString(); try (PmdAnalysis pmd = PmdAnalysis.create(conf)) { List files = pmd.files().getCollectedFiles(); assertThat(files, hasSize(3)); - assertThat(files.get(0).getDisplayName(), equalTo(zipPath.toAbsolutePath() + "!/otherSrc/somefile.dummy")); - assertThat(files.get(1).getDisplayName(), equalTo(zipPath.toAbsolutePath() + "!/src/somefile.dummy")); - assertThat(files.get(2).getDisplayName(), equalTo(zipPath.toAbsolutePath() + "!/src/somefile1.dummy")); + assertThat(files.get(0).getDisplayName(), equalTo(reportPath + "!/otherSrc/somefile.dummy")); + assertThat(files.get(1).getDisplayName(), equalTo(reportPath + "!/src/somefile.dummy")); + assertThat(files.get(2).getDisplayName(), equalTo(reportPath + "!/src/somefile1.dummy")); } } From a93b45c0400a9a30b64e2cd82592b62e80adc775 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 25 Jan 2023 13:02:06 +0100 Subject: [PATCH 13/22] [doc] Update doc for --relativize-paths-with regarding absolute paths --- docs/pages/pmd/userdocs/cli_reference.md | 3 ++- .../src/main/java/net/sourceforge/pmd/cli/PMDParameters.java | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/pages/pmd/userdocs/cli_reference.md b/docs/pages/pmd/userdocs/cli_reference.md index 154eebe2b2..2201d4ab53 100644 --- a/docs/pages/pmd/userdocs/cli_reference.md +++ b/docs/pages/pmd/userdocs/cli_reference.md @@ -137,8 +137,9 @@ The tool comes with a rather extensive help text, simply running with `--help`! {% include custom/cli_option_row.html options="--relativize-paths-with,-z" option_arg="path" description="Path relative to which directories are rendered in the report. This option allows - shortening directories in the report; without it, paths are rendered as absolute paths. + shortening directories in the report; without it, paths are rendered as mentioned in the source directory (option \"--dir\"). The option can be repeated, in which case the shortest relative path will be used. + If the root path is mentioned (e.g. \"/\" or \"C:\\\"), then the paths will be rendered as absolute. This option replaces `--short-names` since PMD 6.54.0." %} {% include custom/cli_option_row.html options="--report-file,-r" diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java index 7b53aa3988..b956cac746 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java @@ -129,8 +129,9 @@ public class PMDParameters { variableArity = true, description = "Path relative to which directories are rendered in the report." + "This option allows shortening directories in the report; " - + "without it, paths are rendered as absolute paths. " - + "The option can be repeated, in which case the shortest relative path will be used.", + + "without it, paths are rendered as mentioned in the source directory (option \"--dir\"). " + + "The option can be repeated, in which case the shortest relative path will be used." + + "If the root path is mentioned (e.g. \"/\" or \"C:\\\"), then the paths will be rendered as absolute.", validateValueWith = PathToRelativizeRootValidator.class, converter = StringToPathConverter.class) private List relativizePathRoot = new ArrayList<>(); From 8eabce2f6f3f91887ee3cb9c96e16cb0ebccec26 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 25 Jan 2023 13:33:43 +0100 Subject: [PATCH 14/22] Follow symlinks when collecting source files Verify behavior with symlinks and relativize paths with. --- .../net/sourceforge/pmd/PMDConfiguration.java | 3 +- .../pmd/lang/document/FileCollector.java | 9 ++++-- .../net/sourceforge/pmd/cli/CoreCliTest.java | 31 +++++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java index 8aad402651..2c9ff0530a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java @@ -958,7 +958,8 @@ public class PMDConfiguration extends AbstractConfiguration { * @throws NullPointerException If the path is null */ public void addRelativizeRoot(Path path) { - // TODO symlinks? + // Note: the given path is not further modified or resolved. E.g. there is no special handling for symlinks. + // The goal is, that if the user inputs a path, PMD should output in terms of that path, not it's resolution. this.relativizeRoots.add(Objects.requireNonNull(path)); if (Files.isRegularFile(path)) { diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java index 26cac4d5e3..28ed6fe7f2 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java @@ -14,6 +14,7 @@ import java.nio.file.FileSystem; import java.nio.file.FileSystemAlreadyExistsException; import java.nio.file.FileSystemNotFoundException; import java.nio.file.FileSystems; +import java.nio.file.FileVisitOption; import java.nio.file.FileVisitResult; import java.nio.file.Files; import java.nio.file.Path; @@ -23,6 +24,7 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; +import java.util.EnumSet; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashSet; @@ -264,6 +266,8 @@ public final class FileCollector implements AutoCloseable { /** * Return the textfile's display name. + * + *

package private for test only

*/ static String getDisplayNameLegacy(Path file, List relativizeRoots) { String fileName = file.toString(); @@ -282,9 +286,8 @@ public final class FileCollector implements AutoCloseable { /** * Return the textfile's display name. Takes the shortest path we * can construct from the relativize roots. - * test only */ - static String getDisplayName(Path file, List relativizeRoots) { + private static String getDisplayName(Path file, List relativizeRoots) { Path best = file; for (Path root : relativizeRoots) { Path candidate; @@ -332,7 +335,7 @@ public final class FileCollector implements AutoCloseable { reporter.error("Not a directory {0}", dir); return false; } - Files.walkFileTree(dir, new SimpleFileVisitor() { + Files.walkFileTree(dir, EnumSet.of(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, new SimpleFileVisitor() { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { if (attrs.isRegularFile()) { diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java index 1d6e6fe5f4..71c4fc9d0d 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java @@ -204,6 +204,37 @@ public class CoreCliTest { assertThat(outStreamCaptor.getLog(), startsWith(IOUtil.normalizePath("src/someSource.dummy"))); } + @Test + public void testRelativizeWithSymLink() throws IOException { + // srcDir = /tmp/junit123/src + // symlinkedSrcDir = /tmp/junit123/sources -> /tmp/junit123/src + Path symlinkedSrcDir = Files.createSymbolicLink(tempRoot().resolve("sources"), srcDir); + startCapturingErrAndOut(); + runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", symlinkedSrcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", symlinkedSrcDir); + + assertThat(outStreamCaptor.getLog(), not(containsString(srcDir.resolve("someSource.dummy").toString()))); + assertThat(outStreamCaptor.getLog(), not(containsString(symlinkedSrcDir.resolve("someSource.dummy").toString()))); + assertThat(outStreamCaptor.getLog(), startsWith("someSource.dummy")); + } + + @Test + public void testRelativizeWithSymLinkParent() throws IOException { + // srcDir = /tmp/junit123/src + // symlinkedSrcDir = /tmp/junit-relativize-with-123 -> /tmp/junit123/src + Path tempPath = Files.createTempDirectory("junit-relativize-with-"); + Files.delete(tempPath); + Path symlinkedSrcDir = Files.createSymbolicLink(tempPath, srcDir); + startCapturingErrAndOut(); + // relativizing against parent of symlinkedSrcDir: /tmp + runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", symlinkedSrcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", symlinkedSrcDir.getParent()); + + assertThat(outStreamCaptor.getLog(), not(containsString(srcDir.resolve("someSource.dummy").toString()))); + assertThat(outStreamCaptor.getLog(), not(containsString(symlinkedSrcDir.resolve("someSource.dummy").toString()))); + // base path is symlinkedSrcDir without /tmp: e.g. junit-relativize-with-123 + String basePath = symlinkedSrcDir.getParent().relativize(symlinkedSrcDir).toString(); + assertThat(outStreamCaptor.getLog(), startsWith(basePath + File.separator + "someSource.dummy")); + } + @Test public void testRelativizeWithMultiple() { startCapturingErrAndOut(); From cc8d845b6bad2ec3e5cfed7d2758708406627791 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 25 Jan 2023 15:33:26 +0100 Subject: [PATCH 15/22] Fix tests --- .../net/sourceforge/pmd/ant/PMDTaskTest.java | 4 ++-- .../sourceforge/pmd/ant/xml/pmdtasktest.xml | 3 ++- .../pmd/lang/document/FileCollector.java | 4 +++- .../pmd/lang/document/NioTextFile.java | 15 +++----------- .../pmd/lang/document/TextFile.java | 12 ++++++++--- .../net/sourceforge/pmd/cli/CoreCliTest.java | 8 ++++---- .../sourceforge/pmd/cli/PMDFilelistTest.java | 4 ++-- .../pmd/lang/document/NioTextFileTest.java | 20 +++++++++---------- .../pmd/lang/document/TextFilesTest.java | 1 + 9 files changed, 35 insertions(+), 36 deletions(-) diff --git a/pmd-ant/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java b/pmd-ant/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java index f38f3b6326..c12eb9d0b1 100644 --- a/pmd-ant/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java +++ b/pmd-ant/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java @@ -9,6 +9,7 @@ import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.fail; +import java.io.File; import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; @@ -16,7 +17,6 @@ import java.nio.file.Files; import java.nio.file.Paths; import org.apache.tools.ant.BuildException; -import org.junit.Assert; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -91,7 +91,7 @@ class PMDTaskTest extends AbstractAntTest { String actual = IOUtil.readToString(in, StandardCharsets.UTF_8); // remove any trailing newline actual = actual.replaceAll("\n|\r", ""); - Assert.assertEquals(IOUtil.normalizePath("src/sample.dummy") + ":0:\tSampleXPathRule:\tTest Rule 2", actual); + assertThat(actual, containsString("src" + File.separator + "sample.dummy:1:\tSampleXPathRule:\tTest Rule 2")); } } diff --git a/pmd-ant/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml b/pmd-ant/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml index 2df4c0bbd3..fe9a2bbf9b 100644 --- a/pmd-ant/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml +++ b/pmd-ant/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml @@ -38,7 +38,8 @@ - ${pmd.home}/src/test/resources/rulesets/dummy/basic.xml + + rulesets/dummy/basic.xml diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java index 9d542a9e4d..b6b2576f18 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java @@ -211,7 +211,9 @@ public final class FileCollector implements AutoCloseable { LanguageVersion version = discoverLanguage(pathId); if (version != null) { - return addFileImpl(TextFile.builderForCharSeq(sourceContents, pathId, version).build()); + return addFileImpl(TextFile.builderForCharSeq(sourceContents, pathId, version) + .withDisplayName(pathId) + .build()); } return false; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NioTextFile.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NioTextFile.java index fa29d2c5f9..1b51bd59bb 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NioTextFile.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/NioTextFile.java @@ -5,16 +5,13 @@ package net.sourceforge.pmd.lang.document; import java.io.BufferedWriter; -import java.io.File; import java.io.IOException; -import java.net.URI; import java.nio.charset.Charset; import java.nio.file.FileSystem; import java.nio.file.Files; import java.nio.file.Path; import org.checkerframework.checker.nullness.qual.NonNull; -import org.checkerframework.checker.nullness.qual.Nullable; import net.sourceforge.pmd.internal.util.AssertionUtil; import net.sourceforge.pmd.internal.util.BaseCloseable; @@ -28,14 +25,14 @@ class NioTextFile extends BaseCloseable implements TextFile { private final Path path; private final Charset charset; private final LanguageVersion languageVersion; - private final @Nullable String displayName; + private final String displayName; private final String pathId; private boolean readOnly; NioTextFile(Path path, Charset charset, LanguageVersion languageVersion, - @Nullable String displayName, + String displayName, boolean readOnly) { AssertionUtil.requireParamNotNull("path", path); AssertionUtil.requireParamNotNull("charset", charset); @@ -58,13 +55,7 @@ class NioTextFile extends BaseCloseable implements TextFile { @Override public @NonNull String getDisplayName() { - if (displayName != null) { - return displayName; - } - if ("jar".equals(path.toUri().getScheme())) { - return new File(URI.create(path.toUri().getSchemeSpecificPart()).getPath()).toString(); - } - return path.toString(); + return displayName; } @Override diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextFile.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextFile.java index 76a715cd66..324bf8e33b 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextFile.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextFile.java @@ -160,7 +160,9 @@ public interface TextFile extends Closeable { * @throws NullPointerException If any parameter is null */ static TextFile forPath(Path path, Charset charset, LanguageVersion languageVersion) { - return builderForPath(path, charset, languageVersion).build(); + return builderForPath(path, charset, languageVersion) + .withDisplayName(path.toString()) + .build(); } /** @@ -194,7 +196,9 @@ public interface TextFile extends Closeable { * @throws NullPointerException If any parameter is null */ static TextFile forCharSeq(CharSequence charseq, String pathId, LanguageVersion languageVersion) { - return builderForCharSeq(charseq, pathId, languageVersion).build(); + return builderForCharSeq(charseq, pathId, languageVersion) + .withDisplayName(pathId) + .build(); } /** @@ -226,7 +230,9 @@ public interface TextFile extends Closeable { * @throws NullPointerException If any parameter is null */ static TextFile forReader(Reader reader, String pathId, LanguageVersion languageVersion) { - return builderForReader(reader, pathId, languageVersion).build(); + return builderForReader(reader, pathId, languageVersion) + .withDisplayName(pathId) + .build(); } /** diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java index f7c0eb99b8..97418bf319 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java @@ -193,7 +193,7 @@ class CoreCliTest { @Test void testRelativizeWith() throws Exception { - String log = SystemLambda.tapSystemErrAndOut(() -> { + String log = SystemLambda.tapSystemOut(() -> { runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.getParent()); }); @@ -206,7 +206,7 @@ class CoreCliTest { // srcDir = /tmp/junit123/src // symlinkedSrcDir = /tmp/junit123/sources -> /tmp/junit123/src Path symlinkedSrcDir = Files.createSymbolicLink(tempRoot().resolve("sources"), srcDir); - String log = SystemLambda.tapSystemErrAndOut(() -> { + String log = SystemLambda.tapSystemOut(() -> { runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", symlinkedSrcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", symlinkedSrcDir); }); @@ -223,7 +223,7 @@ class CoreCliTest { Files.delete(tempPath); Path symlinkedSrcDir = Files.createSymbolicLink(tempPath, srcDir); // relativizing against parent of symlinkedSrcDir: /tmp - String log = SystemLambda.tapSystemErrAndOut(() -> { + String log = SystemLambda.tapSystemOut(() -> { runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", symlinkedSrcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", symlinkedSrcDir.getParent()); }); @@ -236,7 +236,7 @@ class CoreCliTest { @Test void testRelativizeWithMultiple() throws Exception { - String log = SystemLambda.tapSystemErrAndOut(() -> { + String log = SystemLambda.tapSystemOut(() -> { runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.getParent(), srcDir); }); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java index 5ea3a30760..ddce7c5cf2 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/PMDFilelistTest.java @@ -55,10 +55,10 @@ class PMDFilelistTest { collectFileList(collector, RESOURCE_PREFIX + "filelist2.txt"); List applicableFiles = collector.getCollectedFiles(); - assertThat(applicableFiles, hasSize(3)); + // note: the file has 3 entries, but one is duplicated, resulting in 2 individual files + assertThat(applicableFiles, hasSize(2)); assertThat(applicableFiles.get(0).getPathId(), endsWith("anotherfile.dummy")); assertThat(applicableFiles.get(1).getPathId(), endsWith("somefile.dummy")); - assertThat(applicableFiles.get(2).getPathId(), endsWith("somefile.dummy")); } @Test diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/NioTextFileTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/NioTextFileTest.java index 597d09f6d8..f03454451d 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/NioTextFileTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/NioTextFileTest.java @@ -7,21 +7,17 @@ package net.sourceforge.pmd.lang.document; import static org.junit.Assert.assertEquals; import java.io.FileOutputStream; -import java.net.URI; import java.nio.charset.StandardCharsets; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; import java.nio.file.Path; -import java.util.Collections; +import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; -import net.sourceforge.pmd.lang.DummyLanguageModule; import net.sourceforge.pmd.lang.LanguageRegistry; -import net.sourceforge.pmd.lang.LanguageVersion; +import net.sourceforge.pmd.lang.LanguageVersionDiscoverer; import net.sourceforge.pmd.util.IOUtil; class NioTextFileTest { @@ -38,11 +34,13 @@ class NioTextFileTest { zipOutputStream.write("dummy text".getBytes(StandardCharsets.UTF_8)); zipOutputStream.closeEntry(); } - try (FileSystem fileSystem = FileSystems.newFileSystem(URI.create("jar:" + zipArchive.toUri()), Collections.emptyMap())) { - Path path = fileSystem.getPath("path/inside/someSource.dummy"); - LanguageRegistry.PMD.getLanguageById("dummy"); - LanguageVersion languageVersion = DummyLanguageModule.getInstance().getDefaultVersion(); - TextFile textFile = TextFile.builderForPath(path, StandardCharsets.UTF_8, languageVersion).build(); + + LanguageVersionDiscoverer discoverer = new LanguageVersionDiscoverer(LanguageRegistry.PMD, null); + try (FileCollector collector = FileCollector.newCollector(discoverer, new TestMessageReporter())) { + collector.addZipFileWithContent(zipArchive); + List collectedFiles = collector.getCollectedFiles(); + assertEquals(1, collectedFiles.size()); + TextFile textFile = collectedFiles.get(0); assertEquals(zipArchive.toAbsolutePath() + "!" + IOUtil.normalizePath("/path/inside/someSource.dummy"), textFile.getDisplayName()); } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/TextFilesTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/TextFilesTest.java index 16dbe22bd3..ed0721292d 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/TextFilesTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/TextFilesTest.java @@ -144,6 +144,7 @@ class TextFilesTest { void testNioFileExplicitReadOnly() throws IOException { Path file = makeTmpFile(StandardCharsets.UTF_8, "some content"); try (TextFile tf = TextFile.builderForPath(file, StandardCharsets.UTF_8, dummyVersion()) + .withDisplayName(file.toString()) .asReadOnly().build()) { assertTrue(tf.isReadOnly(), "readonly"); From cc4d83d279aea922f7b148cd1c44d5b3ec5d5442 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 25 Jan 2023 16:40:04 +0100 Subject: [PATCH 16/22] Deprecate PMDConfiguration#reportShortNames --- docs/pages/release_notes.md | 4 ++++ .../main/java/net/sourceforge/pmd/PMDConfiguration.java | 8 ++++++-- .../main/java/net/sourceforge/pmd/cli/PMDParameters.java | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 7723accb1b..d8120fd661 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -40,6 +40,10 @@ This is a {{ site.pmd.release_type }} release. by {% jdoc !!core::lang.document.FileCollector#addZipFileWithContent(java.nio.file.Path) %} which directly adds the content of the zip file for analysis. +* {% jdoc !!core::PMDConfiguration#setReportShortNames(boolean) %} and + {% jdoc !!core::PMDConfiguration#isReportShortNames() %} have been deprecated for removal. + Use {% jdoc !!core::PMDConfiguration#addRelativizeRoot(java.nio.file.Path) %} instead. + ##### Internal APIs * {% jdoc core::renderers.CSVWriter %} diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java index 2c9ff0530a..776a9712bc 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java @@ -74,8 +74,8 @@ import net.sourceforge.pmd.util.ClasspathClassLoader; *
    *
  • The renderer format to use for Reports. {@link #getReportFormat()}
  • *
  • The file to which the Report should render. {@link #getReportFile()}
  • - *
  • An indicator of whether to use File short names in Reports, defaults to - * false. {@link #isReportShortNames()}
  • + *
  • Configure the root paths that are used to relativize file names in reports via {@link #addRelativizeRoot(Path)}. + * This enables to get short names in reports.
  • *
  • The initialization properties to use when creating a Renderer instance. * {@link #getReportProperties()}
  • *
  • An indicator of whether to show suppressed Rule violations in Reports. @@ -116,6 +116,7 @@ public class PMDConfiguration extends AbstractConfiguration { // Reporting options private String reportFormat; private Path reportFile; + @Deprecated private boolean reportShortNames = false; private Properties reportProperties = new Properties(); private boolean showSuppressedViolations = false; @@ -635,6 +636,7 @@ public class PMDConfiguration extends AbstractConfiguration { * * @return true when using short names in reports. */ + @Deprecated public boolean isReportShortNames() { return reportShortNames; } @@ -644,7 +646,9 @@ public class PMDConfiguration extends AbstractConfiguration { * * @param reportShortNames * true when using short names in reports. + * @deprecated for removal. Use {@link #addRelativizeRoot(Path)} instead. */ + @Deprecated public void setReportShortNames(boolean reportShortNames) { this.reportShortNames = reportShortNames; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java index b956cac746..3a39b4bc63 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java @@ -127,10 +127,10 @@ public class PMDParameters { @Parameter(names = { RELATIVIZE_PATHS_WITH, "-z" }, variableArity = true, - description = "Path relative to which directories are rendered in the report." + description = "Path relative to which directories are rendered in the report. " + "This option allows shortening directories in the report; " + "without it, paths are rendered as mentioned in the source directory (option \"--dir\"). " - + "The option can be repeated, in which case the shortest relative path will be used." + + "The option can be repeated, in which case the shortest relative path will be used. " + "If the root path is mentioned (e.g. \"/\" or \"C:\\\"), then the paths will be rendered as absolute.", validateValueWith = PathToRelativizeRootValidator.class, converter = StringToPathConverter.class) From 8fa35ae10d9d0ae4783d49ce2ba31cdbddfb86ec Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 25 Jan 2023 16:02:49 +0100 Subject: [PATCH 17/22] Remove old --short-names option (cli + ant) --- docs/pages/pmd/userdocs/cli_reference.md | 7 +---- docs/pages/pmd/userdocs/tools/ant.md | 10 ------- .../java/net/sourceforge/pmd/ant/PMDTask.java | 20 ------------- .../pmd/ant/internal/PMDTaskImpl.java | 12 -------- .../net/sourceforge/pmd/ant/PMDTaskTest.java | 14 ---------- .../sourceforge/pmd/ant/xml/pmdtasktest.xml | 16 +++-------- .../pmd/cli/commands/internal/PmdCommand.java | 6 ---- .../net/sourceforge/pmd/PMDConfiguration.java | 28 +++---------------- .../sourceforge/pmd/cli/PMDParameters.java | 8 ------ .../pmd/internal/util/FileCollectionUtil.java | 18 +----------- .../pmd/lang/document/TextFile.java | 2 +- .../sourceforge/pmd/PmdConfigurationTest.java | 8 ------ .../net/sourceforge/pmd/cli/CoreCliTest.java | 8 ------ 13 files changed, 11 insertions(+), 146 deletions(-) diff --git a/docs/pages/pmd/userdocs/cli_reference.md b/docs/pages/pmd/userdocs/cli_reference.md index b63e6dcebd..ba0353d144 100644 --- a/docs/pages/pmd/userdocs/cli_reference.md +++ b/docs/pages/pmd/userdocs/cli_reference.md @@ -153,17 +153,12 @@ The tool comes with a rather extensive help text, simply running with `--help`! description="Path relative to which directories are rendered in the report. This option allows shortening directories in the report; without it, paths are rendered as mentioned in the source directory (option \"--dir\"). The option can be repeated, in which case the shortest relative path will be used. - If the root path is mentioned (e.g. \"/\" or \"C:\\\"), then the paths will be rendered as absolute. - This option replaces `--short-names` since PMD 6.54.0." + If the root path is mentioned (e.g. \"/\" or \"C:\\\"), then the paths will be rendered as absolute." %} {% include custom/cli_option_row.html options="--report-file,-r" option_arg="path" description="Path to a file to which report output is written. The file is created if it does not exist. If this option is not specified, the report is rendered to standard output." %} - {% include custom/cli_option_row.html options="--short-names" - description="Prints shortened filenames in the report. -

    Deprecated since PMD 6.54.0. Use `--relativize-paths-with` instead.

    " - %} {% include custom/cli_option_row.html options="--show-suppressed" description="Causes the suppressed rule violations to be added to the report." %} diff --git a/docs/pages/pmd/userdocs/tools/ant.md b/docs/pages/pmd/userdocs/tools/ant.md index 9cf33b6564..c0637db94e 100644 --- a/docs/pages/pmd/userdocs/tools/ant.md +++ b/docs/pages/pmd/userdocs/tools/ant.md @@ -77,15 +77,6 @@ The examples below won't repeat this taskdef element, as this is always required The rule priority threshold; rules with lower priority than they will not be used No - - shortFilenames - - Deprecated Use relativizePathsWith - as nested element instead. - Places truncated filenames in the report. This can reduce your report file size by 15%-20%. - - No - failuresPropertyName A property name to plug the number of rule violations into when the task finishes @@ -207,7 +198,6 @@ fileset elements. See [FileSet](https://ant.apache.org/manual/Types/fileset.html This option allows shortening directories in the report; without it, paths are rendered as absolute paths. The option can be repeated, in which case the shortest relative path will be used. It is a [path-like structure](https://ant.apache.org/manual/using.html#path). -This option replaces `shortFilenames` since PMD 6.54.0. ### Language version selection diff --git a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/PMDTask.java b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/PMDTask.java index bf6528827b..578db83ca5 100644 --- a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/PMDTask.java +++ b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/PMDTask.java @@ -11,7 +11,6 @@ import java.util.Iterator; import java.util.List; import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.Project; import org.apache.tools.ant.Task; import org.apache.tools.ant.types.FileSet; import org.apache.tools.ant.types.Path; @@ -34,8 +33,6 @@ public class PMDTask extends Task { private final List filesets = new ArrayList<>(); private boolean failOnError; private boolean failOnRuleViolation; - @Deprecated - private boolean shortFilenames; private final List relativizePathsWith = new ArrayList<>(); private String suppressMarker; private String rulesetFiles; @@ -86,11 +83,6 @@ public class PMDTask extends Task { } rulesetFiles = getNestedRuleSetFiles(); } - - if (shortFilenames) { - log("DEPRECATED - Use of shortFilenames is deprecated. Use a nested relativePathsWith element instead.", - Project.MSG_WARN); - } } private String getNestedRuleSetFiles() { @@ -105,14 +97,6 @@ public class PMDTask extends Task { return sb.toString(); } - /** - * @deprecated Use {@link #addRelativizePathsWith(Path)} - */ - @Deprecated - public void setShortFilenames(boolean reportShortNames) { - this.shortFilenames = reportShortNames; - } - public void setSuppressMarker(String suppressMarker) { this.suppressMarker = suppressMarker; } @@ -222,10 +206,6 @@ public class PMDTask extends Task { return failOnRuleViolation; } - public boolean isShortFilenames() { - return shortFilenames; - } - public String getSuppressMarker() { return suppressMarker; } diff --git a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java index b636e7c0e4..a39fd1abfd 100644 --- a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java +++ b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/internal/PMDTaskImpl.java @@ -53,7 +53,6 @@ public class PMDTaskImpl { private Project project; public PMDTaskImpl(PMDTask task) { - configuration.setReportShortNames(task.isShortFilenames()); configuration.addRelativizeRoots(task.getRelativizeRoots()); if (task.getSuppressMarker() != null) { configuration.setSuppressMarker(task.getSuppressMarker()); @@ -104,9 +103,6 @@ public class PMDTaskImpl { project.log("Setting suppress marker to be " + configuration.getSuppressMarker(), Project.MSG_VERBOSE); } - - @SuppressWarnings("PMD.CloseResource") final List reportShortNamesPaths = new ArrayList<>(); - List ruleSetPaths = expandRuleSetPaths(configuration.getRuleSetPaths()); // don't let PmdAnalysis.create create rulesets itself. configuration.setRuleSets(Collections.emptyList()); @@ -119,17 +115,9 @@ public class PMDTaskImpl { for (FileSet fileset : filesets) { DirectoryScanner ds = fileset.getDirectoryScanner(project); - if (configuration.isReportShortNames()) { - pmd.files().relativizeWith(ds.getBasedir().getPath()); - } for (String srcFile : ds.getIncludedFiles()) { pmd.files().addFile(ds.getBasedir().toPath().resolve(srcFile)); } - - final String commonInputPath = ds.getBasedir().getPath(); - if (configuration.isReportShortNames()) { - reportShortNamesPaths.add(commonInputPath); - } } @SuppressWarnings("PMD.CloseResource") diff --git a/pmd-ant/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java b/pmd-ant/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java index c12eb9d0b1..d3ea8f2072 100644 --- a/pmd-ant/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java +++ b/pmd-ant/src/test/java/net/sourceforge/pmd/ant/PMDTaskTest.java @@ -69,20 +69,6 @@ class PMDTaskTest extends AbstractAntTest { } } - @Test - void testWithShortFilenames() throws IOException { - executeTarget("testWithShortFilenames"); - - try (InputStream in = Files.newInputStream(Paths.get("target/pmd-ant-test.txt"))) { - String actual = IOUtil.readToString(in, StandardCharsets.UTF_8); - // remove any trailing newline - actual = actual.trim(); - assertThat(actual, containsString("sample.dummy:1:\tSampleXPathRule:\tTest Rule 2")); - } - - assertThat(log.toString(), containsString("DEPRECATED - Use of shortFilenames is deprecated. Use a nested relativePathsWith element instead.")); - } - @Test void testRelativizeWith() throws IOException { executeTarget("testRelativizeWith"); diff --git a/pmd-ant/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml b/pmd-ant/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml index fe9a2bbf9b..fe82ff049a 100644 --- a/pmd-ant/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml +++ b/pmd-ant/src/test/resources/net/sourceforge/pmd/ant/xml/pmdtasktest.xml @@ -25,17 +25,6 @@ - - - - rulesets/dummy/basic.xml - - - - - - - @@ -51,13 +40,16 @@ - + rulesets/dummy/basic.xml + + + diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java index 4ab3a65bcd..cf9ece592f 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java @@ -84,7 +84,6 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand { private boolean benchmark; - private boolean shortnames; private boolean showSuppressed; @@ -140,10 +139,6 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand { this.benchmark = benchmark; } - @Option(names = "--short-names", description = "Prints shortened filenames in the report.") - public void setShortnames(final boolean shortnames) { - this.shortnames = shortnames; - } @Option(names = "--show-suppressed", description = "Report should show suppressed rule violations.") public void setShowSuppressed(final boolean showSuppressed) { @@ -272,7 +267,6 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand { configuration.setMinimumPriority(minimumPriority); configuration.setReportFile(reportFile); configuration.setReportProperties(properties); - configuration.setReportShortNames(shortnames); configuration.setRuleSets(rulesets); configuration.setRuleSetFactoryCompatibilityEnabled(!this.noRuleSetCompatibility); configuration.setShowSuppressedViolations(showSuppressed); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java index 6706d44f96..1c8549fed6 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java @@ -79,8 +79,8 @@ import net.sourceforge.pmd.util.log.internal.SimpleMessageReporter; *
      *
    • The renderer format to use for Reports. {@link #getReportFormat()}
    • *
    • The file to which the Report should render. {@link #getReportFile()}
    • - *
    • An indicator of whether to use File short names in Reports, defaults to - * false. {@link #isReportShortNames()}
    • + *
    • Configure the root paths that are used to relativize file names in reports via {@link #addRelativizeRoot(Path)}. + * This enables to get short names in reports.
    • *
    • The initialization properties to use when creating a Renderer instance. * {@link #getReportProperties()}
    • *
    • An indicator of whether to show suppressed Rule violations in Reports. @@ -123,7 +123,6 @@ public class PMDConfiguration extends AbstractConfiguration { // Reporting options private String reportFormat; private Path reportFile; - private boolean reportShortNames = false; private Properties reportProperties = new Properties(); private boolean showSuppressedViolations = false; private boolean failOnViolation = true; @@ -485,7 +484,7 @@ public class PMDConfiguration extends AbstractConfiguration { * @param inputPaths The comma separated list. * * @throws NullPointerException If the parameter is null - * @deprecated Use {@link #setInputPaths(List)} or {@link #addInputPath(String)} + * @deprecated Use {@link #setInputPathList(List)} or {@link #addInputPath(Path)} */ @Deprecated public void setInputPaths(String inputPaths) { @@ -602,25 +601,6 @@ public class PMDConfiguration extends AbstractConfiguration { this.inputUri = inputUri; } - /** - * Get whether to use File short names in Reports. - * - * @return true when using short names in reports. - */ - public boolean isReportShortNames() { - return reportShortNames; - } - - /** - * Set whether to use File short names in Reports. - * - * @param reportShortNames - * true when using short names in reports. - */ - public void setReportShortNames(boolean reportShortNames) { - this.reportShortNames = reportShortNames; - } - /** * Create a Renderer instance based upon the configured reporting options. * No writer is created. @@ -955,7 +935,7 @@ public class PMDConfiguration extends AbstractConfiguration { /** * Returns the paths used to shorten paths output in the report. *
        - *
      • If the list is empty, then paths are not touched (unless {@link #isReportShortNames()} is true) + *
      • If the list is empty, then paths are not touched *
      • If the list is non-empty, then source file paths are relativized with all the items in the list. * The shortest of these relative paths is taken as the display name of the file. *
      diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java index ab271a24e5..a3a9b353f9 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java @@ -103,9 +103,6 @@ public class PMDParameters { @Parameter(names = { "--stress", "-stress", "-S" }, description = "Performs a stress test.") private boolean stress = false; - @Parameter(names = { "--short-names", "-shortnames" }, description = "Prints shortened filenames in the report.") - private boolean shortnames = false; - @Parameter(names = { "--show-suppressed", "-showsuppressed" }, description = "Report should show suppressed rule violations.") private boolean showsuppressed = false; @@ -272,7 +269,6 @@ public class PMDParameters { configuration.setMinimumPriority(this.getMinimumPriority()); configuration.setReportFile(this.getReportfile()); configuration.setReportProperties(this.getProperties()); - configuration.setReportShortNames(this.isShortnames()); configuration.setRuleSets(Arrays.asList(this.getRulesets().split(","))); configuration.setRuleSetFactoryCompatibilityEnabled(!this.noRuleSetCompatibility); configuration.setShowSuppressedViolations(this.isShowsuppressed()); @@ -354,10 +350,6 @@ public class PMDParameters { return stress; } - public boolean isShortnames() { - return shortnames; - } - public boolean isShowsuppressed() { return showsuppressed; } diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java index d77cb13b43..f06a227c31 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/internal/util/FileCollectionUtil.java @@ -42,23 +42,7 @@ public final class FileCollectionUtil { } - // This is to be removed when --short-names is removed. - // If the new --relativize-paths-with option is specified (!= null), it takes precedence. - boolean legacyShortNamesBehavior = - configuration.getRelativizeRoots().isEmpty() && configuration.isReportShortNames(); - - for (Path path : configuration.getInputPathList()) { - try { - if (legacyShortNamesBehavior) { - collector.relativizeWith(path.toString()); - } - addRoot(collector, path); - } catch (IOException e) { - collector.getReporter().errorEx("Error collecting " + path, e); - } - } - // use that, once --short-names is removed - //collectFiles(collector, configuration.getInputPathList()); + collectFiles(collector, configuration.getInputPathList()); if (configuration.getUri() != null) { collectDB(collector, configuration.getUri()); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextFile.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextFile.java index 324bf8e33b..6e0af1e1b4 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextFile.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/TextFile.java @@ -283,7 +283,7 @@ public interface TextFile extends Closeable { @Override public @NonNull String getDisplayName() { - return ds.getNiceFileName(config.isReportShortNames(), shortPaths); + return ds.getNiceFileName(false, shortPaths); } @Override diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/PmdConfigurationTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/PmdConfigurationTest.java index 772e481c9c..127fea8da0 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/PmdConfigurationTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/PmdConfigurationTest.java @@ -167,14 +167,6 @@ class PmdConfigurationTest { assertEquals(expected, configuration.getInputPathList(), "Changed input paths"); } - @Test - void testReportShortNames() { - PMDConfiguration configuration = new PMDConfiguration(); - assertEquals(false, configuration.isReportShortNames(), "Default report short names"); - configuration.setReportShortNames(true); - assertEquals(true, configuration.isReportShortNames(), "Changed report short names"); - } - @Test void testReportFormat() { PMDConfiguration configuration = new PMDConfiguration(); diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java index 97418bf319..f30b3be477 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java @@ -255,14 +255,6 @@ class CoreCliTest { + srcDir.resolve("someSource.dummy"))); } - @Test - void testDeprecationWarningForShortNames() throws Exception { - String log = runPmdSuccessfully("--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET, "--short-names"); - - assertThat(log, containsString("Some deprecated options were used on the command-line, including --short-names")); - assertThat(log, containsString("Consider replacing it with --relativize-paths-with")); - } - @Test void testFileCollectionWithUnknownFiles() throws Exception { Path reportFile = tempRoot().resolve("out/reportFile.txt"); From c659e86bea1a0bf53b5962c910c5e8a28b7044f4 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 25 Jan 2023 16:25:02 +0100 Subject: [PATCH 18/22] Add new option --relativize-paths-with to new cli --- .../pmd/cli/commands/internal/PmdCommand.java | 21 +++++++++++++++++++ .../net/sourceforge/pmd/cli/PmdCliTest.java | 20 ++++++++++++++++++ .../net/sourceforge/pmd/cli/FakeRuleset2.xml | 21 +++++++++++++++++++ 3 files changed, 62 insertions(+) create mode 100644 pmd-cli/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java index cf9ece592f..1e5f34974e 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java @@ -7,7 +7,9 @@ package net.sourceforge.pmd.cli.commands.internal; import java.io.IOException; import java.io.OutputStreamWriter; import java.io.Writer; +import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -84,6 +86,7 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand { private boolean benchmark; + private List relativizeRootPaths; private boolean showSuppressed; @@ -139,6 +142,21 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand { this.benchmark = benchmark; } + @Option(names = { "--relativize-paths-with", "-z"}, description = "Path relative to which directories are rendered in the report. " + + "This option allows shortening directories in the report; " + + "without it, paths are rendered as mentioned in the source directory (option \"--dir\"). " + + "The option can be repeated, in which case the shortest relative path will be used. " + + "If the root path is mentioned (e.g. \"/\" or \"C:\\\"), then the paths will be rendered as absolute.") + public void setRelativizePathsWith(List rootPaths) { + this.relativizeRootPaths = rootPaths.stream().map(Paths::get).collect(Collectors.toList()); + + for (Path path : this.relativizeRootPaths) { + if (Files.isRegularFile(path)) { + throw new ParameterException(spec.commandLine(), + "Expected a directory path for option '--relativize-paths-with', found a file: " + path); + } + } + } @Option(names = "--show-suppressed", description = "Report should show suppressed rule violations.") public void setShowSuppressed(final boolean showSuppressed) { @@ -267,6 +285,9 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand { configuration.setMinimumPriority(minimumPriority); configuration.setReportFile(reportFile); configuration.setReportProperties(properties); + if (relativizeRootPaths != null) { + configuration.addRelativizeRoots(relativizeRootPaths); + } configuration.setRuleSets(rulesets); configuration.setRuleSetFactoryCompatibilityEnabled(!this.noRuleSetCompatibility); configuration.setShowSuppressedViolations(showSuppressed); diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java index 6679d8d8d5..948d1ff205 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java @@ -26,8 +26,12 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; +import net.sourceforge.pmd.RuleContext; import net.sourceforge.pmd.cli.internal.ExecutionResult; import net.sourceforge.pmd.internal.Slf4jSimpleConfiguration; +import net.sourceforge.pmd.lang.ast.Node; +import net.sourceforge.pmd.lang.rule.MockRule; +import net.sourceforge.pmd.util.IOUtil; import com.github.stefanbirkner.systemlambda.SystemLambda; @@ -37,6 +41,7 @@ class PmdCliTest extends BaseCliTest { private Path tempDir; private static final String DUMMY_RULESET = "net/sourceforge/pmd/cli/FakeRuleset.xml"; + private static final String DUMMY_RULESET_WITH_VIOLATIONS = "net/sourceforge/pmd/cli/FakeRuleset2.xml"; private static final String STRING_TO_REPLACE = "__should_be_replaced__"; private Path srcDir; @@ -206,6 +211,14 @@ class PmdCliTest extends BaseCliTest { assertThat(log, containsString("Usage: pmd check")); } + @Test + void testRelativizeWith() throws Exception { + final String log = runCli(ExecutionResult.VIOLATIONS_FOUND, "--dir", srcDir.toString(), "--rulesets", + DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.getParent().toString()); + assertThat(log, not(containsString(srcDir.resolve("someSource.dummy").toString()))); + assertThat(log, containsString("\n" + IOUtil.normalizePath("src/someSource.dummy"))); + } + // utilities private Path tempRoot() { return tempDir; @@ -239,4 +252,11 @@ class PmdCliTest extends BaseCliTest { return argList; } + + public static class FooRule extends MockRule { + @Override + public void apply(Node node, RuleContext ctx) { + ctx.addViolation(node); + } + } } diff --git a/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml new file mode 100644 index 0000000000..e09f6ff039 --- /dev/null +++ b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml @@ -0,0 +1,21 @@ + + + + + Ruleset used by net.sourceforge.pmd.cli.PmdCliTest + + + + +Just for test + + 3 + + + + + + From 1861ae5b5f61f186121d01e0cb27d5d3bae94488 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Wed, 25 Jan 2023 16:41:19 +0100 Subject: [PATCH 19/22] Move tests from CoreCliTest to PmdCliTest related to --relativize-paths-with --- .../pmd/cli/commands/internal/PmdCommand.java | 11 +- .../net/sourceforge/pmd/cli/PmdCliTest.java | 119 ++++++++++++++- .../sourceforge/pmd/cli/src/anotherfile.dummy | 1 + .../sourceforge/pmd/cli/src/somefile.dummy | 1 + .../sourceforge/pmd/cli/src/somefile1.dummy | 1 + .../sourceforge/pmd/cli/src/somefile2.dummy | 1 + .../sourceforge/pmd/cli/src/somefile3.dummy | 1 + .../sourceforge/pmd/cli/src/somefile4.dummy | 1 + .../net/sourceforge/pmd/cli/CoreCliTest.java | 143 ------------------ .../net/sourceforge/pmd/cli/FakeRuleset2.xml | 21 --- 10 files changed, 132 insertions(+), 168 deletions(-) create mode 100644 pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/anotherfile.dummy create mode 100644 pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile.dummy create mode 100644 pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile1.dummy create mode 100644 pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile2.dummy create mode 100644 pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile3.dummy create mode 100644 pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile4.dummy delete mode 100644 pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java index 1e5f34974e..83db851e7b 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.Properties; import java.util.stream.Collectors; +import org.apache.commons.lang3.exception.ExceptionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -325,7 +326,15 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand { TimeTracker.startGlobalTracking(); } - final PMDConfiguration configuration = toConfiguration(); + PMDConfiguration configuration = null; + try { + configuration = toConfiguration(); + } catch (IllegalArgumentException e) { + System.err.println("Cannot start analysis: " + e); + LOG.debug(ExceptionUtils.getStackTrace(e)); + return ExecutionResult.USAGE_ERROR; + } + final MessageReporter pmdReporter = configuration.getReporter(); try { diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java index 948d1ff205..ec493e2fea 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java @@ -7,21 +7,24 @@ package net.sourceforge.pmd.cli; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsStringIgnoringCase; +import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.not; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertTrue; +import java.io.File; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; -import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.io.TempDir; @@ -46,8 +49,8 @@ class PmdCliTest extends BaseCliTest { private Path srcDir; - @AfterAll - static void resetLogging() { + @AfterEach + void resetLogging() { // reset logging in case "--debug" changed the logging properties // See also Slf4jSimpleConfigurationForAnt Slf4jSimpleConfiguration.reconfigureDefaultLogLevel(null); @@ -211,6 +214,66 @@ class PmdCliTest extends BaseCliTest { assertThat(log, containsString("Usage: pmd check")); } + @Test + void testNoRelativizeWithAbsoluteSrcDir() throws Exception { + assertTrue(srcDir.isAbsolute(), "srcDir should be absolute"); + String log = runCli(ExecutionResult.VIOLATIONS_FOUND, "--dir", srcDir.toString(), "--rulesets", + DUMMY_RULESET_WITH_VIOLATIONS); + + assertThat(log, containsString(srcDir.resolve("someSource.dummy").toString())); + } + + @Test + void testNoRelativizeWithRelativeSrcDir() throws Exception { + // Note, that we can't reliably change the current working directory for the current java process + // therefore we use the current directory and make sure, we are at the correct place - in pmd-core + Path cwd = Paths.get(".").toRealPath(); + assertThat(cwd.toString(), endsWith("pmd-cli")); + String relativeSrcDir = "src/test/resources/net/sourceforge/pmd/cli/src"; + assertTrue(Files.isDirectory(cwd.resolve(relativeSrcDir))); + + String log = runCli(ExecutionResult.VIOLATIONS_FOUND, "--dir", relativeSrcDir, "--rulesets", + DUMMY_RULESET_WITH_VIOLATIONS); + + assertThat(log, containsString("\n" + IOUtil.normalizePath(relativeSrcDir + "/somefile.dummy"))); + } + + @Test + void testNoRelativizeWithRelativeSrcDirParent() throws Exception { + // Note, that we can't reliably change the current working directory for the current java process + // therefore we use the current directory and make sure, we are at the correct place - in pmd-core + Path cwd = Paths.get(".").toRealPath(); + assertThat(cwd.toString(), endsWith("pmd-cli")); + String relativeSrcDir = IOUtil.normalizePath("src/test/resources/net/sourceforge/pmd/cli/src"); + assertTrue(Files.isDirectory(cwd.resolve(relativeSrcDir))); + + // use the parent directory + String relativeSrcDirWithParent = relativeSrcDir + File.separator + ".."; + + String log = runCli(ExecutionResult.VIOLATIONS_FOUND, "--dir", relativeSrcDirWithParent, "--rulesets", + DUMMY_RULESET_WITH_VIOLATIONS); + + assertThat(log, containsString("\n" + relativeSrcDirWithParent + IOUtil.normalizePath("/src/somefile.dummy"))); + } + + @Test + void testRelativizeWithRootRelativeSrcDir() throws Exception { + // Note, that we can't reliably change the current working directory for the current java process + // therefore we use the current directory and make sure, we are at the correct place - in pmd-core + Path cwd = Paths.get(".").toRealPath(); + assertThat(cwd.toString(), endsWith("pmd-cli")); + String relativeSrcDir = "src/test/resources/net/sourceforge/pmd/cli/src"; + assertTrue(Files.isDirectory(cwd.resolve(relativeSrcDir))); + + String root = cwd.getRoot().toString(); + + String log = runCli(ExecutionResult.VIOLATIONS_FOUND, "--dir", relativeSrcDir, "--rulesets", + DUMMY_RULESET_WITH_VIOLATIONS, "--relativize-paths-with", root); + + String absoluteSrcPath = cwd.resolve(relativeSrcDir).resolve("somefile.dummy").toString(); + assertThat(log, containsString("\n" + absoluteSrcPath)); + } + @Test void testRelativizeWith() throws Exception { final String log = runCli(ExecutionResult.VIOLATIONS_FOUND, "--dir", srcDir.toString(), "--rulesets", @@ -219,6 +282,56 @@ class PmdCliTest extends BaseCliTest { assertThat(log, containsString("\n" + IOUtil.normalizePath("src/someSource.dummy"))); } + @Test + void testRelativizeWithSymLink() throws Exception { + // srcDir = /tmp/junit123/src + // symlinkedSrcDir = /tmp/junit123/sources -> /tmp/junit123/src + Path symlinkedSrcDir = Files.createSymbolicLink(tempRoot().resolve("sources"), srcDir); + String log = runCli(ExecutionResult.VIOLATIONS_FOUND, "--dir", symlinkedSrcDir.toString(), "--rulesets", + DUMMY_RULESET_WITH_VIOLATIONS, "-z", symlinkedSrcDir.toString()); + + assertThat(log, not(containsString(srcDir.resolve("someSource.dummy").toString()))); + assertThat(log, not(containsString(symlinkedSrcDir.resolve("someSource.dummy").toString()))); + assertThat(log, containsString("\nsomeSource.dummy")); + } + + @Test + void testRelativizeWithSymLinkParent() throws Exception { + // srcDir = /tmp/junit123/src + // symlinkedSrcDir = /tmp/junit-relativize-with-123 -> /tmp/junit123/src + Path tempPath = Files.createTempDirectory("junit-relativize-with-"); + Files.delete(tempPath); + Path symlinkedSrcDir = Files.createSymbolicLink(tempPath, srcDir); + // relativizing against parent of symlinkedSrcDir: /tmp + String log = runCli(ExecutionResult.VIOLATIONS_FOUND, "--dir", symlinkedSrcDir.toString(), "--rulesets", + DUMMY_RULESET_WITH_VIOLATIONS, "-z", symlinkedSrcDir.getParent().toString()); + + assertThat(log, not(containsString(srcDir.resolve("someSource.dummy").toString()))); + assertThat(log, not(containsString(symlinkedSrcDir.resolve("someSource.dummy").toString()))); + // base path is symlinkedSrcDir without /tmp: e.g. junit-relativize-with-123 + String basePath = symlinkedSrcDir.getParent().relativize(symlinkedSrcDir).toString(); + assertThat(log, containsString("\n" + basePath + File.separator + "someSource.dummy")); + } + + @Test + void testRelativizeWithMultiple() throws Exception { + String log = runCli(ExecutionResult.VIOLATIONS_FOUND, "--dir", srcDir.toString(), "--rulesets", + DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.getParent().toString(), "-z", srcDir.toString()); + + assertThat(log, not(containsString(srcDir.resolve("someSource.dummy").toString()))); + assertThat(log, containsString("\nsomeSource.dummy")); + } + + @Test + void testRelativizeWithFileIsError() throws Exception { + String log = runCli(ExecutionResult.USAGE_ERROR, "--dir", srcDir.toString(), "--rulesets", + DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.resolve("someSource.dummy").toString()); + + assertThat(log, containsString( + "Expected a directory path for option '--relativize-paths-with', found a file: " + + srcDir.resolve("someSource.dummy"))); + } + // utilities private Path tempRoot() { return tempDir; diff --git a/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/anotherfile.dummy b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/anotherfile.dummy new file mode 100644 index 0000000000..c3d7ac9496 --- /dev/null +++ b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/anotherfile.dummy @@ -0,0 +1 @@ +Another file for testing diff --git a/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile.dummy b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile.dummy new file mode 100644 index 0000000000..901f2e4bd0 --- /dev/null +++ b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile.dummy @@ -0,0 +1 @@ +Some file for testing diff --git a/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile1.dummy b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile1.dummy new file mode 100644 index 0000000000..901f2e4bd0 --- /dev/null +++ b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile1.dummy @@ -0,0 +1 @@ +Some file for testing diff --git a/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile2.dummy b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile2.dummy new file mode 100644 index 0000000000..901f2e4bd0 --- /dev/null +++ b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile2.dummy @@ -0,0 +1 @@ +Some file for testing diff --git a/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile3.dummy b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile3.dummy new file mode 100644 index 0000000000..901f2e4bd0 --- /dev/null +++ b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile3.dummy @@ -0,0 +1 @@ +Some file for testing diff --git a/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile4.dummy b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile4.dummy new file mode 100644 index 0000000000..901f2e4bd0 --- /dev/null +++ b/pmd-cli/src/test/resources/net/sourceforge/pmd/cli/src/somefile4.dummy @@ -0,0 +1 @@ +Some file for testing diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java index f30b3be477..99e8b06697 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java @@ -7,16 +7,13 @@ package net.sourceforge.pmd.cli; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.containsStringIgnoringCase; -import static org.hamcrest.Matchers.endsWith; import static org.hamcrest.Matchers.not; -import static org.hamcrest.Matchers.startsWith; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.fail; -import java.io.File; import java.io.FileOutputStream; import java.io.FilterOutputStream; import java.io.IOException; @@ -26,7 +23,6 @@ import java.nio.charset.StandardCharsets; import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; @@ -37,10 +33,7 @@ import org.junit.jupiter.api.io.TempDir; import net.sourceforge.pmd.PMD; import net.sourceforge.pmd.PMD.StatusCode; -import net.sourceforge.pmd.RuleContext; import net.sourceforge.pmd.internal.Slf4jSimpleConfiguration; -import net.sourceforge.pmd.lang.ast.Node; -import net.sourceforge.pmd.lang.rule.MockRule; import net.sourceforge.pmd.util.IOUtil; import com.github.stefanbirkner.systemlambda.SystemLambda; @@ -54,7 +47,6 @@ class CoreCliTest { private Path tempDir; private static final String DUMMY_RULESET = "net/sourceforge/pmd/cli/FakeRuleset.xml"; - private static final String DUMMY_RULESET_WITH_VIOLATIONS = "net/sourceforge/pmd/cli/FakeRuleset2.xml"; private static final String STRING_TO_REPLACE = "__should_be_replaced__"; private Path srcDir; @@ -127,134 +119,6 @@ class CoreCliTest { assertTrue(Files.exists(reportFile), "Report file should have been created"); } - @Test - void testNoRelativizeWithAbsoluteSrcDir() throws Exception { - assertTrue(srcDir.isAbsolute(), "srcDir should be absolute"); - String log = SystemLambda.tapSystemErrAndOut(() -> { - runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS); - }); - - assertThat(log, containsString(srcDir.resolve("someSource.dummy").toString())); - } - - @Test - void testNoRelativizeWithRelativeSrcDir() throws Exception { - // Note, that we can't reliably change the current working directory for the current java process - // therefore we use the current directory and make sure, we are at the correct place - in pmd-core - Path cwd = Paths.get(".").toRealPath(); - assertThat(cwd.toString(), endsWith("pmd-core")); - String relativeSrcDir = "src/test/resources/net/sourceforge/pmd/cli/src"; - assertTrue(Files.isDirectory(cwd.resolve(relativeSrcDir))); - - String log = SystemLambda.tapSystemErrAndOut(() -> { - runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", relativeSrcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS); - }); - - assertThat(log, containsString("\n" + IOUtil.normalizePath(relativeSrcDir + "/somefile.dummy"))); - } - - @Test - void testNoRelativizeWithRelativeSrcDirParent() throws Exception { - // Note, that we can't reliably change the current working directory for the current java process - // therefore we use the current directory and make sure, we are at the correct place - in pmd-core - Path cwd = Paths.get(".").toRealPath(); - assertThat(cwd.toString(), endsWith("pmd-core")); - String relativeSrcDir = IOUtil.normalizePath("src/test/resources/net/sourceforge/pmd/cli/src"); - assertTrue(Files.isDirectory(cwd.resolve(relativeSrcDir))); - - // use the parent directory - String relativeSrcDirWithParent = relativeSrcDir + File.separator + ".."; - - String log = SystemLambda.tapSystemErrAndOut(() -> { - runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", relativeSrcDirWithParent, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS); - }); - - assertThat(log, containsString("\n" + relativeSrcDirWithParent + IOUtil.normalizePath("/src/somefile.dummy"))); - } - - @Test - void testRelativizeWithRootRelativeSrcDir() throws Exception { - // Note, that we can't reliably change the current working directory for the current java process - // therefore we use the current directory and make sure, we are at the correct place - in pmd-core - Path cwd = Paths.get(".").toRealPath(); - assertThat(cwd.toString(), endsWith("pmd-core")); - String relativeSrcDir = "src/test/resources/net/sourceforge/pmd/cli/src"; - assertTrue(Files.isDirectory(cwd.resolve(relativeSrcDir))); - - String root = cwd.getRoot().toString(); - - String log = SystemLambda.tapSystemErrAndOut(() -> { - runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", relativeSrcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "--relativize-paths-with", root); - }); - - String absoluteSrcPath = cwd.resolve(relativeSrcDir).resolve("somefile.dummy").toString(); - assertThat(log, containsString("\n" + absoluteSrcPath)); - } - - @Test - void testRelativizeWith() throws Exception { - String log = SystemLambda.tapSystemOut(() -> { - runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.getParent()); - }); - - assertThat(log, not(containsString(srcDir.resolve("someSource.dummy").toString()))); - assertThat(log, startsWith(IOUtil.normalizePath("src/someSource.dummy"))); - } - - @Test - void testRelativizeWithSymLink() throws Exception { - // srcDir = /tmp/junit123/src - // symlinkedSrcDir = /tmp/junit123/sources -> /tmp/junit123/src - Path symlinkedSrcDir = Files.createSymbolicLink(tempRoot().resolve("sources"), srcDir); - String log = SystemLambda.tapSystemOut(() -> { - runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", symlinkedSrcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", symlinkedSrcDir); - }); - - assertThat(log, not(containsString(srcDir.resolve("someSource.dummy").toString()))); - assertThat(log, not(containsString(symlinkedSrcDir.resolve("someSource.dummy").toString()))); - assertThat(log, startsWith("someSource.dummy")); - } - - @Test - void testRelativizeWithSymLinkParent() throws Exception { - // srcDir = /tmp/junit123/src - // symlinkedSrcDir = /tmp/junit-relativize-with-123 -> /tmp/junit123/src - Path tempPath = Files.createTempDirectory("junit-relativize-with-"); - Files.delete(tempPath); - Path symlinkedSrcDir = Files.createSymbolicLink(tempPath, srcDir); - // relativizing against parent of symlinkedSrcDir: /tmp - String log = SystemLambda.tapSystemOut(() -> { - runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", symlinkedSrcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", symlinkedSrcDir.getParent()); - }); - - assertThat(log, not(containsString(srcDir.resolve("someSource.dummy").toString()))); - assertThat(log, not(containsString(symlinkedSrcDir.resolve("someSource.dummy").toString()))); - // base path is symlinkedSrcDir without /tmp: e.g. junit-relativize-with-123 - String basePath = symlinkedSrcDir.getParent().relativize(symlinkedSrcDir).toString(); - assertThat(log, startsWith(basePath + File.separator + "someSource.dummy")); - } - - @Test - void testRelativizeWithMultiple() throws Exception { - String log = SystemLambda.tapSystemOut(() -> { - runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.getParent(), srcDir); - }); - - assertThat(log, not(containsString(srcDir.resolve("someSource.dummy").toString()))); - assertThat(log, startsWith("someSource.dummy")); - } - - @Test - void testRelativizeWithFileIsError() throws Exception { - String log = SystemLambda.tapSystemErr(() -> { - runPmd(StatusCode.ERROR, "--no-cache", "--dir", srcDir, "--rulesets", DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.resolve("someSource.dummy")); - }); - - assertThat(log, containsString( - "Expected a directory path for option --relativize-paths-with, found a file: " - + srcDir.resolve("someSource.dummy"))); - } - @Test void testFileCollectionWithUnknownFiles() throws Exception { Path reportFile = tempRoot().resolve("out/reportFile.txt"); @@ -450,11 +314,4 @@ class CoreCliTest { StatusCode actualExitCode = PMD.runPmd(argsToString(args)); assertEquals(expectedExitCode, actualExitCode, "Exit code"); } - - public static class FooRule extends MockRule { - @Override - public void apply(Node node, RuleContext ctx) { - ctx.addViolation(node); - } - } } diff --git a/pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml b/pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml deleted file mode 100644 index 33a996d1ba..0000000000 --- a/pmd-core/src/test/resources/net/sourceforge/pmd/cli/FakeRuleset2.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - Ruleset used by test RuleSetFactoryTest - - - - -Just for test - - 3 - - - - - - From 047d8db8e20e69f4cc52b6b76e38b528603d64b2 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Jan 2023 10:40:13 +0100 Subject: [PATCH 20/22] Fix tests under Windows --- .../src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java | 4 ++-- .../net/sourceforge/pmd/lang/document/NioTextFileTest.java | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java index 99e8b06697..b695153ede 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/cli/CoreCliTest.java @@ -250,7 +250,7 @@ class CoreCliTest { runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", zipArchive, "--rulesets", "rulesets/dummy/basic.xml"); }); assertThat(log, not(containsStringIgnoringCase("Cannot open zip file"))); - String reportPath = IOUtil.normalizePath(zipArchive.toString() + "!/someSource.dummy"); + String reportPath = IOUtil.normalizePath(zipArchive.toString()) + "!/someSource.dummy"; assertThat(log, containsString(reportPath + ":1:\tSampleXPathRule:\tTest Rule 2")); } @@ -261,7 +261,7 @@ class CoreCliTest { runPmd(StatusCode.VIOLATIONS_FOUND, "--no-cache", "--dir", jarArchive, "--rulesets", "rulesets/dummy/basic.xml"); }); assertThat(log, not(containsStringIgnoringCase("Cannot open zip file"))); - String reportPath = IOUtil.normalizePath(jarArchive.toString() + "!/someSource.dummy"); + String reportPath = IOUtil.normalizePath(jarArchive.toString()) + "!/someSource.dummy"; assertThat(log, containsString(reportPath + ":1:\tSampleXPathRule:\tTest Rule 2")); } diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/NioTextFileTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/NioTextFileTest.java index f03454451d..6638422a3a 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/NioTextFileTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/lang/document/NioTextFileTest.java @@ -18,7 +18,6 @@ import org.junit.jupiter.api.io.TempDir; import net.sourceforge.pmd.lang.LanguageRegistry; import net.sourceforge.pmd.lang.LanguageVersionDiscoverer; -import net.sourceforge.pmd.util.IOUtil; class NioTextFileTest { @@ -41,7 +40,7 @@ class NioTextFileTest { List collectedFiles = collector.getCollectedFiles(); assertEquals(1, collectedFiles.size()); TextFile textFile = collectedFiles.get(0); - assertEquals(zipArchive.toAbsolutePath() + "!" + IOUtil.normalizePath("/path/inside/someSource.dummy"), + assertEquals(zipArchive.toAbsolutePath() + "!/path/inside/someSource.dummy", textFile.getDisplayName()); } } From 6e2b2cb579f067111351f1ae2687259cc8530c66 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Jan 2023 13:10:29 +0100 Subject: [PATCH 21/22] Fix dogfood issues - SimplifyBooleanReturns --- .../pmd/lang/document/FileCollector.java | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java index b6b2576f18..e3ca07677a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/lang/document/FileCollector.java @@ -153,12 +153,10 @@ public final class FileCollector implements AutoCloseable { return false; } LanguageVersion languageVersion = discoverLanguage(file.toString()); - if (languageVersion != null) { - return addFileImpl(TextFile.builderForPath(file, charset, languageVersion) - .withDisplayName(getDisplayName(file)) - .build()); - } - return false; + return languageVersion != null + && addFileImpl(TextFile.builderForPath(file, charset, languageVersion) + .withDisplayName(getDisplayName(file)) + .build()); } /** @@ -193,10 +191,7 @@ public final class FileCollector implements AutoCloseable { */ public boolean addFile(TextFile textFile) { AssertionUtil.requireParamNotNull("textFile", textFile); - if (checkContextualVersion(textFile)) { - return addFileImpl(textFile); - } - return false; + return checkContextualVersion(textFile) && addFileImpl(textFile); } /** @@ -210,13 +205,10 @@ public final class FileCollector implements AutoCloseable { AssertionUtil.requireParamNotNull("pathId", pathId); LanguageVersion version = discoverLanguage(pathId); - if (version != null) { - return addFileImpl(TextFile.builderForCharSeq(sourceContents, pathId, version) - .withDisplayName(pathId) - .build()); - } - - return false; + return version != null + && addFileImpl(TextFile.builderForCharSeq(sourceContents, pathId, version) + .withDisplayName(pathId) + .build()); } private boolean addFileImpl(TextFile textFile) { From 8e558eaeaf0d5acb778e632e72102f91605bcab6 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Thu, 26 Jan 2023 18:16:39 +0100 Subject: [PATCH 22/22] Fixes from review (#4363) --- .../pmd/cli/commands/internal/PmdCommand.java | 19 +++++-------------- .../net/sourceforge/pmd/cli/PmdCliTest.java | 2 +- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java index fd1cd12030..e2da3c1af7 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java @@ -9,14 +9,12 @@ import java.io.OutputStreamWriter; import java.io.Writer; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.stream.Collectors; -import org.apache.commons.lang3.exception.ExceptionUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -147,9 +145,10 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand { + "This option allows shortening directories in the report; " + "without it, paths are rendered as mentioned in the source directory (option \"--dir\"). " + "The option can be repeated, in which case the shortest relative path will be used. " - + "If the root path is mentioned (e.g. \"/\" or \"C:\\\"), then the paths will be rendered as absolute.") - public void setRelativizePathsWith(List rootPaths) { - this.relativizeRootPaths = rootPaths.stream().map(Paths::get).collect(Collectors.toList()); + + "If the root path is mentioned (e.g. \"/\" or \"C:\\\"), then the paths will be rendered as absolute.", + arity = "1..*", split = ",") + public void setRelativizePathsWith(List rootPaths) { + this.relativizeRootPaths = rootPaths; for (Path path : this.relativizeRootPaths) { if (Files.isRegularFile(path)) { @@ -326,15 +325,7 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand { TimeTracker.startGlobalTracking(); } - PMDConfiguration configuration = null; - try { - configuration = toConfiguration(); - } catch (IllegalArgumentException e) { - System.err.println("Cannot start analysis: " + e); - LOG.debug(ExceptionUtils.getStackTrace(e)); - return CliExitCode.USAGE_ERROR; - } - + final PMDConfiguration configuration = toConfiguration(); final MessageReporter pmdReporter = configuration.getReporter(); try { diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java index 582ba8a764..f95c39afc7 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java @@ -446,7 +446,7 @@ class PmdCliTest extends BaseCliTest { @Test void testRelativizeWithMultiple() throws Exception { runCli(CliExitCode.VIOLATIONS_FOUND, "--dir", srcDir.toString(), "--rulesets", - DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.getParent().toString(), "-z", srcDir.toString()) + DUMMY_RULESET_WITH_VIOLATIONS, "-z", srcDir.getParent().toString() + "," + srcDir.toString()) .verify(result -> { result.checkStdOut(not(containsString(srcDir.resolve("someSource.dummy").toString()))); result.checkStdOut(startsWith("someSource.dummy"));