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