Skip to content

Commit 44f2ffd

Browse files
NEW(cpd): @W-16866828@: Implemented the runRules method for CPD (with no configuration yet) (#118)
1 parent 5444607 commit 44f2ffd

40 files changed

+744
-228
lines changed

packages/code-analyzer-pmd-engine/pmd-wrapper/build.gradle.kts renamed to packages/code-analyzer-pmd-engine/pmd-cpd-wrappers/build.gradle.kts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ application {
4242

4343

4444
// Directories of interest
45-
val pmdWrapperDistDir: String = layout.projectDirectory.dir("../dist/pmd-wrapper").asFile.path;
45+
val pmdCpdWrappersDistDir: String = layout.projectDirectory.dir("../dist/pmd-cpd-wrappers").asFile.path;
4646
val reportsDir: String = layout.buildDirectory.dir("reports").get().asFile.path
4747

4848

@@ -59,7 +59,7 @@ tasks.distTar {
5959
// During assemble, we want to run the installDist task (which comes from the distribution plugin which comes from the application plugin)
6060
// instead ... but first we need to modify the location where the jar files should be placed.
6161
tasks.installDist {
62-
into(pmdWrapperDistDir)
62+
into(pmdCpdWrappersDistDir)
6363
includeEmptyDirs = false
6464
}
6565
tasks.assemble {
@@ -102,9 +102,9 @@ tasks.register("showCoverageReport") {
102102

103103

104104
// ======== CLEAN RELATED TASKS ========================================================================================
105-
tasks.register<Delete>("deletePmdWrapperFromDist") {
106-
delete(pmdWrapperDistDir)
105+
tasks.register<Delete>("deletePmdCpdWrappersFromDist") {
106+
delete(pmdCpdWrappersDistDir)
107107
}
108108
tasks.named("clean") {
109-
dependsOn("deletePmdWrapperFromDist")
109+
dependsOn("deletePmdCpdWrappersFromDist")
110110
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.salesforce.sfca.cpdwrapper;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
/**
7+
* Java object to help build cpd results for a specific language.
8+
* We will serialize Map<String, CpdLanguageRunResults> to json to create the overall results for all languages.
9+
*/
10+
public class CpdLanguageRunResults {
11+
public List<Match> matches = new ArrayList<>();
12+
public List<ProcessingError> processingErrors = new ArrayList<>();
13+
14+
public static class Match {
15+
public int numTokensInBlock;
16+
public int numNonemptyLinesInBlock;
17+
public int numBlocks;
18+
public List<BlockLocation> blockLocations = new ArrayList<>();
19+
20+
public static class BlockLocation {
21+
public String file;
22+
public int startLine;
23+
public int startCol;
24+
public int endLine;
25+
public int endCol;
26+
}
27+
}
28+
29+
public static class ProcessingError {
30+
public String file;
31+
public String message;
32+
public String detail;
33+
}
34+
}

packages/code-analyzer-pmd-engine/pmd-wrapper/src/main/java/com/salesforce/sfca/cpdwrapper/CpdRunInputData.java renamed to packages/code-analyzer-pmd-engine/pmd-cpd-wrappers/src/main/java/com/salesforce/sfca/cpdwrapper/CpdRunInputData.java

File renamed without changes.

packages/code-analyzer-pmd-engine/pmd-wrapper/src/main/java/com/salesforce/sfca/cpdwrapper/CpdRunner.java renamed to packages/code-analyzer-pmd-engine/pmd-cpd-wrappers/src/main/java/com/salesforce/sfca/cpdwrapper/CpdRunner.java

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
import java.nio.file.Path;
1616
import java.nio.file.Paths;
1717
import java.text.MessageFormat;
18-
import java.util.ArrayList;
1918
import java.util.HashMap;
2019
import java.util.List;
2120
import java.util.Map;
@@ -25,10 +24,10 @@
2524
* Class to help us invoke CPD - once for each language that should be processed
2625
*/
2726
class CpdRunner {
28-
public Map<String, List<CpdMatch>> run(CpdRunInputData runInputData) throws IOException {
27+
public Map<String, CpdLanguageRunResults> run(CpdRunInputData runInputData) throws IOException {
2928
validateRunInputData(runInputData);
3029

31-
Map<String, List<CpdMatch>> results = new HashMap<>();
30+
Map<String, CpdLanguageRunResults> results = new HashMap<>();
3231

3332
for (Map.Entry<String, List<String>> entry : runInputData.filesToScanPerLanguage.entrySet()) {
3433
String language = entry.getKey();
@@ -37,17 +36,17 @@ public Map<String, List<CpdMatch>> run(CpdRunInputData runInputData) throws IOEx
3736
continue;
3837
}
3938
List<Path> pathsToScan = filesToScan.stream().map(Paths::get).collect(Collectors.toList());
40-
List<CpdMatch> languageMatches = runLanguage(language, pathsToScan, runInputData.minimumTokens, runInputData.skipDuplicateFiles);
39+
CpdLanguageRunResults languageRunResults = runLanguage(language, pathsToScan, runInputData.minimumTokens, runInputData.skipDuplicateFiles);
4140

42-
if (!languageMatches.isEmpty()) {
43-
results.put(language, languageMatches);
41+
if (!languageRunResults.matches.isEmpty() || !languageRunResults.processingErrors.isEmpty()) {
42+
results.put(language, languageRunResults);
4443
}
4544
}
4645

4746
return results;
4847
}
4948

50-
private List<CpdMatch> runLanguage(String language, List<Path> pathsToScan, int minimumTokens, boolean skipDuplicateFiles) throws IOException {
49+
private CpdLanguageRunResults runLanguage(String language, List<Path> pathsToScan, int minimumTokens, boolean skipDuplicateFiles) throws IOException {
5150
// Note that the name "minimumTokens" comes from the public facing documentation and the cli but
5251
// behind the scenes, it maps to MinimumTileSize. To learn more about the mappings to the config, see:
5352
// https://github.com/pmd/pmd/blob/main/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java
@@ -62,23 +61,27 @@ private List<CpdMatch> runLanguage(String language, List<Path> pathsToScan, int
6261
config.setSkipDuplicates(skipDuplicateFiles);
6362
config.setReporter(new CpdErrorListener());
6463

65-
List<CpdMatch> cpdMatches = new ArrayList<>();
64+
CpdLanguageRunResults languageRunResults = new CpdLanguageRunResults();
6665

6766
try (CpdAnalysis cpd = CpdAnalysis.create(config)) {
6867
cpd.performAnalysis(report -> {
69-
for (Report.ProcessingError processingError : report.getProcessingErrors()) {
70-
// We don't expect any processing errors, but if there are any, then we can push them
71-
// to stdOut so that they ultimately get logged. But we should continue as normal here.
72-
System.out.println("Unexpected CPD processing error: " + processingError.getError().getMessage());
68+
69+
for (Report.ProcessingError reportProcessingError : report.getProcessingErrors()) {
70+
CpdLanguageRunResults.ProcessingError processingErr = new CpdLanguageRunResults.ProcessingError();
71+
processingErr.file = reportProcessingError.getFileId().getAbsolutePath();
72+
processingErr.message = reportProcessingError.getMsg();
73+
processingErr.detail = reportProcessingError.getDetail();
74+
languageRunResults.processingErrors.add(processingErr);
7375
}
76+
7477
for (Match match : report.getMatches()) {
75-
CpdMatch cpdMatch = new CpdMatch();
78+
CpdLanguageRunResults.Match cpdMatch = new CpdLanguageRunResults.Match();
7679
cpdMatch.numBlocks = match.getMarkCount();
7780
cpdMatch.numTokensInBlock = match.getTokenCount();
7881
cpdMatch.numNonemptyLinesInBlock = match.getLineCount();
7982

8083
for (Mark mark : match.getMarkSet()) {
81-
CpdMatch.BlockLocation blockLocation = new CpdMatch.BlockLocation();
84+
CpdLanguageRunResults.Match.BlockLocation blockLocation = new CpdLanguageRunResults.Match.BlockLocation();
8285
FileLocation location = mark.getLocation();
8386
blockLocation.file = location.getFileId().getAbsolutePath();
8487
blockLocation.startLine = location.getStartLine();
@@ -89,12 +92,12 @@ private List<CpdMatch> runLanguage(String language, List<Path> pathsToScan, int
8992
cpdMatch.blockLocations.add(blockLocation);
9093
}
9194

92-
cpdMatches.add(cpdMatch);
95+
languageRunResults.matches.add(cpdMatch);
9396
}
9497
});
9598
}
9699

97-
return cpdMatches;
100+
return languageRunResults;
98101
}
99102

100103
private void validateRunInputData(CpdRunInputData runInputData) {

packages/code-analyzer-pmd-engine/pmd-wrapper/src/main/java/com/salesforce/sfca/cpdwrapper/CpdWrapper.java renamed to packages/code-analyzer-pmd-engine/pmd-cpd-wrappers/src/main/java/com/salesforce/sfca/cpdwrapper/CpdWrapper.java

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import java.io.FileWriter;
55
import java.io.IOException;
66
import java.util.Arrays;
7-
import java.util.List;
87
import java.util.Map;
98

109
import com.google.gson.Gson;
@@ -29,24 +28,27 @@
2928
* - {resultsOutputFile} is a JSON file to write CPD results to.
3029
* Example:
3130
* {
32-
* "apex": [
33-
* {
34-
* "numTokensInBlock": 18,
35-
* "numNonemptyLinesInBlock": 5,
36-
* "numBlocks": 2,
37-
* "blockLocations": [
38-
* {
39-
* "file": "/full/path/to/file1.cls",
40-
* "startLine": 1, "startCol": 1, "endLine": 5, "endCol": 2
41-
* },
42-
* {
43-
* "file": "/full/path/to/file2.cls",
44-
* "startLine": 18, "startCol": 6, "endLine": 22, "endCol": 8
45-
* }
46-
* ]
47-
* },
48-
* ...
49-
* ],
31+
* "apex": {
32+
* matches: [
33+
* {
34+
* "numTokensInBlock": 18,
35+
* "numNonemptyLinesInBlock": 5,
36+
* "numBlocks": 2,
37+
* "blockLocations": [
38+
* {
39+
* "file": "/full/path/to/file1.cls",
40+
* "startLine": 1, "startCol": 1, "endLine": 5, "endCol": 2
41+
* },
42+
* {
43+
* "file": "/full/path/to/file2.cls",
44+
* "startLine": 18, "startCol": 6, "endLine": 22, "endCol": 8
45+
* }
46+
* ]
47+
* },
48+
* ...
49+
* ],
50+
* processingErrors: []
51+
* },
5052
* "xml": ...
5153
* }
5254
*/
@@ -84,7 +86,7 @@ private static void invokeRunCommand(String[] args) {
8486
}
8587

8688
CpdRunner cpdRunner = new CpdRunner();
87-
Map<String, List<CpdMatch>> results;
89+
Map<String, CpdLanguageRunResults> results;
8890
try {
8991
results = cpdRunner.run(inputData);
9092
} catch (Exception e) {

packages/code-analyzer-pmd-engine/pmd-wrapper/src/main/java/com/salesforce/sfca/pmdwrapper/PmdRuleDescriber.java renamed to packages/code-analyzer-pmd-engine/pmd-cpd-wrappers/src/main/java/com/salesforce/sfca/pmdwrapper/PmdRuleDescriber.java

File renamed without changes.

packages/code-analyzer-pmd-engine/pmd-wrapper/src/main/java/com/salesforce/sfca/pmdwrapper/PmdRuleInfo.java renamed to packages/code-analyzer-pmd-engine/pmd-cpd-wrappers/src/main/java/com/salesforce/sfca/pmdwrapper/PmdRuleInfo.java

File renamed without changes.

packages/code-analyzer-pmd-engine/pmd-wrapper/src/main/java/com/salesforce/sfca/pmdwrapper/PmdRuleRunner.java renamed to packages/code-analyzer-pmd-engine/pmd-cpd-wrappers/src/main/java/com/salesforce/sfca/pmdwrapper/PmdRuleRunner.java

File renamed without changes.

packages/code-analyzer-pmd-engine/pmd-wrapper/src/main/java/com/salesforce/sfca/pmdwrapper/PmdWrapper.java renamed to packages/code-analyzer-pmd-engine/pmd-cpd-wrappers/src/main/java/com/salesforce/sfca/pmdwrapper/PmdWrapper.java

File renamed without changes.

0 commit comments

Comments
 (0)