dfac6cd179375d443a1003bb6c8b71b91fb8b37f
[integration.git] / version-manifest / src / main / java / org / onap / integration / versionmanifest / VersionCheckMojo.java
1 /*
2  * Copyright 2017 Huawei Technologies, Ltd. and others.
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 an "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.onap.integration.versionmanifest;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.io.InputStreamReader;
22 import java.nio.charset.StandardCharsets;
23 import java.util.Arrays;
24 import java.util.HashMap;
25 import java.util.List;
26 import java.util.Map;
27 import java.util.Map.Entry;
28 import java.util.Properties;
29 import java.util.Set;
30 import java.util.TreeSet;
31
32 import org.apache.commons.csv.CSVFormat;
33 import org.apache.commons.csv.CSVRecord;
34 import org.apache.maven.artifact.Artifact;
35 import org.apache.maven.plugin.AbstractMojo;
36 import org.apache.maven.plugin.MojoExecutionException;
37 import org.apache.maven.plugin.logging.Log;
38 import org.apache.maven.plugins.annotations.LifecyclePhase;
39 import org.apache.maven.plugins.annotations.Mojo;
40 import org.apache.maven.plugins.annotations.Parameter;
41 import org.apache.maven.project.MavenProject;
42
43 @Mojo(name = "version-check", defaultPhase = LifecyclePhase.PROCESS_SOURCES)
44 public class VersionCheckMojo extends AbstractMojo {
45
46     /**
47      * The Maven Project.
48      *
49      * @since 1.0-alpha-1
50      */
51     @Parameter(defaultValue = "${project}", required = true, readonly = true)
52     protected MavenProject project;
53
54     /**
55      * Location of the file.
56      */
57     @Parameter(property = "manifest", required = true, defaultValue = "/java-manifest.csv")
58     private String manifest;
59
60     public void execute() throws MojoExecutionException {
61         final Log log = getLog();
62
63         final Properties gitProps = new Properties();
64         try (InputStream in = getClass().getResourceAsStream("/git.properties")) {
65             gitProps.load(in);
66         } catch (IOException e) {
67             log.error(e);
68             throw new MojoExecutionException(e.getMessage());
69         }
70
71         log.info("Manifest version: " + gitProps.getProperty("git.build.time") + " "
72                 + gitProps.getProperty("git.commit.id") + " " + gitProps.getProperty("git.remote.origin.url"));
73
74         log.info("");
75
76         final List<String> groupIdPrefixes = Arrays.asList("org.onap", "org.openecomp", "org.openo");
77
78         final Map<String, String> expectedVersions = new HashMap<>();
79
80         try (InputStreamReader in = new InputStreamReader(getClass().getResourceAsStream(manifest),
81                 StandardCharsets.ISO_8859_1)) {
82             Iterable<CSVRecord> records = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(in);
83             for (CSVRecord record : records) {
84                 String groupId = record.get("groupId");
85                 String artifactId = record.get("artifactId");
86                 String version = record.get("version");
87                 log.debug("Expected version: " + groupId + ":" + artifactId + ":" + version);
88                 expectedVersions.put(groupId + ":" + artifactId, version);
89             }
90         } catch (IOException e) {
91             log.error(e);
92             throw new MojoExecutionException(e.getMessage());
93         }
94
95         final Map<String, String> actualVersions = new HashMap<>();
96         final MavenProject parent = project.getParent();
97         if (parent != null) {
98             log.debug("Parent: " + parent);
99             // don't warn within the same groupId
100             if (!project.getGroupId().equals(parent.getGroupId())) {
101                 actualVersions.put(parent.getGroupId() + ":" + parent.getArtifactId(), parent.getVersion());
102             }
103         } else {
104             log.debug("No parent");
105         }
106
107         for (Artifact dep : project.getDependencyArtifacts()) {
108             log.debug("DependencyArtifact: " + dep.toString());
109             // don't warn within the same groupId
110             if (!project.getGroupId().equals(dep.getGroupId())) {
111                 actualVersions.put(dep.getGroupId() + ":" + dep.getArtifactId(), dep.getVersion());
112             }
113         }
114
115         final Set<String> mismatches = new TreeSet<>();
116         final Set<String> missingArtifacts = new TreeSet<>();
117
118         for (Entry<String, String> actualVersionEntry : actualVersions.entrySet()) {
119             String artifact = actualVersionEntry.getKey();
120             String actualVersion = actualVersionEntry.getValue();
121             String expectedVersion = expectedVersions.get(artifact);
122             if (expectedVersion == null) {
123                 if (groupIdPrefixes.stream().anyMatch(prefix -> artifact.startsWith(prefix))) {
124                     missingArtifacts.add(artifact);
125                 }
126             } else if (!expectedVersion.equals(actualVersion)) {
127                 mismatches.add(artifact);
128             }
129         }
130
131         // used for formatting
132         int[] columnWidths = new int[10];
133         columnWidths[0] = actualVersions.keySet().stream().mapToInt(s -> ("" + s).length()).max().orElse(1);
134         columnWidths[1] = actualVersions.values().stream().mapToInt(s -> ("" + s).length()).max().orElse(1);
135         columnWidths[2] = expectedVersions.values().stream().mapToInt(s -> ("" + s).length()).max().orElse(1);
136         String format = "  %-" + columnWidths[0] + "s" + "  %" + columnWidths[1] + "s -> %" + columnWidths[2] + "s";
137
138         if (mismatches.isEmpty()) {
139             log.debug("No version mismatches found");
140         } else {
141             log.warn("The following dependencies should be updated to match the version manifest:");
142             for (String artifact : mismatches) {
143                 String expectedVersion = expectedVersions.get(artifact);
144                 String actualVersion = actualVersions.get(artifact);
145
146                 if (actualVersion != null && !actualVersion.equals(expectedVersion)) {
147                     log.warn(String.format(format, artifact, actualVersion, expectedVersion));
148                 }
149             }
150             log.warn("");
151         }
152
153         if (missingArtifacts.isEmpty()) {
154             log.debug("No artifacts found missing in the version manifest");
155         } else {
156             log.warn("The following dependencies are missing in the version manifest:");
157             for (String artifact : missingArtifacts) {
158                 String actualVersion = actualVersions.get(artifact);
159                 log.warn(String.format(format, artifact, actualVersion, "?"));
160             }
161             log.warn("");
162         }
163
164     }
165 }