1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.plugins.invoker;
20
21 import java.io.File;
22 import java.io.FileReader;
23 import java.io.IOException;
24 import java.util.ArrayList;
25 import java.util.List;
26
27 import org.apache.maven.plugin.MojoFailureException;
28 import org.apache.maven.plugin.logging.Log;
29 import org.apache.maven.plugins.invoker.model.BuildJob;
30 import org.codehaus.plexus.util.IOUtil;
31
32 import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
33
34
35
36
37
38
39 class InvokerSession {
40 private static final String SEPARATOR =
41 buffer().strong("-------------------------------------------------").build();
42
43 private List<BuildJob> buildJobs;
44
45 private List<BuildJob> failedJobs;
46
47 private List<BuildJob> errorJobs;
48
49 private List<BuildJob> successfulJobs;
50
51 private List<BuildJob> skippedJobs;
52
53
54
55
56 InvokerSession() {
57 buildJobs = new ArrayList<>();
58 }
59
60
61
62
63
64
65 InvokerSession(List<BuildJob> buildJobs) {
66 this.buildJobs = new ArrayList<>(buildJobs);
67 }
68
69
70
71
72
73
74 public void addJob(BuildJob buildJob) {
75 buildJobs.add(buildJob);
76
77 resetStats();
78 }
79
80
81
82
83
84
85 public void setJobs(List<? extends BuildJob> buildJobs) {
86 this.buildJobs = new ArrayList<>(buildJobs);
87
88 resetStats();
89 }
90
91
92
93
94
95
96 public List<BuildJob> getJobs() {
97 return buildJobs;
98 }
99
100
101
102
103
104
105 public List<BuildJob> getSuccessfulJobs() {
106 updateStats();
107
108 return successfulJobs;
109 }
110
111
112
113
114
115
116 public List<BuildJob> getFailedJobs() {
117 updateStats();
118
119 return failedJobs;
120 }
121
122
123
124
125
126
127 public List<BuildJob> getErrorJobs() {
128 updateStats();
129
130 return errorJobs;
131 }
132
133
134
135
136
137
138 public List<BuildJob> getSkippedJobs() {
139 updateStats();
140
141 return skippedJobs;
142 }
143
144 private void resetStats() {
145 successfulJobs = null;
146 failedJobs = null;
147 skippedJobs = null;
148 errorJobs = null;
149 }
150
151 private void updateStats() {
152 if (successfulJobs != null && skippedJobs != null && failedJobs != null && errorJobs != null) {
153 return;
154 }
155
156 successfulJobs = new ArrayList<>();
157 failedJobs = new ArrayList<>();
158 skippedJobs = new ArrayList<>();
159 errorJobs = new ArrayList<>();
160
161 for (BuildJob buildJob : buildJobs) {
162 if (BuildJob.Result.SUCCESS.equals(buildJob.getResult())) {
163 successfulJobs.add(buildJob);
164 } else if (BuildJob.Result.SKIPPED.equals(buildJob.getResult())) {
165 skippedJobs.add(buildJob);
166 } else if (BuildJob.Result.ERROR.equals(buildJob.getResult())) {
167 errorJobs.add(buildJob);
168 } else if (buildJob.getResult() != null) {
169 failedJobs.add(buildJob);
170 }
171 }
172 }
173
174
175
176
177
178
179
180 public void logSummary(Log logger, boolean ignoreFailures) {
181 updateStats();
182
183 logger.info(SEPARATOR);
184 logger.info("Build Summary:");
185 logger.info(" Passed: " + successfulJobs.size()
186 + ", Failed: " + failedJobs.size()
187 + ", Errors: " + errorJobs.size()
188 + ", Skipped: " + skippedJobs.size());
189 logger.info(SEPARATOR);
190
191 logBuildJobList(logger, ignoreFailures, "The following builds failed:", failedJobs);
192 logBuildJobList(logger, ignoreFailures, "The following builds finished with error:", errorJobs);
193 logBuildJobList(logger, true, "The following builds were skipped:", skippedJobs);
194 }
195
196 public void logFailedBuildLog(Log logger, boolean ignoreFailures) throws MojoFailureException {
197 updateStats();
198
199 List<BuildJob> jobToLogs = new ArrayList<>(failedJobs);
200 jobToLogs.addAll(errorJobs);
201
202 for (BuildJob buildJob : jobToLogs) {
203 File buildLogFile = buildJob.getBuildlog() != null ? new File(buildJob.getBuildlog()) : null;
204 if (buildLogFile != null && buildLogFile.exists()) {
205 try {
206
207
208 StringBuilder buildLogMessage = new StringBuilder();
209 buildLogMessage.append(System.lineSeparator());
210 buildLogMessage.append(System.lineSeparator());
211 buildLogMessage.append("*** begin build.log for: " + buildJob.getProject() + " ***");
212 buildLogMessage.append(System.lineSeparator());
213 try (FileReader buildLogReader = new FileReader(buildLogFile)) {
214 buildLogMessage.append(IOUtil.toString(buildLogReader));
215 }
216 buildLogMessage.append("*** end build.log for: " + buildJob.getProject() + " ***");
217 buildLogMessage.append(System.lineSeparator());
218
219 logWithLevel(logger, ignoreFailures, SEPARATOR);
220 logWithLevel(logger, ignoreFailures, buildLogMessage.toString());
221 logWithLevel(logger, ignoreFailures, SEPARATOR);
222 logWithLevel(logger, ignoreFailures, "");
223
224 } catch (IOException e) {
225 throw new MojoFailureException(e.getMessage(), e);
226 }
227 }
228 }
229 }
230
231
232
233
234
235
236
237
238 public void handleFailures(Log logger, boolean ignoreFailures) throws MojoFailureException {
239 updateStats();
240
241 if (!failedJobs.isEmpty()) {
242 String message = failedJobs.size() + " build" + (failedJobs.size() == 1 ? "" : "s") + " failed.";
243
244 if (ignoreFailures) {
245 logger.warn("Ignoring that " + message);
246 } else {
247 throw new MojoFailureException(message + " See console output above for details.");
248 }
249 }
250
251 if (!errorJobs.isEmpty()) {
252 String message = errorJobs.size() + " build" + (errorJobs.size() == 1 ? "" : "s") + " in error.";
253
254 if (ignoreFailures) {
255 logger.warn("Ignoring that " + message);
256 } else {
257 throw new MojoFailureException(message + " See console output above for details.");
258 }
259 }
260 }
261
262
263
264
265
266
267
268
269 private void logBuildJobList(Log logger, boolean warn, String header, List<BuildJob> buildJobs) {
270 if (buildJobs.isEmpty()) {
271 return;
272 }
273
274 logWithLevel(logger, warn, header);
275
276 for (BuildJob buildJob : buildJobs) {
277 logWithLevel(logger, warn, "* " + buildJob.getProject());
278 }
279
280 logger.info(SEPARATOR);
281 }
282
283
284
285
286
287
288
289
290 private void logWithLevel(Log logger, boolean warn, String message) {
291
292 if (warn) {
293 logger.warn(message);
294 } else {
295 logger.error(message);
296 }
297 }
298 }