You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by kh...@apache.org on 2018/12/22 10:44:42 UTC

[maven-enforcer] branch MENFORCER-306 updated (50cc61e -> 9eed415)

This is an automated email from the ASF dual-hosted git repository.

khmarbaise pushed a change to branch MENFORCER-306
in repository https://gitbox.apache.org/repos/asf/maven-enforcer.git.


 discard 50cc61e  WIP - [MENFORCER-306] - [REGRESSION] RequirePluginVersions fails  o Added some debugging output  o Added first implementation which is not final yet.  o Added simple IT's for this case.  o Make it Maven 3.0.5 compatible.  o Changed IT's according to parameter definition with List.
     new 9eed415  WIP - [MENFORCER-306] - [REGRESSION] RequirePluginVersions fails  o Added simple IT's for this case.  o Make it Maven 3.0.5 compatible.  o Changed IT's according to parameter definition with List.

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (50cc61e)
            \
             N -- N -- N   refs/heads/MENFORCER-306 (9eed415)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../plugins/enforcer/RequirePluginVersions.java    | 129 +++++++++++----------
 1 file changed, 68 insertions(+), 61 deletions(-)


[maven-enforcer] 01/01: WIP - [MENFORCER-306] - [REGRESSION] RequirePluginVersions fails o Added simple IT's for this case. o Make it Maven 3.0.5 compatible. o Changed IT's according to parameter definition with List.

Posted by kh...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

khmarbaise pushed a commit to branch MENFORCER-306
in repository https://gitbox.apache.org/repos/asf/maven-enforcer.git

commit 9eed4159e5c709dd92c1d4f32d8311e2c27f3e58
Author: Karl Heinz Marbaise <kh...@apache.org>
AuthorDate: Tue Jun 19 17:58:07 2018 +0200

    WIP - [MENFORCER-306] - [REGRESSION] RequirePluginVersions fails
     o Added simple IT's for this case.
     o Make it Maven 3.0.5 compatible.
     o Changed IT's according to parameter definition with List.
---
 .../plugins/enforcer/RequirePluginVersions.java    | 404 ++++++++++++---------
 .../enforcer/TestRequirePluginVersions.java        |   1 +
 .../src/it/projects/MENFORCER-306/parent/pom.xml   | 103 ++++++
 .../src/it/projects/MENFORCER-306/pom.xml          |  31 ++
 4 files changed, 376 insertions(+), 163 deletions(-)

diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/RequirePluginVersions.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/RequirePluginVersions.java
index b63af6e..59fd6a0 100644
--- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/RequirePluginVersions.java
+++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/RequirePluginVersions.java
@@ -79,7 +79,7 @@ import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
 public class RequirePluginVersions
     extends AbstractNonCacheableEnforcerRule
 {
-    
+
     private EnforcerRuleHelper helper;
 
     /**
@@ -162,25 +162,25 @@ public class RequirePluginVersions
     private Collection<Lifecycle> lifecycles;
 
     /** The factory. */
-    ArtifactFactory factory;
+    private ArtifactFactory factory;
 
     /** The resolver. */
-    ArtifactResolver resolver;
+    private ArtifactResolver resolver;
 
     /** The local. */
-    ArtifactRepository local;
+    private ArtifactRepository local;
 
     /** The remote repositories. */
-    List<ArtifactRepository> remoteRepositories;
+    private List<ArtifactRepository> remoteRepositories;
 
     /** The log. */
-    Log log;
+    private Log log;
 
     /** The session. */
-    MavenSession session;
+    private MavenSession session;
 
     /** The utils. */
-    EnforcerRuleUtils utils;
+    private EnforcerRuleUtils utils;
 
     @Override
     public void execute( EnforcerRuleHelper helper )
@@ -234,6 +234,12 @@ public class RequirePluginVersions
             allPlugins =
                 removeUncheckedPlugins( combineUncheckedPlugins( unCheckedPlugins, unCheckedPluginList ), allPlugins );
 
+            for ( Plugin plugin : allPlugins )
+            {
+                log.debug( "allPlugins(): " + plugin.getGroupId() + ":" + plugin.getArtifactId() + ":"
+                    + plugin.getVersion() );
+            }
+
             // there's nothing to do here
             if ( allPlugins.isEmpty() )
             {
@@ -248,6 +254,11 @@ public class RequirePluginVersions
             // get all the plugins that are mentioned in the pom (and parents)
             List<PluginWrapper> pluginWrappers = getAllPluginEntries( project );
 
+            for ( PluginWrapper pluginWrapper : pluginWrappers )
+            {
+                log.debug( "pluginWrappers: " + pluginWrapper.getGroupId() + ":" + pluginWrapper.getArtifactId() + ":"
+                    + pluginWrapper.getVersion() + " source:" + pluginWrapper.getSource() );
+            }
             // now look for the versions that aren't valid and add to a list.
             List<Plugin> failures = new ArrayList<Plugin>();
             for ( Plugin plugin : allPlugins )
@@ -261,63 +272,7 @@ public class RequirePluginVersions
             // if anything was found, log it then append the optional message.
             if ( !failures.isEmpty() )
             {
-                StringBuilder newMsg = new StringBuilder();
-                newMsg.append( "Some plugins are missing valid versions:" );
-                if ( banLatest || banRelease || banSnapshots || banTimestamps )
-                {
-                    newMsg.append( " (" );
-                    if ( banLatest )
-                    {
-                        newMsg.append( "LATEST " );
-                    }
-                    if ( banRelease )
-                    {
-                        newMsg.append( "RELEASE " );
-                    }
-                    if ( banSnapshots || banTimestamps )
-                    {
-                        newMsg.append( "SNAPSHOT " );
-                    }
-                    newMsg.append( "are not allowed)" );
-                }
-                newMsg.append( "\n" );
-                for ( Plugin plugin : failures )
-                {
-                    newMsg.append( plugin.getGroupId() );
-                    newMsg.append( ":" );
-                    newMsg.append( plugin.getArtifactId() );
-
-                    try
-                    {
-                        newMsg.append( ". \tThe version currently in use is " );
-
-                        Plugin currentPlugin = findCurrentPlugin( plugin, project );
-
-                        if ( currentPlugin != null )
-                        {
-                            newMsg.append( currentPlugin.getVersion() );
-                        }
-                        else
-                        {
-                            newMsg.append( "unknown" );
-                        }
-                    }
-                    catch ( Exception e )
-                    {
-                        // lots can go wrong here. Don't allow any issues trying to
-                        // determine the issue stop me
-                        log.debug( "Exception while determining plugin Version.", e );
-                        newMsg.append( ". Unable to determine the plugin version." );
-                    }
-                    newMsg.append( "\n" );
-                }
-                String message = getMessage();
-                if ( StringUtils.isNotEmpty( message ) )
-                {
-                    newMsg.append( message );
-                }
-
-                throw new EnforcerRuleException( newMsg.toString() );
+                handleMessagesToTheUser( project, failures );
             }
         }
         catch ( ExpressionEvaluationException e )
@@ -362,6 +317,73 @@ public class RequirePluginVersions
         }
     }
 
+    private void handleMessagesToTheUser( MavenProject project, List<Plugin> failures )
+        throws EnforcerRuleException
+    {
+        StringBuilder newMsg = new StringBuilder();
+        newMsg.append( "Some plugins are missing valid versions:" );
+        handleBanMessages( newMsg );
+        newMsg.append( "\n" );
+        for ( Plugin plugin : failures )
+        {
+            newMsg.append( plugin.getGroupId() );
+            newMsg.append( ":" );
+            newMsg.append( plugin.getArtifactId() );
+
+            try
+            {
+                newMsg.append( ". \tThe version currently in use is " );
+
+                Plugin currentPlugin = findCurrentPlugin( plugin, project );
+
+                if ( currentPlugin != null )
+                {
+                    newMsg.append( currentPlugin.getVersion() );
+                }
+                else
+                {
+                    newMsg.append( "unknown" );
+                }
+            }
+            catch ( Exception e )
+            {
+                // lots can go wrong here. Don't allow any issues trying to
+                // determine the issue stop me
+                log.debug( "Exception while determining plugin Version.", e );
+                newMsg.append( ". Unable to determine the plugin version." );
+            }
+            newMsg.append( "\n" );
+        }
+        String message = getMessage();
+        if ( StringUtils.isNotEmpty( message ) )
+        {
+            newMsg.append( message );
+        }
+
+        throw new EnforcerRuleException( newMsg.toString() );
+    }
+
+    private void handleBanMessages( StringBuilder newMsg )
+    {
+        if ( banLatest || banRelease || banSnapshots || banTimestamps )
+        {
+            newMsg.append( " (" );
+            if ( banLatest )
+            {
+                newMsg.append( "LATEST " );
+            }
+            if ( banRelease )
+            {
+                newMsg.append( "RELEASE " );
+            }
+            if ( banSnapshots || banTimestamps )
+            {
+                newMsg.append( "SNAPSHOT " );
+            }
+            newMsg.append( "are not allowed)" );
+        }
+    }
+
     /**
      * Remove the plugins that the user doesn't want to check.
      *
@@ -392,7 +414,8 @@ public class RequirePluginVersions
      * @return List of unchecked plugins.
      */
     // CHECKSTYLE_OFF: LineLength
