@@ -29,6 +29,28 @@ public class FileNameResolver {
2929 */
3030 public void run (final Report report , final String sourceDirectoryPrefix ,
3131 final Predicate <String > skipFileNamePredicate ) {
32+ run (report , sourceDirectoryPrefix , skipFileNamePredicate , "" , "" );
33+ }
34+
35+ /**
36+ * Resolves the file names of the affected files of the specified set of issues with optional path remapping.
37+ * This is useful when the paths in the report are generated in a different environment (e.g., inside a Docker
38+ * container) and need to be remapped to the actual workspace paths.
39+ *
40+ * @param report
41+ * the issues to resolve the paths
42+ * @param sourceDirectoryPrefix
43+ * absolute source path that should be used as parent folder to search for files
44+ * @param skipFileNamePredicate
45+ * skip specific files based on the file name
46+ * @param sourcePathPrefix
47+ * the path prefix to be replaced (e.g., path inside docker container). Empty string means no remapping.
48+ * @param targetPathPrefix
49+ * the path prefix to replace with (e.g., path in Jenkins workspace). Empty string means no remapping.
50+ */
51+ public void run (final Report report , final String sourceDirectoryPrefix ,
52+ final Predicate <String > skipFileNamePredicate , final String sourcePathPrefix ,
53+ final String targetPathPrefix ) {
3254 Set <String > filesToProcess = report .getFiles ()
3355 .stream ()
3456 .filter (fileName -> isInterestingFileName (fileName , skipFileNamePredicate ))
@@ -40,6 +62,8 @@ public void run(final Report report, final String sourceDirectoryPrefix,
4062 return ;
4163 }
4264
65+ filesToProcess = applyPathMapping (report , sourcePathPrefix , targetPathPrefix , skipFileNamePredicate );
66+
4367 Map <String , String > pathMapping = filesToProcess .parallelStream ()
4468 .collect (Collectors .toMap (fileName -> fileName ,
4569 fileName -> makeRelative (sourceDirectoryPrefix , fileName )))
@@ -57,6 +81,43 @@ public void run(final Report report, final String sourceDirectoryPrefix,
5781 pathMapping .size (), filesToProcess .size () - pathMapping .size ());
5882 }
5983
84+ /**
85+ * Applies path mapping to the issues in the report. This remaps file paths from one prefix to another, which is
86+ * useful when the report was generated in a different environment (e.g., inside a Docker container).
87+ *
88+ * @param report
89+ * the issues to remap paths for
90+ * @param sourcePathPrefix
91+ * the path prefix to be replaced (e.g., path inside docker container). Empty string means no remapping.
92+ * @param targetPathPrefix
93+ * the path prefix to replace with (e.g., path in Jenkins workspace). Empty string means no remapping.
94+ * @param skipFileNamePredicate
95+ * skip specific files based on the file name
96+ *
97+ * @return the updated set of files to process after remapping
98+ */
99+ private Set <String > applyPathMapping (final Report report , final String sourcePathPrefix ,
100+ final String targetPathPrefix , final Predicate <String > skipFileNamePredicate ) {
101+ boolean shouldRemap = !sourcePathPrefix .isEmpty () && !targetPathPrefix .isEmpty ();
102+ if (shouldRemap ) {
103+ report .logInfo ("-> remapping paths from '%s' to '%s'" , sourcePathPrefix , targetPathPrefix );
104+ try (var builder = new IssueBuilder ()) {
105+ report .stream ()
106+ .filter (issue -> issue .getFileName ().startsWith (sourcePathPrefix ))
107+ .forEach (issue -> {
108+ String originalPath = issue .getFileName ();
109+ String remappedPath = targetPathPrefix + originalPath .substring (sourcePathPrefix .length ());
110+ issue .setFileName (issue .getPath (), builder .internFileName (remappedPath ));
111+ });
112+ }
113+ }
114+
115+ return report .getFiles ()
116+ .stream ()
117+ .filter (fileName -> isInterestingFileName (fileName , skipFileNamePredicate ))
118+ .collect (Collectors .toSet ());
119+ }
120+
60121 private String makeRelative (final String sourceDirectoryPrefix , final String fileName ) {
61122 return PATH_UTIL .getRelativePath (sourceDirectoryPrefix , fileName );
62123 }
0 commit comments