From 34abe877e243d06af67c6fc5c2822b192ce3f770 Mon Sep 17 00:00:00 2001 From: Bruno Ferreira Date: Mon, 14 Jan 2019 23:12:32 +0000 Subject: [PATCH 1/3] Sorts the listed files by path in order to avoid unconsistencies since the listing on directories provided by tha java api does not guarantee always the same order. Therefore, sorting the files by path (ignoring the case), we can guarantee that the files will be iterated always by the same order, avoiding returning different clones for the same files in different cpd executions. --- .../net/sourceforge/pmd/util/FileFinder.java | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/FileFinder.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/FileFinder.java index 544e10dad6..fd001d34a5 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/FileFinder.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/FileFinder.java @@ -7,6 +7,8 @@ package net.sourceforge.pmd.util; import java.io.File; import java.io.FilenameFilter; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; /** @@ -17,10 +19,25 @@ public class FileFinder { private FilenameFilter filter; private static final String FILE_SEP = System.getProperty("file.separator"); + /** + * Searches for files in a given directory. + * The returned files are sorted alphabetically by path, ignoring the case. + * + * @param dir the directory to search files + * @param filter the filename filter that can optionally be passed to get files that match this filter + * @param recurse search for files recursively or not + * @return list of the found files sorted alphabetically by path, ignoring the case + */ public List findFilesFrom(File dir, FilenameFilter filter, boolean recurse) { this.filter = filter; List files = new ArrayList<>(); scanDirectory(dir, files, recurse); + Collections.sort(files, new Comparator() { + @Override + public int compare(File o1, File o2) { + return o1.getPath().compareToIgnoreCase(o2.getPath()); + } + }); return files; } From 214dc7f8c735872d42c4325d05191b47727f5360 Mon Sep 17 00:00:00 2001 From: Bruno Ferreira Date: Sat, 19 Jan 2019 12:34:47 +0000 Subject: [PATCH 2/3] Starts using the PathFileComparator from apache commons instead of custom comparator. Moves the sort to the private method that scans directories and starts listing files instead of paths, avoiding the creation of new File instances on our own. --- .../net/sourceforge/pmd/util/FileFinder.java | 26 ++++++++----------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/util/FileFinder.java b/pmd-core/src/main/java/net/sourceforge/pmd/util/FileFinder.java index fd001d34a5..d4719bb444 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/util/FileFinder.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/util/FileFinder.java @@ -7,37 +7,31 @@ package net.sourceforge.pmd.util; import java.io.File; import java.io.FilenameFilter; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; +import java.util.Arrays; import java.util.List; +import org.apache.commons.io.comparator.PathFileComparator; + /** * A utility class for finding files within a directory. */ public class FileFinder { private FilenameFilter filter; - private static final String FILE_SEP = System.getProperty("file.separator"); /** * Searches for files in a given directory. - * The returned files are sorted alphabetically by path, ignoring the case. * * @param dir the directory to search files * @param filter the filename filter that can optionally be passed to get files that match this filter * @param recurse search for files recursively or not - * @return list of the found files sorted alphabetically by path, ignoring the case + * @return list of files from the given directory */ public List findFilesFrom(File dir, FilenameFilter filter, boolean recurse) { this.filter = filter; List files = new ArrayList<>(); scanDirectory(dir, files, recurse); - Collections.sort(files, new Comparator() { - @Override - public int compare(File o1, File o2) { - return o1.getPath().compareToIgnoreCase(o2.getPath()); - } - }); + return files; } @@ -45,18 +39,20 @@ public class FileFinder { * Implements a tail recursive file scanner */ private void scanDirectory(File dir, List list, boolean recurse) { - String[] candidates = dir.list(filter); + File[] candidates = dir.listFiles(filter); if (candidates == null) { return; } - for (int i = 0; i < candidates.length; i++) { - File tmp = new File(dir + FILE_SEP + candidates[i]); + + Arrays.sort(candidates, PathFileComparator.PATH_INSENSITIVE_COMPARATOR); + + for (File tmp : candidates) { if (tmp.isDirectory()) { if (recurse) { scanDirectory(tmp, list, true); } } else { - list.add(new File(dir + FILE_SEP + candidates[i])); + list.add(tmp); } } } From add3957b718f6c4c6bc666cbae707094957d7947 Mon Sep 17 00:00:00 2001 From: Andreas Dangel Date: Sat, 19 Jan 2019 18:07:46 +0100 Subject: [PATCH 3/3] Update release notes, refs #1584, fixes #1196 --- docs/pages/release_notes.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index a95dc2b305..7079339b36 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -37,6 +37,8 @@ This is a {{ site.pmd.release_type }} release. ### Fixed Issues +* all + * [#1196](https://github.com/pmd/pmd/issues/1196): \[core] CPD results not consistent between runs * apex * [#1542](https://github.com/pmd/pmd/pull/1542): \[apex] Include the documentation category * java @@ -70,6 +72,7 @@ This is a {{ site.pmd.release_type }} release. * [#1534](https://github.com/pmd/pmd/pull/1534): \[java] This is the change regarding the usediamondoperator #1517 - [hemanshu070](https://github.com/hemanshu070) * [#1545](https://github.com/pmd/pmd/pull/1545): \[doc] fixing dead links + tool to check for dead links automatically - [Kris Scheibe](https://github.com/kris-scheibe) * [#1551](https://github.com/pmd/pmd/pull/1551): \[java] InvalidSlf4jMessageFormatRule should not throw NPE for enums - [Robbie Martinus](https://github.com/rmartinus) +* [#1584](https://github.com/pmd/pmd/pull/1584): \[core] Fixes 1196: inconsistencies of clones returned by different CPD executions for the same files - [Bruno Ferreira](https://github.com/bmbferreira) {% endtocmaker %}