View Javadoc
1   package org.apache.maven.plugins.enforcer;
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.HashSet;
23  import java.util.List;
24  import java.util.Set;
25  
26  import org.apache.maven.artifact.Artifact;
27  import org.apache.maven.artifact.resolver.filter.AndArtifactFilter;
28  import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
29  import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
30  import org.apache.maven.plugin.logging.Log;
31  import org.apache.maven.project.MavenProject;
32  import org.apache.maven.shared.artifact.filter.StrictPatternExcludesArtifactFilter;
33  import org.apache.maven.shared.artifact.filter.StrictPatternIncludesArtifactFilter;
34  import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
35  
36  /**
37   * This rule checks that no snapshots are included.
38   *
39   * @author <a href="mailto:brianf@apache.org">Brian Fox</a>
40   * @version $Id: RequireReleaseDeps.java 1802595 2017-07-21 13:39:48Z rfscholte $
41   */
42  public class RequireReleaseDeps
43      extends AbstractBanDependencies
44  {
45  
46      /**
47       * Allows this rule to execute only when this project is a release.
48       *
49       * @parameter
50       * 
51       * @see {@link #setOnlyWhenRelease(boolean)}
52       * @see {@link #isOnlyWhenRelease()}
53  
54       */
55      private boolean onlyWhenRelease = false;
56  
57      /**
58       * Allows this rule to fail when the parent is defined as a snapshot.
59       *
60       * @parameter
61       * 
62       * @see {@link #setFailWhenParentIsSnapshot(boolean)}
63       * @see {@link #isFailWhenParentIsSnapshot()}
64       */
65      private boolean failWhenParentIsSnapshot = true;
66  
67      /**
68       * Dependencies to ignore when checking for release versions.  For example, inter-module dependencies 
69       * can be excluded from the check and therefore allowed to contain snapshot versions.
70       * 
71       * @see {@link #setExcludes(List)}
72       * @see {@link #getExcludes()}
73       */
74      private List<String> excludes = null;
75  
76      /**
77       * Dependencies to include when checking for release versions.  If any of the included dependencies
78       * have snapshot versions, the rule will fail.
79       * 
80       * @see {@link #setIncludes(List)}
81       * @see {@link #getIncludes()}
82       */
83      private List<String> includes = null;
84  
85      // Override parent to allow optional ignore of this rule.
86      @Override
87      public void execute( EnforcerRuleHelper helper )
88          throws EnforcerRuleException
89      {
90          boolean callSuper;
91          MavenProject project = null;
92          if ( onlyWhenRelease )
93          {
94              // get the project
95              project = getProject( helper );
96  
97              // only call super if this project is a release
98              callSuper = !project.getArtifact().isSnapshot();
99          }
100         else
101         {
102             callSuper = true;
103         }
104         if ( callSuper )
105         {
106             super.execute( helper );
107             if ( failWhenParentIsSnapshot )
108             {
109                 if ( project == null )
110                 {
111                     project = getProject( helper );
112                 }
113                 Artifact parentArtifact = project.getParentArtifact();
114                 if ( parentArtifact != null && parentArtifact.isSnapshot() )
115                 {
116                     throw new EnforcerRuleException( "Parent Cannot be a snapshot: " + parentArtifact.getId() );
117                 }
118             }
119         }
120     }
121 
122     /**
123      * @param helper
124      * @return The evaluated {@link MavenProject}.
125      * @throws EnforcerRuleException
126      */
127     private MavenProject getProject( EnforcerRuleHelper helper )
128         throws EnforcerRuleException
129     {
130         try
131         {
132             return (MavenProject) helper.evaluate( "${project}" );
133         }
134         catch ( ExpressionEvaluationException eee )
135         {
136             throw new EnforcerRuleException( "Unable to retrieve the MavenProject: ", eee );
137         }
138     }
139 
140     @Override
141     protected Set<Artifact> checkDependencies( Set<Artifact> dependencies, Log log )
142         throws EnforcerRuleException
143     {
144         Set<Artifact> foundSnapshots = new HashSet<Artifact>();
145 
146         Set<Artifact> filteredDependencies = filterArtifacts( dependencies );
147         
148         for ( Artifact artifact : filteredDependencies )
149         {
150             if ( artifact.isSnapshot() )
151             {
152                 foundSnapshots.add( artifact );
153             }
154         }
155 
156         return foundSnapshots;
157     }
158     
159     /*
160      * Filter the dependency artifacts according to the includes and excludes
161      * If includes and excludes are both null, the original set is returned.
162      * 
163      * @param dependencies the list of dependencies to filter
164      * @return the resulting set of dependencies
165      */
166     public Set<Artifact> filterArtifacts( Set<Artifact> dependencies )
167     {
168         if ( includes == null && excludes == null )
169         {
170             return dependencies;
171         }
172         
173         AndArtifactFilter filter = new AndArtifactFilter( );
174         if ( includes != null )
175         {
176             filter.add( new StrictPatternIncludesArtifactFilter( includes ) );
177         }
178         if ( excludes != null )
179         {
180             filter.add( new StrictPatternExcludesArtifactFilter( excludes ) );
181         }
182         
183         Set<Artifact> result = new HashSet<Artifact>();
184         for ( Artifact artifact : dependencies )
185         {
186             if ( filter.include( artifact ) )
187             {
188                 result.add( artifact );
189             }
190         }
191         return result;
192     }
193 
194     public final boolean isOnlyWhenRelease()
195     {
196         return onlyWhenRelease;
197     }
198 
199     public final void setOnlyWhenRelease( boolean onlyWhenRelease )
200     {
201         this.onlyWhenRelease = onlyWhenRelease;
202     }
203 
204     public final boolean isFailWhenParentIsSnapshot()
205     {
206         return failWhenParentIsSnapshot;
207     }
208 
209     public final void setFailWhenParentIsSnapshot( boolean failWhenParentIsSnapshot )
210     {
211         this.failWhenParentIsSnapshot = failWhenParentIsSnapshot;
212     }
213     
214     public final void setExcludes( List<String> excludes )
215     {
216         this.excludes = excludes;
217     }
218     
219     public final List<String> getExcludes()
220     {
221         return excludes;
222     }
223     
224     public void setIncludes( List<String> includes )
225     {
226         this.includes = includes;
227     }
228     
229     public List<String> getIncludes()
230     {
231         return includes;
232     }
233 }