-    public Collection<String> combineUncheckedPlugins( Collection<String> uncheckedPlugins, String uncheckedPluginsList )
+    public Collection<String> combineUncheckedPlugins( Collection<String> uncheckedPlugins,
+                                                       String uncheckedPluginsList )
     // CHECKSTYLE_ON: LineLength
     {
         // if the comma list is empty, then there's nothing to do here.
@@ -546,9 +569,8 @@ public class RequirePluginVersions
     {
 
         List<ArtifactRepository> pluginRepositories = project.getPluginArtifactRepositories();
-        Artifact artifact =
-            factory.createPluginArtifact( plugin.getGroupId(), plugin.getArtifactId(),
-                                          VersionRange.createFromVersion( "LATEST" ) );
+        Artifact artifact = factory.createPluginArtifact( plugin.getGroupId(), plugin.getArtifactId(),
+                                                          VersionRange.createFromVersion( "LATEST" ) );
 
         try
         {
@@ -557,11 +579,11 @@ public class RequirePluginVersions
         }
         catch ( ArtifactResolutionException e )
         {
-            //What does this mean?
+            // What does this mean?
         }
         catch ( ArtifactNotFoundException e )
         {
-            //What does this mean?
+            // What does this mean?
         }
 
         return plugin;
@@ -595,6 +617,8 @@ public class RequirePluginVersions
                 try
                 {
                     Lifecycle lifecycle = getLifecycleForPhase( lifecyclePhase );
+                    log.debug( "getBoundPlugins(): " + project.getId() + " " + lifecyclePhase + " "
+                        + lifecycle.getId() );
                     allPlugins.addAll( getAllPlugins( project, lifecycle ) );
                 }
                 catch ( BuildFailureException e )
@@ -608,12 +632,11 @@ public class RequirePluginVersions
         return allPlugins;
     }
 
-    /*
-     * Checks to see if the version is specified for the plugin. Can optionally ban "RELEASE" or "LATEST" even if
-     * specified.
-     */
     /**
      * Checks for valid version specified.
+     * 
+     * Checks to see if the version is specified for the plugin. Can optionally ban "RELEASE" or "LATEST" even if
+     * specified.
      *
      * @param helper the helper
      * @param source the source
@@ -628,8 +651,7 @@ public class RequirePluginVersions
         for ( PluginWrapper plugin : pluginWrappers )
         {
             // find the matching plugin entry
-            if ( source.getArtifactId().equals( plugin.getArtifactId() )
-                && source.getGroupId().equals( plugin.getGroupId() ) )
+            if ( isMatchingPlugin( source, plugin ) )
             {
                 found = true;
                 // found the entry. now see if the version is specified
@@ -643,9 +665,9 @@ public class RequirePluginVersions
                     return false;
                 }
 
-                if ( StringUtils.isNotEmpty( version ) && !StringUtils.isWhitespace( version ) )
+                if ( isValidVersion( version ) )
                 {
-
+                    helper.getLog().debug( "checking for notEmpty and notIsWhiespace(): " + version );
                     if ( banRelease && version.equals( "RELEASE" ) )
                     {
                         return false;
@@ -676,11 +698,22 @@ public class RequirePluginVersions
         }
         if ( !found )
         {
-            log.debug( "plugin " + source.getGroupId() + ":" + source.getArtifactId() + " not found" );
+            helper.getLog().debug( "plugin " + source.getGroupId() + ":" + source.getArtifactId() + " not found" );
         }
         return status;
     }
 
+    private boolean isValidVersion( String version )
+    {
+        return StringUtils.isNotEmpty( version ) && !StringUtils.isWhitespace( version );
+    }
+
+    private boolean isMatchingPlugin( Plugin source, PluginWrapper plugin )
+    {
+        return source.getArtifactId().equals( plugin.getArtifactId() )
+            && source.getGroupId().equals( plugin.getGroupId() );
+    }
+
     /**
      * Checks if is snapshot.
      *
@@ -783,6 +816,7 @@ public class RequirePluginVersions
                 List<String> phases = lifecycle.getPhases();
                 for ( String phase : phases )
                 {
+                    log.debug( "getPhaseToLifecycleMap(): phase: " + phase );
                     if ( phaseToLifecycleMap.containsKey( phase ) )
                     {
                         Lifecycle prevLifecycle = (Lifecycle) phaseToLifecycleMap.get( phase );
@@ -835,9 +869,8 @@ public class RequirePluginVersions
         String packaging = project.getPackaging();
         Map<String, String> mappings = null;
 
-        LifecycleMapping m =
-            (LifecycleMapping) findExtension( project, LifecycleMapping.ROLE, packaging, session.getSettings(),
-                                              session.getLocalRepository() );
+        LifecycleMapping m = (LifecycleMapping) findExtension( project, LifecycleMapping.ROLE, packaging,
+                                                               session.getSettings(), session.getLocalRepository() );
         if ( m != null )
         {
             mappings = m.getPhases( lifecycle.getId() );
@@ -856,8 +889,8 @@ public class RequirePluginVersions
             {
                 if ( defaultMappings == null )
                 {
-                    throw new LifecycleExecutionException( "Cannot find lifecycle mapping for packaging: \'"
-                        + packaging + "\'.", e );
+                    throw new LifecycleExecutionException( "Cannot find lifecycle mapping for packaging: \'" + packaging
+                        + "\'.", e );
                 }
             }
         }
@@ -893,9 +926,8 @@ public class RequirePluginVersions
         String packaging = project.getPackaging();
         List<String> optionalMojos = null;
 
-        LifecycleMapping m =
-            (LifecycleMapping) findExtension( project, LifecycleMapping.ROLE, packaging, session.getSettings(),
-                                              session.getLocalRepository() );
+        LifecycleMapping m = (LifecycleMapping) findExtension( project, LifecycleMapping.ROLE, packaging,
+                                                               session.getSettings(), session.getLocalRepository() );
 
         if ( m != null )
         {
@@ -912,7 +944,7 @@ public class RequirePluginVersions
             catch ( ComponentLookupException e )
             {
                 log.debug( "Error looking up lifecycle mapping to retrieve optional mojos. Lifecycle ID: "
-                               + lifecycle.getId() + ". Error: " + e.getMessage(), e );
+                    + lifecycle.getId() + ". Error: " + e.getMessage(), e );
             }
         }
 
@@ -1028,6 +1060,7 @@ public class RequirePluginVersions
         return pluginDescriptor;
     }
 
+    
     /**
      * Gets all plugin entries in build.plugins, build.pluginManagement.plugins, profile.build.plugins, reporting and
      * profile.reporting in this project and all parents
@@ -1042,96 +1075,141 @@ public class RequirePluginVersions
     protected List<PluginWrapper> getAllPluginEntries( MavenProject project )
         throws ArtifactResolutionException, ArtifactNotFoundException, IOException, XmlPullParserException
     {
-        List<PluginWrapper> plugins = new ArrayList<PluginWrapper>();
-        // get all the pom models
-
         List<Model> models = new ArrayList<Model>();
-        
+
         List<MavenProject> sortedProjects = session.getProjectDependencyGraph().getSortedProjects();
+
+        if ( !sortedProjects.isEmpty() && sortedProjects.get( 0 ).getParent() != null )
+        {
+            getOriginalModelFromAllParents( models, sortedProjects );
+        }
+
         for ( MavenProject mavenProject : sortedProjects )
         {
             models.add( mavenProject.getOriginalModel() );
         }
-                        
+
+        List<PluginWrapper> plugins = new ArrayList<PluginWrapper>();
         // now find all the plugin entries, either in
         // build.plugins or build.pluginManagement.plugins, profiles.plugins and reporting
         for ( Model model : models )
         {
-            try
-            {
-                List<Plugin> modelPlugins = model.getBuild().getPlugins();
-                plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ), model.getId()
-                    + ".build.plugins" ) );
-            }
-            catch ( NullPointerException e )
-            {
-                // guess there are no plugins here.
-            }
+            getPlugins( plugins, model );
+            getReportingPlugins( plugins, model );
+            getPluginManagementPlugins( plugins, model );
 
-            try
-            {
-                List<ReportPlugin> modelReportPlugins = model.getReporting().getPlugins();
-                // add the reporting plugins
-                plugins.addAll( PluginWrapper.addAll( utils.resolveReportPlugins( modelReportPlugins ), model.getId()
-                    + ".reporting" ) );
-            }
-            catch ( NullPointerException e )
-            {
-                // guess there are no plugins here.
-            }
+            addPluginsInProfiles( plugins, model );
+        }
 
-            try
-            {
-                List<Plugin> modelPlugins = model.getBuild().getPluginManagement().getPlugins();
-                plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ), model.getId()
-                    + ".build.pluginManagement.plugins" ) );
-            }
-            catch ( NullPointerException e )
-            {
-                // guess there are no plugins here.
-            }
+        return plugins;
+    }
 
-            // Add plugins in profiles
-            List<Profile> profiles = model.getProfiles();
-            for ( Profile profile : profiles )
-            {
-                try
-                {
-                    List<Plugin> modelPlugins = profile.getBuild().getPlugins();
-                    plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ), model.getId()
-                        + ".profiles.profile[" + profile.getId() + "].build.plugins" ) );
-                }
-                catch ( NullPointerException e )
-                {
-                    // guess there are no plugins here.
-                }
+    private void getOriginalModelFromAllParents( List<Model> models, List<MavenProject> sortedProjects )
+    {
+        MavenProject parent = sortedProjects.get( 0 ).getParent();
+        do
+        {
+            models.add( parent.getOriginalModel() );
+            parent = parent.getParent();
+        }
+        while ( parent != null );
+    }
 
-                try
-                {
-                    List<ReportPlugin> modelReportPlugins = profile.getReporting().getPlugins();
-                    // add the reporting plugins
-                    plugins.addAll( PluginWrapper.addAll( utils.resolveReportPlugins( modelReportPlugins ),
-                                                          model.getId() + "profile[" + profile.getId()
-                                                              + "].reporting.plugins" ) );
-                }
-                catch ( NullPointerException e )
-                {
-                    // guess there are no plugins here.
-                }
-                try
-                {
-                    List<Plugin> modelPlugins = profile.getBuild().getPluginManagement().getPlugins();
-                    plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ), model.getId()
-                        + "profile[" + profile.getId() + "].build.pluginManagement.plugins" ) );
-                }
-                catch ( NullPointerException e )
-                {
-                    // guess there are no plugins here.
-                }
-            }
+    private void addPluginsInProfiles( List<PluginWrapper> plugins, Model model )
+    {
+        List<Profile> profiles = model.getProfiles();
+        for ( Profile profile : profiles )
+        {
+            getProfilePlugins( plugins, model, profile );
+            getProfileReportingPlugins( plugins, model, profile );
+            getProfilePluginManagementPlugins( plugins, model, profile );
         }
+    }
 
-        return plugins;
+    private void getProfilePluginManagementPlugins( List<PluginWrapper> plugins, Model model, Profile profile )
+    {
+        try
+        {
+            List<Plugin> modelPlugins = profile.getBuild().getPluginManagement().getPlugins();
+            plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ), model.getId() + "profile["
+                + profile.getId() + "].build.pluginManagement.plugins" ) );
+        }
+        catch ( NullPointerException e )
+        {
+            // guess there are no plugins here.
+        }
+    }
+
+    private void getProfileReportingPlugins( List<PluginWrapper> plugins, Model model, Profile profile )
+    {
+        try
+        {
+            List<ReportPlugin> modelReportPlugins = profile.getReporting().getPlugins();
+            // add the reporting plugins
+            plugins.addAll( PluginWrapper.addAll( utils.resolveReportPlugins( modelReportPlugins ), model.getId()
+                + "profile[" + profile.getId() + "].reporting.plugins" ) );
+        }
+        catch ( NullPointerException e )
+        {
+            // guess there are no plugins here.
+        }
+    }
+
+    private void getProfilePlugins( List<PluginWrapper> plugins, Model model, Profile profile )
+    {
+        try
+        {
+            List<Plugin> modelPlugins = profile.getBuild().getPlugins();
+            plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ), model.getId()
+                + ".profiles.profile[" + profile.getId() + "].build.plugins" ) );
+        }
+        catch ( NullPointerException e )
+        {
+            // guess there are no plugins here.
+        }
+    }
+
+    private void getPlugins( List<PluginWrapper> plugins, Model model )
+    {
+        try
+        {
+            List<Plugin> modelPlugins = model.getBuild().getPlugins();
+            plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ),
+                                                  model.getId() + ".build.plugins" ) );
+        }
+        catch ( NullPointerException e )
+        {
+            // guess there are no plugins here.
+        }
+    }
+
+    private void getPluginManagementPlugins( List<PluginWrapper> plugins, Model model )
+    {
+        try
+        {
+            List<Plugin> modelPlugins = model.getBuild().getPluginManagement().getPlugins();
+            plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ),
+                                                  model.getId() + ".build.pluginManagement.plugins" ) );
+        }
+        catch ( NullPointerException e )
+        {
+            // guess there are no plugins here.
+        }
+    }
+
+    private void getReportingPlugins( List<PluginWrapper> plugins, Model model )
+    {
+        try
+        {
+            List<ReportPlugin> modelReportPlugins = model.getReporting().getPlugins();
+            // add the reporting plugins
+            plugins.addAll( PluginWrapper.addAll( utils.resolveReportPlugins( modelReportPlugins ),
+                                                  model.getId() + ".reporting" ) );
+        }
+        catch ( NullPointerException e )
+        {
+            // guess there are no plugins here.
+        }
     }
 
     /**
diff --git a/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/TestRequirePluginVersions.java b/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/TestRequirePluginVersions.java
index 422967d..64290af 100644
--- a/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/TestRequirePluginVersions.java
+++ b/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/TestRequirePluginVersions.java
@@ -80,6 +80,7 @@ public class TestRequirePluginVersions
         rule.setBanRelease( false );
         rule.setBanSnapshots( false );
 
+
         EnforcerRuleHelper helper = EnforcerTestUtils.getHelper();
 
         assertTrue( rule.hasValidVersionSpecified( helper, source, pluginWrappers ) );
diff --git a/maven-enforcer-plugin/src/it/projects/MENFORCER-306/parent/pom.xml b/maven-enforcer-plugin/src/it/projects/MENFORCER-306/parent/pom.xml
new file mode 100644
index 0000000..d66827e
--- /dev/null
+++ b/maven-enforcer-plugin/src/it/projects/MENFORCER-306/parent/pom.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <groupId>mbenson.test</groupId>
+  <artifactId>test-require-plugin-versions</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <packaging>pom</packaging>
+  <properties>
+    <enforcer.version>3.0.0-SNAPSHOT</enforcer.version>
+  </properties>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-enforcer-plugin</artifactId>
+        <version>@project.version@</version>
+        <executions>
+          <execution>
+            <id>enforce-plugin-versions</id>
+            <goals>
+              <goal>enforce</goal>
+            </goals>
+            <configuration>
+              <rules>
+                <requirePluginVersions>
+                  <banSnapshots>false</banSnapshots>
+                </requirePluginVersions>
+              </rules>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-clean-plugin</artifactId>
+          <version>3.1.0</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-install-plugin</artifactId>
+          <version>2.5.2</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-site-plugin</artifactId>
+          <version>3.7.1</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-deploy-plugin</artifactId>
+          <version>2.8.2</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>3.7.0</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-plugin-plugin</artifactId>
+          <version>3.5.2</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-surefire-plugin</artifactId>
+          <version>2.21.0</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-jar-plugin</artifactId>
+          <version>3.1.0</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-resources-plugin</artifactId>
+          <version>3.1.0</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
+</project>
diff --git a/maven-enforcer-plugin/src/it/projects/MENFORCER-306/pom.xml b/maven-enforcer-plugin/src/it/projects/MENFORCER-306/pom.xml
new file mode 100644
index 0000000..9ad1574
--- /dev/null
+++ b/maven-enforcer-plugin/src/it/projects/MENFORCER-306/pom.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License.  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied.  See the License for the
+specific language governing permissions and limitations
+under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>mbenson.test</groupId>
+    <artifactId>test-require-plugin-versions</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <relativePath>parent/pom.xml</relativePath>
+  </parent>
+  <artifactId>pom</artifactId>
+  <packaging>pom</packaging>
+</project>