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 6ebc229326cc1a6b5116c3e49393a4fd712609f7 Author: Karl Heinz Marbaise <khmarba...@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 0c19c85..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)" + System.lineSeparator() ); - } - 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( System.lineSeparator() ); - } - 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>