1 package org.apache.maven.plugin.invoker;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.List;
25
26 import org.apache.maven.plugin.MojoFailureException;
27 import org.apache.maven.plugin.invoker.model.BuildJob;
28 import org.apache.maven.plugin.logging.Log;
29
30 /**
31 * Tracks a set of build jobs and their results.
32 *
33 * @author Benjamin Bentmann
34 */
35 class InvokerSession
36 {
37
38 private List<BuildJob> buildJobs;
39
40 private List<BuildJob> failedJobs;
41
42 private List<BuildJob> errorJobs;
43
44 private List<BuildJob> successfulJobs;
45
46 private List<BuildJob> skippedJobs;
47
48 /**
49 * Creates a new empty session.
50 */
51 public InvokerSession()
52 {
53 buildJobs = new ArrayList<BuildJob>();
54 }
55
56 /**
57 * Creates a session that initially contains the specified build jobs.
58 *
59 * @param buildJobs The build jobs to set, must not be <code>null</code>.
60 */
61 public InvokerSession( BuildJob[] buildJobs )
62 {
63 this.buildJobs = new ArrayList<BuildJob>( Arrays.asList( buildJobs ) );
64 }
65
66 /**
67 * Adds the specified build job to this session.
68 *
69 * @param buildJob The build job to add, must not be <code>null</code>.
70 */
71 public void addJob( BuildJob buildJob )
72 {
73 buildJobs.add( buildJob );
74
75 resetStats();
76 }
77
78 /**
79 * Sets the build jobs of this session.
80 *
81 * @param buildJobs The build jobs to set, must not be <code>null</code>.
82 */
83 public void setJobs( List<? extends BuildJob> buildJobs )
84 {
85 this.buildJobs = new ArrayList<BuildJob>( buildJobs );
86
87 resetStats();
88 }
89
90 /**
91 * Gets the build jobs in this session.
92 *
93 * @return The build jobs in this session, can be empty but never <code>null</code>.
94 */
95 public List<BuildJob> getJobs()
96 {
97 return buildJobs;
98 }
99
100 /**
101 * Gets the successful build jobs in this session.
102 *
103 * @return The successful build jobs in this session, can be empty but never <code>null</code>.
104 */
105 public List<BuildJob> getSuccessfulJobs()
106 {
107 updateStats();
108
109 return successfulJobs;
110 }
111
112 /**
113 * Gets the failed build jobs in this session.
114 *
115 * @return The failed build jobs in this session, can be empty but never <code>null</code>.
116 */
117 public List<BuildJob> getFailedJobs()
118 {
119 updateStats();
120
121 return failedJobs;
122 }
123
124 /**
125 * Gets the build jobs which had errors for this session.
126 *
127 * @return The build jobs in error for this session, can be empty but never <code>null</code>.
128 */
129 public List<BuildJob> getErrorJobs()
130 {
131 updateStats();
132
133 return errorJobs;
134 }
135
136 /**
137 * Gets the skipped build jobs in this session.
138 *
139 * @return The skipped build jobs in this session, can be empty but never <code>null</code>.
140 */
141 public List<BuildJob> getSkippedJobs()
142 {
143 updateStats();
144
145 return skippedJobs;
146 }
147
148 private void resetStats()
149 {
150 successfulJobs = null;
151 failedJobs = null;
152 skippedJobs = null;
153 errorJobs = null;
154 }
155
156 private void updateStats()
157 {
158 if ( successfulJobs != null && skippedJobs != null && failedJobs != null && errorJobs != null )
159 {
160 return;
161 }
162
163 successfulJobs = new ArrayList<BuildJob>();
164 failedJobs = new ArrayList<BuildJob>();
165 skippedJobs = new ArrayList<BuildJob>();
166 errorJobs = new ArrayList<BuildJob>();
167
168 for ( BuildJob buildJob : buildJobs )
169 {
170 if ( BuildJob.Result.SUCCESS.equals( buildJob.getResult() ) )
171 {
172 successfulJobs.add( buildJob );
173 }
174 else if ( BuildJob.Result.SKIPPED.equals( buildJob.getResult() ) )
175 {
176 skippedJobs.add( buildJob );
177 }
178 else if ( BuildJob.Result.ERROR.equals( buildJob.getResult() ) )
179 {
180 errorJobs.add( buildJob );
181 }
182 else if ( buildJob.getResult() != null )
183 {
184 failedJobs.add( buildJob );
185 }
186 }
187 }
188
189 /**
190 * Prints a summary of this session to the specified logger.
191 *
192 * @param logger The mojo logger to output messages to, must not be <code>null</code>.
193 * @param ignoreFailures A flag whether failures should be ignored or whether a build failure should be signaled.
194 */
195 public void logSummary( Log logger, boolean ignoreFailures )
196 {
197 updateStats();
198
199 String separator = "-------------------------------------------------";
200
201 logger.info( separator );
202 logger.info( "Build Summary:" );
203 logger.info( " Passed: " + successfulJobs.size() + ", Failed: " + failedJobs.size() + ", Errors: "
204 + errorJobs.size() + ", Skipped: " + skippedJobs.size() );
205 logger.info( separator );
206
207 if ( !failedJobs.isEmpty() )
208 {
209 String heading = "The following builds failed:";
210 if ( ignoreFailures )
211 {
212 logger.warn( heading );
213 }
214 else
215 {
216 logger.error( heading );
217 }
218
219 for ( BuildJob buildJob : failedJobs )
220 {
221 String item = "* " + buildJob.getProject();
222 if ( ignoreFailures )
223 {
224 logger.warn( item );
225 }
226 else
227 {
228 logger.error( item );
229 }
230 }
231
232 logger.info( separator );
233 }
234 }
235
236 /**
237 * Handles the build failures in this session.
238 *
239 * @param logger The mojo logger to output messages to, must not be <code>null</code>.
240 * @param ignoreFailures A flag whether failures should be ignored or whether a build failure should be signaled.
241 * @throws MojoFailureException If failures are present and not ignored.
242 */
243 public void handleFailures( Log logger, boolean ignoreFailures )
244 throws MojoFailureException
245 {
246 updateStats();
247
248 if ( !failedJobs.isEmpty() )
249 {
250 String message = failedJobs.size() + " build" + ( failedJobs.size() == 1 ? "" : "s" ) + " failed.";
251
252 if ( ignoreFailures )
253 {
254 logger.warn( "Ignoring that " + message );
255 }
256 else
257 {
258 throw new MojoFailureException( message + " See console output above for details." );
259 }
260 }
261
262 if ( !errorJobs.isEmpty() )
263 {
264 String message = errorJobs.size() + " build" + ( errorJobs.size() == 1 ? "" : "s" ) + " in error.";
265
266 if ( ignoreFailures )
267 {
268 logger.warn( "Ignoring that " + message );
269 }
270 else
271 {
272 throw new MojoFailureException( message + " See console output above for details." );
273 }
274 }
275 }
276
277 }