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