From b145c0825c0bd163a0a2643aeee4c8b283e35ada Mon Sep 17 00:00:00 2001 From: Gautam Shah Date: Sun, 27 May 2018 13:32:07 +0530 Subject: Onboarding build optimization incl Qual Control Sonar fixes, incremental build enhancements and Quality control mechanism integration. Change-Id: I118d7fc0cc50c1eddb94137310c00afaaa3aaffb Issue-ID: SDC-1189 Signed-off-by: GAUTAMS --- openecomp-be/tools/pmd-helper-plugin/pom.xml | 46 ++++ .../onboarding/pmd/InitializationHelperMojo.java | 112 ++++++++++ .../sdc/onboarding/pmd/PMDHelperUtils.java | 242 +++++++++++++++++++++ .../org/openecomp/sdc/onboarding/pmd/PMDState.java | 74 +++++++ .../org/openecomp/sdc/onboarding/pmd/Table.java | 107 +++++++++ .../sdc/onboarding/pmd/VerifyHelperMojo.java | 155 +++++++++++++ .../openecomp/sdc/onboarding/pmd/Violation.java | 60 +++++ .../src/main/resources/pmd-empty.xml | 6 + 8 files changed, 802 insertions(+) create mode 100644 openecomp-be/tools/pmd-helper-plugin/pom.xml create mode 100644 openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/InitializationHelperMojo.java create mode 100644 openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/PMDHelperUtils.java create mode 100644 openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/PMDState.java create mode 100644 openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/Table.java create mode 100644 openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/VerifyHelperMojo.java create mode 100644 openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/Violation.java create mode 100644 openecomp-be/tools/pmd-helper-plugin/src/main/resources/pmd-empty.xml (limited to 'openecomp-be/tools/pmd-helper-plugin') diff --git a/openecomp-be/tools/pmd-helper-plugin/pom.xml b/openecomp-be/tools/pmd-helper-plugin/pom.xml new file mode 100644 index 0000000000..75ab1f89c8 --- /dev/null +++ b/openecomp-be/tools/pmd-helper-plugin/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + org.openecomp.sdc.onboarding + pmd-helper-plugin + maven-plugin + + + sdc-onboarding + org.openecomp.sdc + 1.2.0-SNAPSHOT + ../../../onboarding + + + true + classes/**/*.class + maven-status/** + + + + + org.apache.maven + maven-core + ${maven-core.version} + + + org.apache.maven.plugin-tools + maven-plugin-annotations + ${maven-plugin-annotations.version} + + + + + + + org.apache.maven.plugins + maven-plugin-plugin + ${maven-plugin-plugin.version} + + + + + \ No newline at end of file diff --git a/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/InitializationHelperMojo.java b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/InitializationHelperMojo.java new file mode 100644 index 0000000000..4102a1b382 --- /dev/null +++ b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/InitializationHelperMojo.java @@ -0,0 +1,112 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on a "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openecomp.sdc.onboarding.pmd; + +import static org.openecomp.sdc.onboarding.pmd.PMDHelperUtils.getStateFile; +import static org.openecomp.sdc.onboarding.pmd.PMDHelperUtils.readCurrentPMDState; +import static org.openecomp.sdc.onboarding.pmd.PMDHelperUtils.readInputStream; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.nio.file.StandardCopyOption; +import java.util.List; +import java.util.Map; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; + +@Mojo(name = "init-pmd-helper", threadSafe = true, defaultPhase = LifecyclePhase.PREPARE_PACKAGE, + requiresDependencyResolution = ResolutionScope.NONE) +public class InitializationHelperMojo extends AbstractMojo { + + private static final String SKIP_PMD = "skipPMD"; + + @Parameter(defaultValue = "${project}", readonly = true) + private MavenProject project; + @Parameter(defaultValue = "${project.artifact.groupId}:${project.artifact.artifactId}") + private String moduleCoordinates; + @Parameter + private File pmdTargetLocation; + @Parameter + private File pmdReportFile; + @Parameter + private String persistingModuleCoordinates; + @Parameter + private File pmdStateFile; + @Parameter + private String pmdCurrentStateFilePath; + @Parameter + private String excludePackaging; + + static { + PMDState.setHistoricState(readCurrentPMDState("pmd.dat")); + } + + public void execute() throws MojoExecutionException, MojoFailureException { + if (project.getPackaging().equals(excludePackaging)) { + return; + } + if (moduleCoordinates.equals(persistingModuleCoordinates)) { + pmdStateFile.getParentFile().mkdirs(); + try (OutputStream os = new FileOutputStream(pmdStateFile); + ObjectOutputStream oos = new ObjectOutputStream(os)) { + File f = getStateFile(pmdCurrentStateFilePath.substring(0, pmdCurrentStateFilePath.indexOf('/')), + project, pmdCurrentStateFilePath); + Map> data = readCurrentPMDState(f); + if (PMDState.getHistoricState() != null) { + PMDState.getHistoricState().putAll(data); + oos.writeObject(PMDState.getHistoricState()); + } else { + oos.writeObject(data); + } + if (Paths.get(f.getParentFile().getAbsolutePath(), "compileState.dat").toFile().exists()) { + Files.copy(Paths.get(f.getParentFile().getAbsolutePath(), "compileState.dat"), + Paths.get(pmdStateFile.getParentFile().getAbsolutePath(), "compile.dat"), + StandardCopyOption.REPLACE_EXISTING); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + return; + } + if (project.getProperties().containsKey(SKIP_PMD) && Boolean.TRUE.equals(Boolean.valueOf( + project.getProperties().getProperty(SKIP_PMD)))) { + return; + } + pmdTargetLocation.getParentFile().mkdirs(); + try (InputStream is = this.getClass().getResourceAsStream("/pmd-empty.xml"); + OutputStream os = new FileOutputStream(pmdTargetLocation)) { + String text = readInputStream(is); + os.write(text.getBytes()); + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + } + +} diff --git a/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/PMDHelperUtils.java b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/PMDHelperUtils.java new file mode 100644 index 0000000000..38dde12454 --- /dev/null +++ b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/PMDHelperUtils.java @@ -0,0 +1,242 @@ +package org.openecomp.sdc.onboarding.pmd; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Scanner; +import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.project.MavenProject; + +public class PMDHelperUtils { + + private PMDHelperUtils() { + // default constructor. donot remove. + } + + private static Map pmdLink = new HashMap<>(); + + static { + pmdLink.put("one", "errorprone"); + pmdLink.put("ign", "design"); + pmdLink.put("ing", "multithreading"); + pmdLink.put("nce", "performance"); + pmdLink.put("ity", "security"); + pmdLink.put("yle", "codestyle"); + pmdLink.put("ces", "bestpractices"); + } + + static String readInputStream(InputStream is) { + try (Scanner s = new Scanner(is).useDelimiter("\\A")) { + return s.hasNext() ? s.next() : ""; + } + } + + static File getStateFile(String moduleCoordinate, MavenProject proj, String filePath) { + return new File(getTopParentProject(moduleCoordinate, proj).getBasedir(), + filePath.substring(filePath.indexOf('/') + 1)); + } + + private static MavenProject getTopParentProject(String moduleCoordinate, MavenProject proj) { + if (getModuleCoordinate(proj).equals(moduleCoordinate) || proj.getParent() == null) { + return proj; + } else { + return getTopParentProject(moduleCoordinate, proj.getParent()); + } + } + + private static String getModuleCoordinate(MavenProject project) { + return project.getGroupId() + ":" + project.getArtifactId(); + } + + private static T readState(String fileName, Class clazz) { + try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName); + ObjectInputStream ois = new ObjectInputStream(is)) { + return clazz.cast(ois.readObject()); + } catch (Exception ioe) { + return null; + } + } + + static T readState(File file, Class clazz) { + try (InputStream is = new FileInputStream(file); ObjectInputStream ois = new ObjectInputStream(is)) { + return clazz.cast(ois.readObject()); + } catch (Exception ioe) { + return null; + } + } + + static boolean evaluateCodeQuality(Map> stats, Map> current, + File file, Log logger) { + boolean qualityCheckPassed = true; + Map table = new HashMap<>(); + Set classes = current.keySet(); + int counter = 0; + for (String clazz : classes) { + List orgViolation = stats.get(clazz) == null ? new ArrayList<>() : stats.get(clazz); + List currViolation = current.get(clazz) == null ? new ArrayList<>() : current.get(clazz); + if (diffViolation(orgViolation, currViolation) > 0) { + Map lDetails = diffCategory(orgViolation, currViolation); + for (String cat : lDetails.keySet()) { + String lineNo = getLineNumbers(currViolation, cat); + table.put(++counter + clazz, cat + ":" + lDetails.get(cat) + ":" + lineNo); + } + } + } + if (!table.isEmpty()) { + qualityCheckPassed = false; + try { + Files.write(file.toPath(), + new Table(getTableHeaders(true), getContents(table, true)).drawTable().getBytes(), + StandardOpenOption.CREATE); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + logger.error(new Table(getTableHeaders(false), getContents(table, false)).drawTable()); + } + return qualityCheckPassed; + } + + private static ArrayList getTableHeaders(boolean addLink) { + ArrayList list = new ArrayList<>(); + list.add("Class Name"); + list.add("Rule Category"); + list.add("Rule Name"); + list.add("Fix"); + list.add("Source Line No"); + if (addLink) { + list.add("Help Link"); + } + return list; + } + + private static ArrayList> getContents(Map data, boolean addLink) { + ArrayList> list = new ArrayList<>(); + Pattern p = Pattern.compile("(.*):(.*):(.*):(.*)"); + for (String s : data.keySet()) { + ArrayList l = new ArrayList<>(); + l.add(s.substring(s.indexOf("::") + 2)); + Matcher m = p.matcher(data.get(s)); + if (m.find()) { + l.add(m.group(1)); + l.add(m.group(2)); + l.add(m.group(3) + " at least"); + l.add(m.group(4)); + if (addLink) { + l.add("http://pmd.sourceforge.net/snapshot/pmd_rules_java_" + getLinkCategory(m.group(1)) + ".html#" + + m.group(2).toLowerCase()); + } + } + list.add(l); + } + return list; + } + + private static String getLinkCategory(String cat) { + for (String category : pmdLink.keySet()) { + if (cat.contains(category)) { + return pmdLink.get(category); + } + } + return "ERROR"; + } + + private static int diffViolation(List org, List curr) { + int diff = 0; + if (org == null || org.isEmpty()) { + if (curr != null && !curr.isEmpty()) { + diff = curr.size(); + } + } else { + if (curr != null && !curr.isEmpty()) { + diff = curr.size() - org.size(); + } + } + return diff; + } + + private static Map diffCategory(List org, List curr) { + Map currData = new HashMap<>(); + Map orgData = new HashMap<>(); + countViolations(curr, currData); + countViolations(org, orgData); + Map val = new HashMap<>(); + for (String cat : currData.keySet()) { + if (orgData.get(cat) == null) { + val.put(cat, currData.get(cat).intValue()); + } else if (currData.get(cat).intValue() > orgData.get(cat).intValue()) { + val.put(cat, currData.get(cat).intValue() - orgData.get(cat).intValue()); + } + } + return val; + } + + private static void countViolations(List violations, Map store){ + for (Violation v : violations) { + if (store.get(v.getCategory() + ":" + v.getRule()) == null) { + store.put(v.getCategory() + ":" + v.getRule(), new AtomicInteger(1)); + } else { + store.get(v.getCategory() + ":" + v.getRule()).incrementAndGet(); + } + } + } + + private static void processOriginalViolations(List org){ + + } + private static String getLineNumbers(List vList, String category) { + String val = ""; + boolean firstOver = false; + for (Violation v : vList) { + if (category.equals(v.getCategory() + ":" + v.getRule())) { + if (firstOver) { + val += ","; + } + val += v.getLine(); + firstOver = true; + } + } + return val; + } + + static Map> readCurrentPMDState(String fileName) { + Map> val = readState(fileName, HashMap.class); + return val == null ? new HashMap<>() : val; + } + + static Map> readCurrentPMDState(File file) { + Map> val = readState(file, HashMap.class); + return val == null ? new HashMap<>() : val; + } + + static void writeCurrentPMDState(File file, Map> data) { + try (OutputStream os = new FileOutputStream(file); ObjectOutputStream oos = new ObjectOutputStream(os)) { + oos.writeObject(data); + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + } + + static boolean isReportEmpty(File reportFile){ + try { + return !reportFile.exists() || Files.readAllLines(reportFile.toPath()).size()<=1; + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } +} diff --git a/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/PMDState.java b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/PMDState.java new file mode 100644 index 0000000000..2602fff2c6 --- /dev/null +++ b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/PMDState.java @@ -0,0 +1,74 @@ +package org.openecomp.sdc.onboarding.pmd; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class PMDState { + + private static Map> data = new HashMap<>(); + private static Map> historicState = null; + private static Pattern p = + Pattern.compile("\"(.*)\",\"(.*)\",\"(.*)\",\"(.*)\",\"(.*)\",\"(.*)\",\"(.*)\",\"(.*)\""); + + public static boolean addViolation(String line, String fileLocation) { + Matcher m = p.matcher(line); + if (m.find()) { + if (m.group(3).indexOf("generated-sources") != -1) { + return true; + } + String mainOrTest = + m.group(3).indexOf(File.separator + "test" + File.separator) == -1 ? "[MAIN] " : "[TEST] "; + List list = data.get(fileLocation + "::" + mainOrTest + m.group(2) + "." + m.group(3).substring( + m.group(3).lastIndexOf(File.separatorChar) + 1)); + if (list == null) { + list = new LinkedList<>(); + data.put(fileLocation + "::" + mainOrTest + m.group(2) + "." + m.group(3).substring( + m.group(3).lastIndexOf(File.separatorChar) + 1), list); + } + + list.add(new Violation(m.group(7), m.group(8), m.group(6), Integer.parseInt(m.group(4)), + Integer.parseInt(m.group(5)))); + return true; + } + return false; + } + + public static void reset(File mainFile, File testFile, String moduleCoordinates) throws IOException { + data.clear(); + init(mainFile, moduleCoordinates, "[MAIN] "); + init(testFile, moduleCoordinates, "[TEST] "); + } + + private static void init(File file, String moduleCoordinates, String maiOrTest) throws IOException { + if (file.exists()) { + List coll = Files.readAllLines(file.toPath()); + for (String line : coll) { + if (line.indexOf("$") == -1) { + data.put(moduleCoordinates + "::" + maiOrTest + line.substring(0, line.indexOf('.')) + .replace(File.separator, ".") + ".java", + new LinkedList<>()); + } + } + } + } + + public static Map> getState() { + return data; + } + + public static void setHistoricState(Map> data) { + historicState = data; + } + + public static Map> getHistoricState() { + return historicState; + } + +} diff --git a/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/Table.java b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/Table.java new file mode 100644 index 0000000000..68eafd0117 --- /dev/null +++ b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/Table.java @@ -0,0 +1,107 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on a "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openecomp.sdc.onboarding.pmd; + +import java.util.ArrayList; +import java.util.List; + +public class Table { + + private final int TABLEPADDING = 1; + private final char SEPERATOR_CHAR = '-'; + + private ArrayList headers; + private ArrayList> table; + private ArrayList maxLength; + + public Table(ArrayList headersIn, ArrayList> content) { + this.headers = headersIn; + this.maxLength = new ArrayList(); + for (int i = 0; i < headers.size(); i++) { + maxLength.add(headers.get(i).length()); + } + this.table = content; + calcMaxLengthAll(); + } + + public String drawTable() { + StringBuilder sb = new StringBuilder(); + StringBuilder sbRowSep = new StringBuilder(); + StringBuffer padder = new StringBuffer(); + String rowSeperator = ""; + + for (int i = 0; i < TABLEPADDING; i++) { + padder.append(" "); + } + + for (int i = 0; i < maxLength.size(); i++) { + sbRowSep.append("|"); + for (int j = 0; j < maxLength.get(i) + (TABLEPADDING * 2); j++) { + sbRowSep.append(SEPERATOR_CHAR); + } + } + sbRowSep.append("|"); + rowSeperator = sbRowSep.toString(); + + sb.append(rowSeperator); + sb.append("\n"); + sb.append("|"); + for (int i = 0; i < headers.size(); i++) { + sb.append(padder); + sb.append(headers.get(i)); + for (int k = 0; k < (maxLength.get(i) - headers.get(i).length()); k++) { + sb.append(" "); + } + sb.append(padder); + sb.append("|"); + } + sb.append("\n"); + sb.append(rowSeperator); + sb.append("\n"); + + for (int i = 0; i < table.size(); i++) { + ArrayList tempRow = table.get(i); + sb.append("|"); + for (int j = 0; j < tempRow.size(); j++) { + sb.append(padder); + sb.append(tempRow.get(j)); + for (int k = 0; k < (maxLength.get(j) - tempRow.get(j).length()); k++) { + sb.append(" "); + } + sb.append(padder); + sb.append("|"); + } + sb.append("\n"); + sb.append(rowSeperator); + sb.append("\n"); + } + return sb.toString(); + } + + private void calcMaxLengthAll() { + for (int i = 0; i < table.size(); i++) { + List temp = table.get(i); + for (int j = 0; j < temp.size(); j++) { + if (temp.get(j).length() > maxLength.get(j)) { + maxLength.set(j, temp.get(j).length()); + } + } + } + } + +} + diff --git a/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/VerifyHelperMojo.java b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/VerifyHelperMojo.java new file mode 100644 index 0000000000..87c9ca5f1f --- /dev/null +++ b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/VerifyHelperMojo.java @@ -0,0 +1,155 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on a "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openecomp.sdc.onboarding.pmd; + +import static org.openecomp.sdc.onboarding.pmd.PMDHelperUtils.getStateFile; +import static org.openecomp.sdc.onboarding.pmd.PMDHelperUtils.readCurrentPMDState; +import static org.openecomp.sdc.onboarding.pmd.PMDHelperUtils.writeCurrentPMDState; +import static org.openecomp.sdc.onboarding.pmd.PMDHelperUtils.isReportEmpty; + +import java.io.File; +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import org.apache.maven.execution.MavenSession; +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; +import org.apache.maven.plugins.annotations.ResolutionScope; +import org.apache.maven.project.MavenProject; + +@Mojo(name = "post-verify-helper", threadSafe = true, defaultPhase = LifecyclePhase.VERIFY, + requiresDependencyResolution = ResolutionScope.NONE) +public class VerifyHelperMojo extends AbstractMojo { + + private static final String SKIP_PMD = "skipPMD"; + + @Parameter(defaultValue = "${project}", readonly = true) + private MavenProject project; + @Parameter(defaultValue = "${project.artifact.groupId}:${project.artifact.artifactId}") + private String moduleCoordinates; + @Parameter(defaultValue = "${session}") + private MavenSession session; + @Parameter + private File pmdTargetLocation; + @Parameter + private File pmdReportFile; + @Parameter + private File pmdStateFile; + @Parameter + private String pmdCurrentStateFilePath; + @Parameter + private String excludePackaging; + @Parameter + private Boolean validatePMDReport = Boolean.FALSE; + @Parameter + private String persistingModuleCoordinates; + @Parameter + private File pmdFailureReportLocation; + @Parameter + private File compiledFilesList; + @Parameter + private File compiledTestFilesList; + + private static File pmdCurrentStateFile; + + public void execute() throws MojoExecutionException, MojoFailureException { + if (project.getPackaging().equals(excludePackaging)) { + return; + } + if (moduleCoordinates.equals(persistingModuleCoordinates)) { + if (pmdStateFile.exists()) { + pmdStateFile.delete(); + } + } + if (pmdCurrentStateFile == null) { + pmdCurrentStateFile = + getStateFile(pmdCurrentStateFilePath.substring(0, pmdCurrentStateFilePath.indexOf('/')), project, + pmdCurrentStateFilePath); + pmdCurrentStateFile.getParentFile().mkdirs(); + pmdReportFile.getParentFile().mkdirs(); + } + if (PMDState.getHistoricState() != null && PMDState.getHistoricState().isEmpty()) { + getLog().error("PMD Check is skipped. problem while loading data."); + } + if (Boolean.FALSE.equals(Boolean.valueOf(project.getProperties().getProperty(SKIP_PMD))) && !isReportEmpty(pmdReportFile)) { + Map> data = readCurrentPMDState(pmdCurrentStateFile); + Map> cv = readCurrentModulePMDReport(); + data.putAll(cv); + if (!PMDState.getHistoricState().isEmpty() && !PMDHelperUtils + .evaluateCodeQuality(PMDState.getHistoricState(), cv, + pmdFailureReportLocation, getLog())) { + if (validatePMDReport) { + throw new MojoFailureException( + "PMD Failures encountered. Build halted. For details refer " + pmdFailureReportLocation + .getAbsolutePath()); + } else { + getLog().error( + "\u001B[31m\u001B[1m Code Quality concerns raised by Quality Management System. For details refer " + + pmdFailureReportLocation.getAbsolutePath() + + " and address them before committing this code in Version Control System. \u001B[0m"); + } + } + Map checksumStore = HashMap.class.cast(data); + checksumStore.put(moduleCoordinates, + project.getProperties().getProperty("mainChecksum") + ":" + project.getProperties() + .getProperty("testChecksum")); + writeCurrentPMDState(pmdCurrentStateFile, data); + } + if (Boolean.FALSE.equals(Boolean.valueOf(project.getProperties().getProperty(SKIP_PMD)))) { + if (isReportEmpty(pmdReportFile)){ + HashMap data = HashMap.class.cast(readCurrentPMDState(pmdCurrentStateFile)); + data.put(moduleCoordinates, + project.getProperties().getProperty("mainChecksum") + ":" + project.getProperties() + .getProperty("testChecksum")); + writeCurrentPMDState(pmdCurrentStateFile, data); + } + pmdReportFile.delete(); + } + if (pmdTargetLocation.exists()) { + pmdTargetLocation.delete(); + } + + } + + private Map> readCurrentModulePMDReport() { + try { + PMDState.reset(compiledFilesList, compiledTestFilesList, moduleCoordinates); + if (pmdReportFile.exists()) { + boolean isFirst = true; + for (String line : Files.lines(pmdReportFile.toPath()).collect(Collectors.toList())) { + if (isFirst) { + isFirst = false; + } else { + PMDState.addViolation(line, moduleCoordinates); + } + } + } + } catch (IOException ioe) { + throw new UncheckedIOException(ioe); + } + return PMDState.getState(); + } + +} diff --git a/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/Violation.java b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/Violation.java new file mode 100644 index 0000000000..4bfbee18b9 --- /dev/null +++ b/openecomp-be/tools/pmd-helper-plugin/src/main/java/org/openecomp/sdc/onboarding/pmd/Violation.java @@ -0,0 +1,60 @@ +/* + * Copyright © 2018 European Support Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on a "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.openecomp.sdc.onboarding.pmd; + +import java.io.File; +import java.io.Serializable; +import java.util.jar.JarFile; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Violation implements Serializable { + + private final String category; + private final String rule; + private final String description; + private final int priority; + private final int line; + + public String getCategory() { + return category; + } + + public String getRule() { + return rule; + } + + public int getPriority() { + return priority; + } + + public int getLine() { + return line; + } + + public Violation(String category, String rule, String description, int priority, int line) { + this.category = category; + this.rule = rule; + this.description = description; + this.priority = priority; + this.line = line; + } + + public String toString() { + return category + ":" + rule + ":" + getPriority() + description + ":" + line; + } +} diff --git a/openecomp-be/tools/pmd-helper-plugin/src/main/resources/pmd-empty.xml b/openecomp-be/tools/pmd-helper-plugin/src/main/resources/pmd-empty.xml new file mode 100644 index 0000000000..c23b533c81 --- /dev/null +++ b/openecomp-be/tools/pmd-helper-plugin/src/main/resources/pmd-empty.xml @@ -0,0 +1,6 @@ + + + -- cgit 1.2.3-korg