re base code
[sdc.git] / openecomp-be / tools / pmd-helper-plugin / src / main / java / org / openecomp / sdc / onboarding / pmd / VerifyHelperMojo.java
1 /*
2  * Copyright © 2018 European Support Limited
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on a "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package org.openecomp.sdc.onboarding.pmd;
18
19 import org.apache.maven.execution.MavenSession;
20 import org.apache.maven.plugin.AbstractMojo;
21 import org.apache.maven.plugin.MojoExecutionException;
22 import org.apache.maven.plugin.MojoFailureException;
23 import org.apache.maven.plugins.annotations.LifecyclePhase;
24 import org.apache.maven.plugins.annotations.Mojo;
25 import org.apache.maven.plugins.annotations.Parameter;
26 import org.apache.maven.plugins.annotations.ResolutionScope;
27 import org.apache.maven.project.MavenProject;
28
29 import java.io.File;
30 import java.io.IOException;
31 import java.io.UncheckedIOException;
32 import java.nio.file.Files;
33 import java.util.HashMap;
34 import java.util.List;
35 import java.util.Map;
36
37 import static org.openecomp.sdc.onboarding.pmd.PMDHelperUtils.*;
38
39 @Mojo(name = "post-verify-helper", threadSafe = true, defaultPhase = LifecyclePhase.VERIFY,
40         requiresDependencyResolution = ResolutionScope.NONE)
41 public class VerifyHelperMojo extends AbstractMojo {
42
43     private static final String SKIP_PMD = "skipPMD";
44
45     @Parameter(defaultValue = "${project}", readonly = true)
46     private MavenProject project;
47     @Parameter(defaultValue = "${project.artifact.groupId}:${project.artifact.artifactId}")
48     private String moduleCoordinates;
49     @Parameter(defaultValue = "${session}")
50     private MavenSession session;
51     @Parameter
52     private File pmdTargetLocation;
53     @Parameter
54     private File pmdReportFile;
55     @Parameter
56     private File pmdStateFile;
57     @Parameter
58     private String pmdCurrentStateFilePath;
59     @Parameter
60     private String excludePackaging;
61     @Parameter
62     private Boolean validatePMDReport = Boolean.FALSE;
63     @Parameter
64     private String persistingModuleCoordinates;
65     @Parameter
66     private File pmdFailureReportLocation;
67     @Parameter
68     private File compiledFilesList;
69     @Parameter
70     private File compiledTestFilesList;
71
72     private static File pmdCurrentStateFile;
73
74     public void execute() throws MojoExecutionException, MojoFailureException {
75         if (project.getPackaging().equals(excludePackaging)) {
76             return;
77         }
78         init();
79         warnDataIssuesIfAny();
80
81         if (Boolean.FALSE.equals(Boolean.valueOf(project.getProperties().getProperty(SKIP_PMD))) && !isReportEmpty(
82                 pmdReportFile)) {
83             Map<String, List<Violation>> data = readCurrentPMDState(pmdCurrentStateFile);
84             Map<String, List<Violation>> cv = readCurrentModulePMDReport();
85             data.putAll(cv);
86             boolean error = false;
87             if (!PMDState.getHistoricState().isEmpty() && !PMDHelperUtils
88                                                                    .evaluateCodeQuality(PMDState.getHistoricState(), cv,
89                                                                            pmdFailureReportLocation, getLog())) {
90                 error = true;
91                 if (validatePMDReport) {
92                     throw new MojoFailureException(
93                             "PMD Failures encountered. Build halted. For details refer " + pmdFailureReportLocation
94                                                                                                    .getAbsolutePath());
95                 } else {
96                     getLog().error(
97                             "\u001B[31m\u001B[1m Code Quality concerns raised by Quality Management System. For details refer "
98                                     + pmdFailureReportLocation.getAbsolutePath()
99                                     + " and address them before committing this code in Version Control System. \u001B[0m");
100                 }
101             }
102             String moduleChecksum = project.getProperties().getProperty("mainChecksum") + ":" + project.getProperties()
103                                                                                                        .getProperty(
104                                                                                                                "testChecksum");
105             data = reinitializeIfNeeded(!error, data);
106
107             Map<String, Object> checksumStore = HashMap.class.cast(data);
108             if (!moduleChecksum.equals(checksumStore.get(moduleCoordinates))) {
109                 checksumStore.put(moduleCoordinates, moduleChecksum);
110                 writeCurrentPMDState(pmdCurrentStateFile, data);
111             }
112         }
113         if (Boolean.FALSE.equals(Boolean.valueOf(project.getProperties().getProperty(SKIP_PMD)))) {
114             if (isReportEmpty(pmdReportFile)) {
115                 HashMap data = HashMap.class.cast(readCurrentPMDState(pmdCurrentStateFile));
116                 data.put(moduleCoordinates,
117                         project.getProperties().getProperty("mainChecksum") + ":" + project.getProperties().getProperty(
118                                 "testChecksum"));
119                 writeCurrentPMDState(pmdCurrentStateFile, data);
120             }
121             pmdReportFile.delete();
122         }
123         removeProcessFiles();
124
125     }
126
127     private void removeProcessFiles() {
128         if (moduleCoordinates.equals(persistingModuleCoordinates) && pmdStateFile.exists()) {
129             for (File file : pmdStateFile.getParentFile().listFiles()) {
130                 if (file.isFile()) {
131                     file.delete();
132                 }
133             }
134         }
135         if (pmdTargetLocation.exists()) {
136             pmdTargetLocation.delete();
137         }
138     }
139
140     private void init() {
141         if (pmdCurrentStateFile == null) {
142             setPmdCurrentStateFile(
143                     getStateFile(pmdCurrentStateFilePath.substring(0, pmdCurrentStateFilePath.indexOf('/')), project,
144                             pmdCurrentStateFilePath));
145
146             pmdReportFile.getParentFile().mkdirs();
147         }
148     }
149
150     private static void setPmdCurrentStateFile(File file) {
151         pmdCurrentStateFile = file;
152         pmdCurrentStateFile.getParentFile().mkdirs();
153     }
154
155     private Map<String, List<Violation>> readCurrentModulePMDReport() {
156         try {
157             PMDState.reset(compiledFilesList, compiledTestFilesList, moduleCoordinates);
158             if (pmdReportFile.exists()) {
159                 List<String> lines = Files.readAllLines(pmdReportFile.toPath());
160                 lines.remove(0);
161                 for (String line : lines) {
162                     PMDState.addViolation(line, moduleCoordinates);
163                 }
164             }
165         } catch (IOException ioe) {
166             throw new UncheckedIOException(ioe);
167         }
168         return PMDState.getState();
169     }
170
171     private void warnDataIssuesIfAny() {
172         if (PMDState.getHistoricState() != null && PMDState.getHistoricState().isEmpty()) {
173             getLog().error("PMD Check is skipped. problem while loading data.");
174         }
175     }
176
177     private Map<String, List<Violation>> reinitializeIfNeeded(boolean required, Map<String, List<Violation>> orig) {
178         if (required) {
179             return readCurrentPMDState(pmdCurrentStateFile);
180         } else {
181             return orig;
182         }
183     }
184
185 }